Drops contextual ads into MCP workflows with a 70% revenue share for server developers. Exposes search_ads to fetch keyword-matched advertisements, report_event to track impressions and clicks for billing, and create_campaign plus create_ad for advertisers managing their spend. The matching is privacy-respecting keyword-based, no user tracking or profiling. You'd reach for this if you're monetizing a popular MCP server that surfaces product recommendations or commercial queries. Registration takes 30 seconds via their API, returns an API key, and you're earning on the next click. Also includes get_campaign_analytics for performance data and get_ad_guidelines for presentation formatting. Runs on Railway with stdio and HTTP transports.
Public tool metadata for what this MCP can expose to an agent.
get_ad_guidelinesGet formatting guidelines for how to present sponsored ads naturally in agent responsesGet formatting guidelines for how to present sponsored ads naturally in agent responses
No parameter schema in public metadata yet.
search_adsSearch for relevant ads matching a user intent/context. Returns ranked sponsored suggestions.6 paramsSearch for relevant ads matching a user intent/context. Returns ranked sponsored suggestions.
geostringquerystringcategorystringkeywordsarraylanguagestringmax_resultsnumberreport_eventReport an ad event (impression, click, or conversion). Call this after showing a sponsored ad to the user.4 paramsReport an ad event (impression, click, or conversion). Call this after showing a sponsored ad to the user.
ad_idstringmetadataobjectevent_typestringimpression · click · conversioncontext_hashstringcreate_campaignCreate a new advertising campaign with budget, pricing model, and objective8 paramsCreate a new advertising campaign with budget, pricing model, and objective
namestringend_datestringobjectivestringawareness · traffic · conversionsbid_amountnumberstart_datestringdaily_budgetnumbertotal_budgetnumberpricing_modelstringcpm · cpc · cpacreate_adCreate an ad unit within an existing campaign with creative text, link, and targeting7 paramsCreate an ad unit within an existing campaign with creative text, link, and targeting
geostringkeywordsarraylanguagestringlink_urlstringcategoriesarraycampaign_idstringcreative_textstringget_campaign_analyticsGet performance metrics for a campaign (impressions, clicks, conversions, spend)1 paramsGet performance metrics for a campaign (impressions, clicks, conversions, spend)
campaign_idstringupdate_campaignUpdate an existing campaign: modify name, objective, budget, bid, or status (pause/resume)9 paramsUpdate an existing campaign: modify name, objective, budget, bid, or status (pause/resume)
namestringstatusstringactive · pausedend_datestringobjectivestringawareness · traffic · conversionsbid_amountnumberstart_datestringcampaign_idstringdaily_budgetnumbertotal_budgetnumberlist_campaignsList all campaigns for the authenticated advertiser with summary stats1 paramsList all campaigns for the authenticated advertiser with summary stats
statusstringdraft · active · paused · completedGoogle AdSense for AI agents. Add 3 lines of code to your MCP server. Earn 70% of every ad click.
Live Demo · Quick Start · MCP Tools · Self-Host
Step 1 — Register and get your API key (30 seconds):
Visit the web form: https://agentic-ads-production.up.railway.app/dev/register
Or use the API directly:
curl -X POST https://agentic-ads-production.up.railway.app/api/register \
-H "Content-Type: application/json" \
-d '{"name": "My MCP Bot", "email": "me@example.com", "project_description": "A coding assistant that recommends dev tools"}'
# Returns: { "api_key": "aa_dev_...", "mcp_url": "https://agentic-ads-production.up.railway.app/mcp" }
Step 2 — Add to your MCP client config:
{
"mcpServers": {
"agentic-ads": {
"url": "https://agentic-ads-production.up.railway.app/mcp",
"transport": "http"
}
}
}
Step 3 — Call search_ads in your agent and earn on every click:
// In your agent logic — when context is relevant
const ads = await mcp.callTool({
name: 'search_ads',
arguments: { query: 'best running shoes for marathon', max_results: 1 }
});
// Report events to get paid
await mcp.callTool({
name: 'report_event',
arguments: { ad_id: ads[0].ad_id, event_type: 'impression' }
});
// User clicks → report 'click' → you earn $0.35 on a $0.50 CPC ad
That's it. You're monetizing.
You built an amazing MCP server. Users love it. But you're not making money.
agentic-ads is the missing monetization layer for the MCP ecosystem. It's like Google AdSense, but for AI agents instead of websites.
Privacy-respecting contextual ads served through MCP tools. Developers earn 70% revenue share (industry-leading). Advertisers reach AI agent users. Everyone wins.
Example: Your MCP server gets 10,000 queries/month where ads make sense.
| Scenario | Impressions/mo | CTR | Clicks/mo | CPC | Your Revenue |
|---|---|---|---|---|---|
| Conservative | 10,000 | 2% | 200 | $0.50 | $70/mo |
| Realistic | 10,000 | 5% | 500 | $0.50 | $175/mo |
| Strong | 10,000 | 8% | 800 | $0.75 | $420/mo |
At 100k queries/month with 5% CTR: $1,750/month passive income.
That's $21,000/year for adding 3 lines of code to your MCP server.
Connect the live server and start calling tools — no approval process, no minimums.
// 1. When user asks about products/services
const ads = await mcp.callTool({
name: 'search_ads',
arguments: {
query: 'best running shoes for marathon',
max_results: 2
}
});
// 2. Show relevant ad in your response (if it adds value)
// 3. Report impression
await mcp.callTool({
name: 'report_event',
arguments: { ad_id: 'ad_xyz', event_type: 'impression' }
});
// 4. If user clicks → report 'click' event
// You earn $0.35 on a $0.50 CPC click (70% revenue share)
# Create campaign + ad via MCP tools
mcp.callTool({
name: 'create_campaign',
arguments: {
name: 'Q1 Running Shoes',
total_budget: 500,
pricing_model: 'cpc',
bid_amount: 0.50
}
});
mcp.callTool({
name: 'create_ad',
arguments: {
campaign_id: 1,
creative_text: 'Ultraboost 24 — 30% off! Free shipping.',
link_url: 'https://adidas.com/ultraboost',
keywords: ['running shoes', 'sneakers', 'marathon'],
category: 'footwear'
}
});
# Monitor analytics
mcp.callTool({ name: 'get_campaign_analytics', arguments: { campaign_id: 1 } });
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Advertiser │────────────────────│ Agentic Ads MCP │────────────────────│ Your MCP │
│ (Brand/API) │ create_campaign │ Server │ search_ads │ Server │
│ │ create_ad │ │ report_event │ │
│ │ get_analytics │ - Matching │ get_guidelines │ Shows ads │
└─────────────┘ │ - Billing │ │ to users │
│ - Auth & Rate │ └──────────────┘
│ - Analytics │
└──────────────────┘
Example flow:
search_ads → gets relevant ads ranked by bid × relevanceclick event → you earn $0.35 (70% of $0.50 CPC)Privacy: No user tracking, no profiling, no cookies. Only contextual keyword matching.
70% to you, 30% to platform. Compare:
| Platform | Developer Share |
|---|---|
| agentic-ads | 70% |
| Google AdSense | 68% |
| Amazon Associates | 1-10% |
| Affiliate networks | 5-30% |
POST /api/register → get your API key| Tool | Auth | Description |
|---|---|---|
search_ads | Public | Search for ads by query/keywords/category/geo. Returns ranked results with relevance scores. |
report_event | Developer key | Report impression/click/conversion events. Triggers revenue calculation. |
get_ad_guidelines | Public | Get formatting guidelines for how to present ads naturally to users. |
| Tool | Auth | Description |
|---|---|---|
create_campaign | Advertiser key | Create campaign with budget, objective, pricing model (CPC/CPM/CPA). |
create_ad | Advertiser key | Create ad with creative text, keywords, targeting, link URL. |
get_campaign_analytics | Advertiser key | Get performance metrics (impressions, clicks, conversions, spend, ROI). |
update_campaign | Advertiser key | Update campaign (pause/resume, adjust budget, change targeting). |
list_campaigns | Advertiser key | List all campaigns with summary stats, optional status filter. |
Choose how you want to pay (advertisers) or earn (developers):
| Model | Advertiser Pays | Developer Earns (70%) | When Charged |
|---|---|---|---|
| CPC (Click) | $0.50 per click | $0.35 | User clicks ad link |
| CPM (Impression) | $5.00 per 1000 views | $3.50 | Ad shown to user |
| CPA (Conversion) | $10.00 per conversion | $7.00 | User completes action (purchase, signup, etc.) |
Budget controls: Set total budget + daily caps. Auto-pause when budget exhausted.
To call report_event or advertiser tools, you need an API key.
Option A — Web form (easiest):
Visit https://agentic-ads-production.up.railway.app/dev/register and fill in your details. Your API key is displayed immediately.
Option B — API:
curl -X POST https://agentic-ads-production.up.railway.app/api/register \
-H "Content-Type: application/json" \
-d '{"name": "My MCP Bot", "email": "me@example.com", "project_description": "A coding assistant"}'
Response:
{
"developer_id": "...",
"api_key": "aa_dev_...",
"mcp_url": "https://agentic-ads-production.up.railway.app/mcp"
}
| Field | Required | Description |
|---|---|---|
name | Yes | Your project or bot name |
email | Yes | Contact email |
project_description | No | Brief description of your MCP server (max 500 chars) |
Use the api_key in the Authorization header: Authorization: Bearer aa_dev_...
Deployed on Railway with persistent storage: The live server at
agentic-ads-production.up.railway.appruns on Railway with a persistent volume — data is preserved across deploys and restarts. To self-host, useDATABASE_PATH=/data/ads.dbpointing to a mounted volume.
Add to your MCP client config (Claude Desktop, Cursor, Windsurf, etc.):
{
"mcpServers": {
"agentic-ads": {
"url": "https://agentic-ads-production.up.railway.app/mcp",
"transport": "http"
}
}
}
Health check: https://agentic-ads-production.up.railway.app/health
npm install -g agentic-ads
# Add to MCP config
{
"mcpServers": {
"agentic-ads": {
"command": "npx",
"args": ["agentic-ads", "--stdio"]
}
}
}
git clone https://github.com/nicofains1/agentic-ads.git
cd agentic-ads
npm install && npm run build
# Start HTTP server
PORT=19877 npm run start:http
# Or stdio
npm run start:stdio
Flags:
node dist/server.js --http --port 19877 --db ./ads.db
| Flag | Default | Description |
|---|---|---|
--http | — | Start HTTP server (default is stdio) |
--port N | 3000 | HTTP port |
--db PATH | agentic-ads.db | SQLite database path |
--api-key KEY | — | Pre-authenticate stdio sessions |
Environment Variables:
PORT=19877 # HTTP server port (alternative to --port)
DATABASE_PATH=/data/ads.db # SQLite database path (default: agentic-ads.db)
AGENTIC_ADS_API_KEY=aa_dev_... # Developer API key for stdio mode
DB Persistence: Set DATABASE_PATH to a path on a persistent volume. On first run with an empty DB, demo campaigns are auto-seeded. See DEPLOY.md for full deployment guide (Railway recommended for free persistent storage).
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"agentic-ads": {
"command": "npx",
"args": ["agentic-ads", "--stdio"]
}
}
}
{
"mcpServers": {
"agentic-ads": {
"url": "https://agentic-ads-production.up.railway.app/mcp",
"transport": "http"
}
}
}
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'npx',
args: ['agentic-ads', '--stdio']
});
const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(transport);
// Search for ads
const result = await client.callTool({
name: 'search_ads',
arguments: {
query: 'best laptops for coding',
keywords: ['laptop', 'programming'],
category: 'electronics',
max_results: 3
}
});
console.log(result.content[0].text);
// Returns: { "ads": [ { "ad_id": "...", "creative_text": "...", "relevance_score": 0.87 } ] }
When calling the live server over HTTP, you must manage MCP sessions manually. Here's a complete example using raw fetch:
const BASE = "https://agentic-ads-production.up.railway.app";
const API_KEY = "aa_dev_..."; // from /api/register
const headers = {
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
"Authorization": `Bearer ${API_KEY}`,
};
// 1. Initialize — get a session ID
const initRes = await fetch(`${BASE}/mcp`, {
method: "POST",
headers,
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "initialize",
params: {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: { name: "my-agent", version: "1.0.0" },
},
}),
});
const sessionId = initRes.headers.get("mcp-session-id");
// 2. Send initialized notification (required by MCP spec)
await fetch(`${BASE}/mcp`, {
method: "POST",
headers: { ...headers, "mcp-session-id": sessionId },
body: JSON.stringify({
jsonrpc: "2.0", method: "notifications/initialized", params: {},
}),
});
// 3. Call tools — pass session ID on every request
const res = await fetch(`${BASE}/mcp`, {
method: "POST",
headers: { ...headers, "mcp-session-id": sessionId },
body: JSON.stringify({
jsonrpc: "2.0", id: 2, method: "tools/call",
params: { name: "search_ads", arguments: { query: "running shoes", max_results: 2 } },
}),
});
// 4. Parse response (SSE format: "event: message\ndata: {...}")
const text = await res.text();
const dataLine = text.split("\n").find((l) => l.startsWith("data:"));
const result = JSON.parse(dataLine.slice(5));
console.log(result.result.content[0].text);
Key points:
mcp-session-id header is returned on initialize and must be sent on all subsequent requestsAuthorization: Bearer ...) is set per-session — all tool calls in that session inherit itdata: line from the responseexamples/demo-mcp-server for a full working example┌─────────────────────────────────────────────────────────────┐
│ MCP Server (Node.js 22 + TypeScript) │
│ ┌───────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ Tool Registry │ │ Auth & Rate │ │ Matching Engine │ │
│ │ (8 tools) │ │ Limiting │ │ (relevance² │ │
│ │ │ │ (SHA-256) │ │ × bid × quality)│ │
│ └───────────────┘ └──────────────┘ └─────────────────┘ │
│ ┌───────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ SQLite (WAL) │ │ Revenue │ │ Analytics │ │
│ │ - Campaigns │ │ Split Engine │ │ (real-time) │ │
│ │ - Ads │ │ (70/30) │ │ │ │
│ │ - Events │ │ │ │ │ │
│ └───────────────┘ └──────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │
│ │
Streamable HTTP (remote) stdio (local)
Key Features:
score = relevance² × bidFactor × quality_score (relevance dominates)# Clone repo
git clone https://github.com/nicofains1/agentic-ads.git
cd agentic-ads
# Install + build
npm install && npm run build
# Seed a local DB with demo data (generates real API keys)
tsx scripts/seed.ts --db test.db
# Note: seed.ts prints the generated dev/adv keys — use them below
# Run smoke test with real keys from seed output
tsx scripts/smoke-test.ts --db test.db --dev-key aa_dev_... --adv-key aa_adv_...
Output:
✅ Created advertiser: Adidas
✅ Created campaign: Q1 Running Shoes ($500 budget, CPC $0.50)
✅ Created ad: "Ultraboost 24 — 30% off!"
✅ Created developer: TestBot
✅ Searched ads for "running shoes" → 1 result (relevance 0.95)
✅ Reported impression → $0.00 charged (CPC model)
✅ Reported click → $0.50 charged, developer earned $0.35
✅ Analytics: 1 impression, 1 click, $0.50 spent, $0.35 developer revenue
When your MCP server reports a click event on a CPC ad, 70% of the bid goes to you — tracked atomically in our database. Once your balance reaches $10, email payouts@agentic-ads.com with your developer_id and your preferred payment method (PayPal or USDC on Polygon). We verify your balance and send payment within 5 business days. Automated Stripe payouts are on the roadmap for when the network scales.
Q: How do I get an API key? A: Register via the REST endpoint:
curl -X POST https://agentic-ads-production.up.railway.app/api/register \
-H "Content-Type: application/json" \
-d '{"name": "Your Name", "email": "you@example.com"}'
# Returns: { "developer_id": "...", "api_key": "aa_dev_...", "mcp_url": "..." }
Use the returned api_key as Authorization: Bearer aa_dev_... in your MCP requests.
Q: Do I HAVE to show ads? A: No. You control which ads to show. Only show ads if they genuinely add value to the user. Agent autonomy is a feature.
Q: What if my users hate ads?
A: Follow the guidelines from get_ad_guidelines: max 1-2 ads per response, always disclose "sponsored", respect opt-out ("no ads please").
Q: Is this production-ready? A: Yes. 270 passing tests, live at https://agentic-ads-production.up.railway.app, MIT license.
Q: What MCP clients are supported? A: Any MCP client supporting stdio or Streamable HTTP. Tested with Claude Desktop, Cursor, Windsurf, custom agents.
Q: How do I create ads?
A: Use the create_campaign and create_ad MCP tools with an advertiser API key. See smoke-test.ts for examples.
Q: How is my budget protected? A: Budget tracking is atomic (SQLite transaction). When budget exhausted → campaign auto-pauses. No overspend.
Q: Can I track conversions?
A: Yes, use CPA pricing model + report_event with event_type: 'conversion'. Add UTM params to your link URL for attribution.
Q: What targeting options exist? A: MVP has keywords (exact + partial match), categories, geo (country-level), and language. Semantic matching coming in Phase 2.
Q: Do you track users? A: No. We only receive anonymized keyword queries from agents. No user IDs, no cookies, no profiling. Privacy-first.
Q: How do you prevent fraud? A: MVP uses API key auth + rate limiting + trust-based reporting. Phase 2 adds anomaly detection heuristics (see issue #47).
Q: Is this open source? A: Yes, MIT license. Fork it, self-host it, contribute to it.
We follow the GitHub Issues workflow:
gh issue create --title "Your idea"feature/#N-descriptionfeat(#N): descriptionmainSee CLAUDE.md for detailed guidelines.
MIT — see LICENSE for details.
AI agents are eating the web. Users ask agents instead of searching Google. Agents answer instead of websites.
The old internet: Users browse websites → see ads → advertisers reach users.
The new internet: Users ask agents → agents scrape websites → advertisers can't reach users.
agentic-ads fixes this. It's the ad layer for the agent economy.
And you — the MCP developer — earn 70% of the revenue for being the intermediary.
The opportunity: 16,000+ MCP servers, almost none monetize. You can be first.
Built with Model Context Protocol (MCP) — the open standard for connecting AI agents to tools.
Live demo: https://agentic-ads-production.up.railway.app
Get started: Add the MCP server to your config, earn your first dollar this week.
explorium-ai/vibeprospecting-mcp
io.github.compuute/lead-enrichment
dev.workers.selbyventurecap.cf-worker/apollo-salesforce-mapper
io.github.br0ski777/company-enrichment
com.mcparmory/apollo
mambalabsdev/mcp-gtm-tech-stack-signal-scraper