Quick start
- In the dashboard, create a key under Settings (Ayarlar) > API (MCP). Keys start with adv_ and are shown only once.
- Point your client at the address below with an Authorization: Bearer <key> header.
- If your client lists the tools, you are connected. For a first try, ask the assistant for your competitor list.
Server URL
https://adversee.com/api/mcpAuthentication
Every request carries an Authorization: Bearer adv_… header. Keys are personal and bound to one workspace; the assistant sees that workspace with your role.
Each request re-checks that the key is not revoked, your account is active and you are still on the team. Users removed and re-invited must create a new key.
Each user can hold at most 10 active keys per workspace. Keys are revoked from the dashboard.
Client setup
Claude Code
One command in your terminal:
claude mcp add --transport http adversee https://adversee.com/api/mcp \
--header "Authorization: Bearer adv_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"Cursor
In ~/.cursor/mcp.json (or .cursor/mcp.json in your project):
{
"mcpServers": {
"adversee": {
"url": "https://adversee.com/api/mcp",
"headers": { "Authorization": "Bearer adv_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}Claude Desktop
Claude Desktop's config file does not connect to remote servers directly; use the mcp-remote bridge (requires Node.js). Add this to claude_desktop_config.json and restart the app. Keeping the key in an environment variable avoids the Windows argument-spacing issue.
{
"mcpServers": {
"adversee": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://adversee.com/api/mcp",
"--transport", "http-only",
"--header", "Authorization:${ADVERSEE_AUTH}"
],
"env": { "ADVERSEE_AUTH": "Bearer adv_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}Plain HTTP
A JSON-RPC request for any MCP client or for testing:
curl -s https://adversee.com/api/mcp \
-H "Authorization: Bearer adv_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"adversee_list_competitors","arguments":{}}}'Tools
All tools are read-only. Parameter names are shown exactly as the API expects them (they are Turkish). Competitor filters accept a slug or a name; slugs come from adversee_list_competitors.
adversee_list_competitors
Tracked competitors: name, slug, site, active and archived campaign counts.
No parameters.
adversee_list_campaigns
Campaigns: title, link, status, dates, first seen, category and group.
| Parameter | Type | Description |
|---|---|---|
rakip | string | Competitor slug or name. |
durum | aktif · yakinda · pasif · kaldirildi | Status: active, upcoming, inactive, removed. |
limit | 1-100 (25) | Number of records. |
offset | ≥0 (0) | Pagination offset. |
adversee_get_campaign
One campaign: extracted fields (cap, wagering, rate), terms and recent snapshots.
| Parameter | Type | Description |
|---|---|---|
id | uuid | From adversee_list_campaigns. |
adversee_list_events
Events, newest first: campaign, banner, Meta, outage and overtake events; changed fields are in 'ayrinti'.
| Parameter | Type | Description |
|---|---|---|
rakip | string | Slug or name; use the slug for brands no longer tracked. |
tip | string | Comma-separated event types (e.g. new_campaign,banner_eklendi). |
baslangic | ISO date-time with offset | From this moment (inclusive). |
bitis | ISO date-time with offset | Before this moment. |
cursor | string | sonrakiCursor from the previous response. |
limit | 1-100 (25) | Page size. |
adversee_get_digest
Daily (09:00) or weekly (Monday) digest: banner and Meta event counts per competitor.
| Parameter | Type | Description |
|---|---|---|
donem | gun · hafta (gun) | Day or week. |
adet | 1-14 (1) | How many periods, newest first. |
adversee_list_homepage_banners
Homepage slider banners (desktop/mobile): stable id, position, target, first/last seen, removal time, previous version, last tour per view and classification.
| Parameter | Type | Description |
|---|---|---|
rakip | string | Slug or name. |
durum | aktif · kalkan (aktif) | Live, or removed within the last 30 days. |
tur | teklif · icerik · marka_geneli | Type filter: offer, content, brand-level. |
kategori | string | Category key or name. |
grup | string | Game group key or name. |
oyun | string | Text contained in the game name on the image. |
adversee_get_banner_history
A competitor's slider order, tour by tour (one tour every 2 hours).
| Parameter | Type | Description |
|---|---|---|
rakip | slug | Required. |
gorunum | masaustu · mobil | Required: desktop or mobile. |
baslangic | ISO date-time with offset | Defaults to 24 hours before the end. |
bitis | ISO date-time with offset | Defaults to now. Window is at most 7 days. |
adversee_list_meta_ads
Meta (Facebook/Instagram) ads: library id and link, start date, first/last seen, end time, text, target, classification and per-brand coverage.
| Parameter | Type | Description |
|---|---|---|
rakip | string | Slug or name. |
durum | aktif · biten (aktif) | Active or ended ads. |
tur · kategori · grup · oyun | string | Same classification filters as the banner tool. |
limit | 1-100 (25) | Number of records. |
offset | ≥0 (0) | Pagination offset. |
adversee_get_image
A banner or ad image as an MCP image (png, jpeg, gif, webp; up to 3.7 MB). Larger or other formats return a dashboard link.
| Parameter | Type | Description |
|---|---|---|
tur | banner · meta | Which surface the image comes from. |
gorselId | uuid | From the banner or Meta tool output. |
adversee_get_overtakes
Where competitors beat you (e.g. cap, rate): open overtakes and recently closed ones.
No parameters.
Example responses
Shortened; '…' marks omitted values. Field names are Turkish, as returned by the API.
adversee_get_banner_history
{
"marka": { "slug": "rakip-a", "ad": "Rakip A" },
"gorunum": "mobil",
"kayitBaslangici": "2026-10-06 11:50:16+00",
"turlar": [
{ "turId": "…", "zaman": "2026-10-07T10:00:12Z", "durum": "tamam",
"liste": [
{ "sira": 1, "slideId": "…", "gorselId": "…", "hedef": "https://…", "gorselLinki": "https://adversee.com/app/panel-api/vitrin/gorsel/…" },
{ "sira": 2, "slideId": "…", "gorselId": "…", "hedef": null, "gorselLinki": "…" }
] },
{ "turId": "…", "zaman": "2026-10-07T12:00:09Z", "durum": "engel",
"liste": null, "listeYokNedeni": "olculemedi" }
]
}adversee_list_events
{
"hareketler": [
{ "id": "…", "tip": "banner_eklendi", "baslik": "…", "rakip": "Rakip A",
"rakipSlug": "rakip-a", "seviye": "hamle", "zaman": "2026-10-07T10:00:12.318Z",
"kampanyaId": null, "ayrinti": { "gorunum": "mobil", "url": "https://…" } }
],
"sonrakiCursor": "b2xheTo…"
}Classification on banner and Meta items
"siniflama": {
"tur": "teklif",
"kategori": { "key": "ek_kazanc", "ad": "Ek Kazanç" },
"grup": { "key": "bas_kazan", "ad": "Bas Kazan" },
"oyun": "Efsane Mücevher Avcısı",
"istemSurumu": 2,
"onerilenKampanya": { "id": "…", "baslik": "…", "guven": 85 }
}Limits
- Rate limit: 60 requests per minute per key; 429 when exceeded.
- No batching: JSON-RPC batches are not supported; send one call per request.
- Body size: Request bodies up to 4 MB.
- Image size: Images up to 3.7 MB are returned as images; larger ones return a dashboard link.
- Invalid keys: More than 20 invalid-key attempts per minute from one address get 429; valid keys are not affected.
- Freshness: Banners are checked every 2 hours, Meta every 6 hours; polling more often brings nothing new.
Error codes
| Status | Meaning |
|---|---|
401 | Missing, malformed or revoked key, or membership ended. |
429 | Per-minute request limit or invalid-key limit exceeded. |
400 | Body is not valid JSON, or a batch request was sent. |
413 | Body exceeds 4 MB. |
405 | The server is stateless; only POST is supported. |
isError | The tool ran but returned no result (e.g. 'Kayıt bulunamadı.' or an invalid date); the message explains why. |
Reading the data correctly
- null means 'unknown', not 'none'. Values that could not be measured are never reported as 0.
- In banner order history a failed tour has liste: null, and listeYokNedeni gives the reason: olculemedi (not measured), eksik (incomplete), kayit_hatasi (write error) or kayit_oncesi (before recording started).
- Banner order history is recorded from 6 October 2026; earlier tours return kayit_oncesi.
- When polling events, set baslangic to 15 minutes before your last pull and de-duplicate by id; rows written at the same moment can appear a few seconds late.
- Date parameters need a time zone (e.g. 2026-10-07T00:00:00Z or +03:00).
- Meta shows logged-out visitors only the first page of large pages, and some pages not at all. The 'kapsam' field states this per brand; counts are distinct ad creatives.
- Image classification is an AI estimate: uncertain fields stay null, the game name is given only if it is written on the image, and campaign matches are confidence-scored suggestions, not hard links.
- A Meta ad is marked ended only after it has been missing for at least 12 hours and at least 3 fully read tours.