MCP server
Connect Claude, Cursor, VS Code, Windsurf or any Model Context Protocol client to WhichClick — tools, resources, prompts, auth and examples.
Updated 2026-09-02
WhichClick ships a native Model Context Protocol server. An agent connected to it can read the documentation, build tracking templates, inspect campaigns, clicks and fraud stats, create links, validate routing rules and record conversions — all scoped to your organization's API key.
Endpoint#
https://app.whichclick.is/api/mcp- Transport: Streamable HTTP (JSON-RPC 2.0 over
POST, stateless, JSON responses; no SSE stream is required). - Protocol versions:
2025-11-25,2025-06-18,2025-03-26,2024-11-05. - Auth:
Authorization: Bearer wc_live_…(an organization API key). Without a key the server still works but only exposes the documentation tools — useful for public assistants. - CORS is open, so browser-based MCP clients can connect directly.
Connect#
claude mcp add --transport http whichclick https://app.whichclick.is/api/mcp \
--header "Authorization: Bearer wc_live_xxxxxxxx"{
"mcpServers": {
"whichclick": {
"url": "https://app.whichclick.is/api/mcp",
"headers": { "Authorization": "Bearer wc_live_xxxxxxxx" }
}
}
}{
"servers": {
"whichclick": { "type": "http", "url": "https://app.whichclick.is/api/mcp", "headers": { "Authorization": "Bearer ${input:whichclick-key}" } }
},
"inputs": [ { "id": "whichclick-key", "type": "promptString", "password": true, "description": "WhichClick API key" } ]
}npx -y whichclick-mcp --url https://app.whichclick.is/api/mcp --key wc_live_xxxxxxxx
# (thin bridge in sdk/mcp of the distribution — zero dependencies)const res = await client.beta.messages.create({
model: "claude-opus-5",
max_tokens: 2048,
betas: ["mcp-client-2025-04-04"],
mcp_servers: [{ type: "url", url: "https://app.whichclick.is/api/mcp", name: "whichclick", authorization_token: process.env.WHICHCLICK_API_KEY }],
messages: [{ role: "user", content: "Show my invalid click rate for the last 7 days and the top 5 IPs." }],
});Tools#
| Tool | What it does | Auth | Effect |
|---|---|---|---|
search_docs | Full-text search over the WhichClick developer documentation. Returns page + section matches with canonical and Markdown URLs. Use before answering any integration question. | none (public) | read-only |
get_doc | Returns one documentation page as Markdown. Slugs come from list_docs / search_docs (e.g. 'quickstart', 'tracking/template', 'api/reference', 'ai/mcp'). | none (public) | read-only |
list_docs | Lists every documentation page grouped by section with a one-line description (same content as /llms.txt). | none (public) | read-only |
build_tracking_template | Generates a Google Ads tracking template and final URL suffix for a tracking domain + link slug that satisfies Google's transparent click tracker guidelines (visible url= next hop, force_transparent=true, ValueTrack capture). Pure function — no account needed. | none (public) | read-only |
validate_routing_rules | Validates a smart-link rules array and optional settings object against the routing schema and reports errors. Use before update_smart_link_routing. | none (public) | read-only |
get_overview | Headline KPIs for the organization: clicks, installs, conversions, revenue, spend, CPI, ROAS, attribution-method mix, top countries/networks and the per-campaign table for the last N days. | API key | read-only |
get_pivot_report | Clicks, bots, installs, conversions, CVR, spend, CPI, revenue and ROAS grouped by one dimension. | API key | read-only |
get_metric_timeseries | Daily values of a metric (clicks, installs, conversions, revenue, spend, cpi, cvr, roas, invalid_rate, uninstalls, reengagements or events:<name>) optionally scoped to one campaign. | API key | read-only |
get_cohorts | Weekly install cohorts with D1/D3/D7/D14/D30 retention plus LTV, CPI and ROAS per campaign. | API key | read-only |
get_protection_stats | Invalid/suspicious click rates, reasons, top offending IPs, open incidents, install-fraud flags and CTIT distribution. | API key | read-only |
list_campaigns | Campaigns with id, name, platform, status and external (ad-platform) id. | API key | read-only |
list_domains | Tracking domains with DNS/verification status, Google-certified flag and the CNAME target to configure. | API key | read-only |
list_tracking_links | Google Ads tracking links (GET /c/{slug}) with domain, default final URL, click-id parameter and the ready-to-paste tracking template. | API key | read-only |
list_smart_links | Smart links (GET /l/{slug}) with store URLs, web fallback, deep-link path, rule count and status. | API key | read-only |
get_smart_link | Full smart-link configuration including routing rules and settings JSON. | API key | read-only |
list_apps | Mobile / CTV apps with platform, bundle id, store URL, deep-link scheme, universal-link host and attribution windows. SDK keys are masked. | API key | read-only |
list_clicks | Most recent click records (ValueTrack fields, next hop, transparency flags, verdict, geo, device) — for debugging a tracking template or exporting offline conversions. | API key | read-only |
list_conversions | Most recent conversions with matched click id, campaign, value and source. | API key | read-only |
lookup_ip | Classifies an IPv4/IPv6 address using the CIDR intelligence pool: type (residential/datacenter/VPN/proxy/Tor/CDN/search bot), ASN, organisation, geo, risk weight, rate-limit key and the Google Ads exclusion form. | API key | read-only |
test_smart_link_route | Runs the routing engine for a smart link with a simulated visitor (country, OS, IP, UA, language, params, hour) and returns the decision and the matched rule — without recording a click. | API key | read-only |
recent_alerts | Recently fired alert events and open protection incidents. | API key | read-only |
create_campaign | Creates a campaign container. Set external_id to the ad-platform campaign id so ValueTrack {campaignid} and cost sync line up. | API key | writes |
create_tracking_link | Creates a Google Ads tracking link on a verified tracking domain and returns the tracking template + final URL suffix to paste into Google Ads. | API key | writes |
create_smart_link | Creates a smart link (OS routing + store redirect + deferred deep link). Attach an app_id to enable deep-link scheme / universal-link resolution. | API key | writes |
update_smart_link_routing | Replaces the routing rules and/or settings of a smart link after validating them. Cached link config is invalidated immediately. | API key | writes |
record_conversion | Records a server-side conversion against a click id or gclid (same as POST /api/v1/conversions). Idempotent on order_id + event. | API key | writes |
set_link_status | Sets a tracking link, smart link or campaign to ACTIVE, PAUSED or ARCHIVED. | API key | writes |
block_ip | Adds an IP or CIDR to the organization's protection blocklist (and to Google Ads negative IPs on the next sync). | API key | writes |
Every tool returns JSON in structuredContent and as text. Write tools are recorded in the audit log with via: "mcp". Tool inputs are validated with the same schemas as the dashboard; invalid input returns isError: true with field-level messages rather than a protocol error.
Resources#
| URI | Content |
|---|---|
whichclick://llms.txt | Documentation index |
whichclick://openapi.json | OpenAPI 3.1 document |
whichclick://docs/{slug} | Any documentation page as Markdown (template whichclick://docs/{slug}) |
Prompts#
| Prompt | Purpose | Arguments |
|---|---|---|
setup_google_ads_tracking | Guided setup of certified Google Ads click tracking: domain, link, template, conversion postback and compliance check. | tracking_domain, landing_url, campaign_name? |
investigate_invalid_clicks | Analyse click-fraud signals for the last N days, list top offenders and recommend blocklist / Google Ads exclusion actions. | days? |
design_smart_link | Design a smart link with routing rules (geo, OS, in-app browser, A/B split) for a mobile campaign and validate it with the simulator. | goal, app_id? |
Raw JSON-RPC examples#
curl -s https://app.whichclick.is/api/mcp -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
curl -s https://app.whichclick.is/api/mcp -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'curl -s https://app.whichclick.is/api/mcp -H "Content-Type: application/json" -H "Authorization: Bearer wc_live_xxxxxxxx" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_protection_stats","arguments":{"days":7}}}'{ "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{ \"clicks\": { \"total\": 18422, \"invalid\": 611, \"invalid_rate\": 0.033, … } }" } ], "structuredContent": { "clicks": { "total": 18422, "invalid": 611, "invalid_rate": 0.033 } } } }Security model#
- The key's organization is the only tenant visible; there is no cross-organization tool.
- Read tools are marked
readOnlyHint: true; write tools are non-destructive (they create or pause, never delete). Deleting still requires the dashboard. - Rate limit: 240 requests / minute per IP on
/api/mcp. - Revoke the key in Settings → API keys to cut an agent off instantly.
Errors#
| JSON-RPC code | Meaning |
|---|---|
-32001 | API key required or invalid for this tool |
-32002 | Resource not found |
-32601 | Unknown method |
-32602 | Invalid params (details in error.data) |
-32700 | Parse error |
HTTP 401 with WWW-Authenticate: Bearer is returned when a bearer token is present but invalid; a missing token is not an HTTP error (documentation tools remain available).