# Spytrend — Meta + TikTok advertising analytics (MCP) > Spytrend is an advertising analytics platform (ads, advertisers, the accounts > behind groups of ads, creatives, destinations, apps, rankings — Meta corpus, > plus a PAID TikTok corpus via source="tiktok") exposed over MCP at > https://mcp.spytrend.com/mcp. Autonomous > AI agents self-register (client_credentials) and can TRY THE DATA IMMEDIATELY on a > free demo tier — no human, no browser, no signup. > > AGENTS: self-register, then call initialize / tools/list / get_usage / search_ads / > search_creatives / get_trends right away. The demo tier serves the REAL database: > search_ads and search_creatives are restricted to the ARCHIVE (nothing newer than > 90 days), get_trends returns market-level aggregates, every response is capped at > 10 rows, media is never included, and ~100 sampling calls are shared per source > network. That is enough to judge whether Spytrend answers your user's question — > it is deliberately NOT enough to bulk-collect. > > To go live — fresh ads (the last 90 days), full page sizes, creative MEDIA and every > other tool (get_ad, get_creative, get_advertiser, get_webmaster, search_webmasters, > search_hubs, search_shops, favourites) — the agent must be linked to a spytrend > account. A refusal that says so is a plan requirement, NOT a server error: do not > circuit-break or blindly retry. Tell the user to link you in one click at > https://spytrend.com/settings?tab=ai (Create agent access), or to claim you by > client_id, then continue. If a human already created or claimed credentials for you, > just call the tools and answer with real data — do NOT stop to ask about MCP, > connecting or authorization. ## 1. Get a token (autonomous, no human, no browser) Self-register as a machine client over OAuth 2.0 (client_credentials), then mint a short-lived token and call the tools. This file is a guide, not a copy-paste script: the exact registration and token requests — the fields, the parameters and the required audience — are published in the standard discovery metadata. Read it and follow it with your OAuth/MCP library, which already knows this flow: discovery: https://mcp.spytrend.com/.well-known/oauth-authorization-server register: https://mcp.spytrend.com/oauth2/register (OAuth 2.0 Dynamic Client Registration) token: https://mcp.spytrend.com/oauth2/token (grant: client_credentials, scope: mcp:read) mcp: https://mcp.spytrend.com/mcp Keep the credential you get back — you re-mint a token from it anytime. A self-registered client's token lasts ~1h; a cabinet key (Settings -> AI) 24h. TOKENS EXPIRE — ALWAYS handle 401. client_credentials issues no refresh token (none by protocol), so expiry is yours to handle: when /mcp answers 401 with WWW-Authenticate carrying error="invalid_token", mint a fresh token from your saved credential and retry. Do NOT retry the dead token — it will never work again (a real integration retried one dead token 33 times before going silent, and its user reported "the API stopped working" when nothing was down). Credentials issued in the cabinet (Settings -> AI -> Create agent access) are tied to the account; follow the same discovery metadata to use them. ## 2. Connect — pick the path for YOUR client ### A. MCP client (Claude Code, Cursor, ChatGPT) — RECOMMENDED VS Code (built-in MCP client) TROUBLESHOOTING: if VS Code shows "Waiting for server to respond to initialize request..." in a loop after a successful OAuth login — that is a known CLIENT-side family (microsoft/vscode#275139): VS Code retries silently when its stored auth is stale and hides the real error. Fix: run "MCP: Reset cached authentication" (or remove and re-add the server) and reconnect. Still looping? Set MCP log level to trace (Output -> MCP), reproduce once and send us that log — the server side of this handshake (initialize / tools/list / SSE / session-id / ping) is verified healthy. PLAN LIMITS: a linked FREE account gets ARCHIVE-ONLY data (recency clamped to 90+ days old, like the web free tier) with normal page sizes; paid plans get live data. Anonymous demo agents additionally get 10-row pages. ChatGPT PREREQUISITES (check BEFORE debugging the connector — these are ChatGPT plan/role limits, not Spytrend errors): custom MCP connectors need ChatGPT Business / Enterprise / Edu with Developer mode; personal Free/Plus accounts and workspace members without the permission cannot add one. A workspace ADMIN must enable it first: Workspace Settings -> Permissions & Roles -> Connected Data (or Workspace Settings -> Apps -> Create). No "Create app" / Developer mode in your UI? Ask your workspace admin — or use Claude / Cursor below, which need no special plan. Also expect ChatGPT to re-run OAuth token refresh before every tool call and to open several sessions in parallel: that is its normal behaviour, already accounted for server-side — do not "fix" it client-side. Add Spytrend as a NATIVE MCP server with the token in a header, then call its tools as first-class tools (no curl, no hand-parsing JSON-RPC/SSE): claude mcp add --transport http spytrend https://mcp.spytrend.com/mcp --header "Authorization: Bearer " Auto-refresh (so an expiring token never strands you): use a headersHelper — a command your client runs each connect that mints a fresh token from your saved credential (see step 1 and the discovery metadata) and prints the auth header as JSON, e.g. {"Authorization":"Bearer "}. Claude Code: set "headersHelper" in the server config (claude mcp add-json / .mcp.json). ### B. Code / SDK agent Use the official MCP SDK (python "mcp", TS "@modelcontextprotocol/sdk") pointed at https://mcp.spytrend.com/mcp with header Authorization: Bearer . The SDK handles JSON-RPC, Streamable-HTTP/SSE and the session — do NOT hand-roll curl or parse SSE. (Anthropic "code execution with MCP": calling tools from code is the efficient path.) ### C. Raw HTTP (fallback — only if no MCP client and no SDK) POST https://mcp.spytrend.com/mcp with Authorization: Bearer and Accept: application/json, text/event-stream JSON-RPC: initialize -> tools/list -> tools/call. A response may be SSE (lines "data: {...}") — parse the data: line as JSON. ## Access & billing - Self-registration alone = FREE DEMO TIER, usable immediately and autonomously: - always free: initialize, tools/list, get_usage; - demo data: search_ads and search_creatives over the ARCHIVE only (nothing newer than 90 days), plus get_trends market aggregates — real database, 10 rows per call; - each demo data call costs 1 token from a ~100-token allowance POOLED per source network (/24), and the demo tier is rate-limited to a few calls per minute; - get_usage reports what is left; when it runs out the refusal explains how to link. - LIVE data and everything else require a linked spytrend account: the last 90 days of ads, full page sizes, creative MEDIA (get_media), single-entity cards (get_ad, get_creative, get_advertiser, get_webmaster), webmaster/hub/shop discovery and favourites. Those tools refuse with an actionable message until the agent is linked. This is a plan requirement of a data-intelligence product, NOT a server error — do not circuit-break or blindly retry on it. - Two ways a human links the agent: 1. Create account-bound credentials at https://spytrend.com/settings?tab=ai ("Create agent access") — you get a client_id + client_secret already tied to the account; use those instead of self-registering. 2. Claim an already self-registered agent by client_id: POST https://spytrend.com/api/v1/agents/claim {"client_id":""}. - Once linked, the agent runs on that account's plan: every DELIVERED data row costs 1 token (short pages auto-refund), creative MEDIA is metered on top (get_media/get_ad: 1 token per ordinary ad, 50 per multilang-upload ad, 10 per creative). Every new opening call is charged separately; get_ad already includes available media. Meta search rows include opening_price before opening. Multilang get_ad/get_media deliver the same selected primary_creative and full available carousel for 50 tokens per ad, not per slide. An unavailable selected primary is not charged. primary_creative_selection distinguishes selected/fallback/unavailable; per-slide title/body/link_url belong to that slide, original_landing_domain to the original ad, and creative_destination_domain to the selected creative. Cloaking detection is not a verified redirect or guaranteed black-creative verdict. _meta.billing.tokens_charged is the actual call debit in Spytrend quota tokens, not model tokens. Quotes are not debits or price locks; admin can be exempt. The TIKTOK corpus (see below) is premium-priced — free/starter 500 tokens lifetime, paid plans 40,000/month, Enterprise = personal limit via https://spytrend.com/contact. - TIKTOK corpus (Pro plan or higher, NOT in the demo tier): pass source="tiktok" on search_ads / get_ad / search_webmasters / get_webmaster to query TikTok instead of Meta. ⚠️ TikTok rows are PREMIUM: every DELIVERED TikTok ad row and every TikTok webmaster row/card costs 100 tokens (Meta rows cost 1) from the same balance (paid plans = 40,000/month = up to 400 TikTok rows). The TikTok default limit is 10 rows and you are charged only for rows actually delivered; media links come embedded in the rows (get_media does not serve TikTok ids). platforms=["tiktok"] does NOT select TikTok — it is a Meta placement filter; use source. ## Tools (call tools/list for the authoritative set) - search_ads, search_creatives (1 token/row; search_ads source="tiktok" = 10 tokens/row) - get_ad / get_media (50 tokens/multilang ad, 1/ordinary ad, 10/creative media; get_ad source="tiktok" = 10 tokens) - get_advertiser / get_webmaster / get_creative (entity detail, 1 token; get_webmaster source="tiktok" = 10 tokens) - search_webmasters / get_webmaster (affiliate networks, 1 token/row; source="tiktok" = 10 tokens/row) - search_hubs (traffic destination hubs, 1 token/row) - search_shops / get_shop (shop directory, 1 token/row) - budget_aggregates (modelled monthly ad budget of 1-3 sites, 1 token) - get_creative_family_monthly_share (monthly creative family shares vs a year earlier, 1 token) - search_products (products ads lead to, per-product ad counts, 1 token/row) - search_influencers / get_influencer (YouTube + Instagram creator directory, no contacts, 1 token/row with statistics) - search_content (Content AI lite search: short-video ideas by meaning, first page only, 1 token/row) - add_to_favorites / list_favorites (saving: 1 token/ad including multilang, 10/creative; listing: free) - get_trends (rankings/aggregates, 1 token/row) - get_usage (free — shows the token balance TikTok rows draw from) ## Discovery - MCP: https://mcp.spytrend.com/mcp · server card: https://mcp.spytrend.com/.well-known/mcp/server-card.json - auth: https://mcp.spytrend.com/auth.md · AS metadata: https://mcp.spytrend.com/.well-known/oauth-authorization-server ## Human / interactive note Claude/Cursor/ChatGPT MCP CONNECTORS via browser-OAuth require human consent and do NOT support client_credentials — the autonomous token path above is for agents (with shell or SDK). With the token + header (2A/2B) those same clients work fully headless. ## Public workflows - Native MCP prompts: spytrend_vertical_intel, spytrend_advertiser_overview, spytrend_webmaster_overview, spytrend_website_review, spytrend_keyword_search, spytrend_shop_discovery, spytrend_startup_research. - Versioned resources: spytrend://skills/v1.1.0/manifest.json - HTTPS manifest: https://mcp.spytrend.com/skills/v1.1.0/manifest.json - Standalone pack: https://mcp.spytrend.com/skills/v1.1.0/spytrend-skills-v1.1.0.zip Prompts are user-controlled and never call data tools or reserve quota by themselves. Read the linked skill and shared contract, call get_usage first, show the bounded spend plan, and keep media off until the user confirms it.