{
  "name": "AdBuyMCP MCP server",
  "page": "https://adbuymcp.com/mcp",
  "checkedAgainstProduct": "2026-10-07",
  "purpose": "Connect Claude, or another client approved for your workspace, to draft, review and report on your awareness plan, with a person approving anything that commits money.",
  "summary": "Each of the 105 tools is a thin wrapper over exactly one REST endpoint, the same endpoint the browser calls. The agent and the browser therefore run on one execution path, with one workspace boundary, one spending check, one approval record and one audit trail. No tool exists for 11 consequential operations, so an agent prepares and proposes, and a named person releases the money.",
  "availability": "AdBuyMCP runs the MCP server, so there is nothing for you to host. MCP access requires an approved workspace and a compatible external client with its own approved client ID and exact callback registration. Connect through Supabase sign-in, workspace selection and OAuth consent. Tool access follows the workspace's enabled capabilities, and consent grants no spend authority. There is no public connector or registry listing.",
  "stage": "Joining the waitlist takes a short form and no card. James is setting the first customers up himself, so he reads every entry and comes back to you, and nothing is bought until the plan, the ads and the start date are confirmed with you. No media has been bought through AdBuyMCP yet. The supply page shows how far buying through each seller has been tested. An MCP connection grants no spend authority.",
  "auth": {
    "summary": "AdBuyMCP operates the hosted MCP server, and every tool call uses a short-lived Supabase OAuth token bound to the person, workspace, registered client and MCP audience. Access requires an approved account and an approved client registration with exact callbacks; there is no public registry listing or automatic client registration.",
    "access": {
      "operatedBy": "AdBuyMCP",
      "deployment": "Hosted service with verified workspace isolation",
      "endpoint": "https://app.adbuymcp.com/mcp",
      "credential": "A short-lived, audience-bound Supabase OAuth token",
      "customerHosting": false,
      "publicConnector": false,
      "publicOAuth": true,
      "accountApprovalRequired": true,
      "clientPreRegistrationRequired": true,
      "dynamicClientRegistration": false
    },
    "agentCredential": "Hosted MCP verifies the Supabase signature, issuer, MCP audience, expiry, registered client identity and server-owned workspace and product claims. Each request receives a short-lived, signed delegation for the API's separate audience, and the API rechecks the actor and workspace. Actor and client attribution persist on actions; an agent credential cannot resolve a human approval or grant itself authority.",
    "modes": [
      {
        "name": "Hosted sign-in uses Supabase OAuth",
        "detail": "This is the deployed sign-in path at app.adbuymcp.com. An approved person signs in, selects their workspace and consents through an authorization-code flow with PKCE S256. Tokens are short-lived and bound to the MCP resource and a registered client. Each external client needs its own approved registration and exact callback URLs; automatic public registration is disabled."
      },
      {
        "name": "A private deployment can use a static token",
        "detail": "The server also has a static service-token mode for a private deployment serving one organisation. It is not how hosted customers sign in and is never used as public multi-user authentication, and the server refuses to start with static tokens and OAuth combined."
      },
      {
        "name": "Development runs without credentials",
        "detail": "A development mode runs without credentials on AdBuyMCP's own machines. Its development identity is no authentication boundary, and the hosted service always requires Supabase sign-in."
      }
    ]
  },
  "protocol": {
    "version": "2026-07-28",
    "legacyPinnedByTests": {
      "http": "2025-11-25",
      "stdio": "2025-11-25"
    }
  },
  "transports": [
    {
      "name": "streamable-http",
      "path": "/mcp",
      "methods": [
        "POST"
      ],
      "stateless": true,
      "sessions": false,
      "serverInitiatedStreams": false,
      "subscriptions": false,
      "limits": {
        "concurrentRequests": 64,
        "bodyMiB": 32,
        "apiDeadlineSeconds": 30
      },
      "detail": "How a registered client reaches the hosted service: stateless request and response on POST /mcp, with a short-lived, audience-bound OAuth token as a bearer header. A client polls the status tools for campaign, booking, approval and asset state."
    },
    {
      "name": "stdio",
      "detail": "The server also speaks stdio, as a local process started beside the client. Customer workspaces are served by AdBuyMCP's hosted service and reached over streamable HTTP."
    }
  ],
  "publicEndpoints": [
    {
      "method": "GET",
      "path": "/healthz",
      "returns": "Service status and the API URL."
    },
    {
      "method": "GET",
      "path": "/capabilities",
      "returns": "Every registered tool's input and output schemas and its REST mapping."
    },
    {
      "method": "GET",
      "path": "/.well-known/oauth-protected-resource",
      "returns": "The hosted MCP resource and its Supabase authorization-server discovery address. This metadata grants no tool access."
    }
  ],
  "toolCount": 105,
  "toolScope": "This is the AdBuyMCP build's full tool list. A deployment can narrow what tools/list returns under its customer's entitlements.",
  "annotations": {
    "note": "These are discovery hints, and a good client uses them to decide what to surface and what to confirm. The security boundary sits a layer below, in the API's fail-closed execution hook, which rejects any consequential call that does not match a registered action and an approval granted for those exact bytes.",
    "counts": {
      "Read-only": 52,
      "Destructive": 40,
      "Idempotent": 34,
      "Open-world": 27
    }
  },
  "groups": [
    {
      "name": "Missions and authority",
      "purpose": "Recover workspace evidence and your agent-owned buyer conversations, then work inside a durable mission and a bounded mandate. An exception stops the run until you say what happened.",
      "tools": [
        {
          "name": "get_buyer_context",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_buyer_sessions",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_buyer_session",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_agent_actions",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "prepare_agent_action",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "create_agent_mission",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_agent_missions",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_agent_mission",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "start_agent_run",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_agent_runs",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_agent_run",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "add_agent_step",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "complete_agent_step",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "request_agent_approval",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "advance_agent_run",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "raise_agent_exception",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_agent_exceptions",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "resolve_agent_exception",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "resume_agent_run",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "record_agent_decision",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "record_agent_evidence",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "finish_agent_run",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Audience and planning",
      "purpose": "Describe who buys from you, turn that into each channel's own targeting terms and draft a plan, or pick the inventory by hand. The registry also keeps the search keyword tools and Google Ads' own forecast, which creates no campaign and spends nothing.",
      "tools": [
        {
          "name": "list_personas",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "extract_persona",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "compile_persona",
          "readOnly": false,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "browse_inventory",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "generate_plan",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "create_manual_plan",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "list_plans",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_plan",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "update_plan_allocations",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "approve_plan",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "suggest_search_keywords",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_plan_search_keywords",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "set_plan_search_keywords",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "forecast_search_performance",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": true
        }
      ]
    },
    {
      "name": "Identity and audience data",
      "purpose": "Match a consented customer list to EUID, check it for opt-outs, and classify UK postcodes with CACI Acorn. Each live call waits for a person's approval, and the EUID agreement and the Acorn licence are both unsigned, so these tools make no live calls today.",
      "tools": [
        {
          "name": "list_identity_cohorts",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_identity_cohort",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "map_identity_cohort",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "check_identity_optouts",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "classify_postcodes",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        }
      ]
    },
    {
      "name": "Creative",
      "purpose": "Read existing creative, adapt a concept for another permitted channel, generate channel-correct copy or upload your own, and precheck it against format and clearance rules. Submission and paid asset production have their own approval gates.",
      "tools": [
        {
          "name": "list_creatives",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "adapt_creative",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "generate_creative",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "upload_creative",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "precheck_creative",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "revise_creative",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "set_campaign_creatives",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "submit_creative",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "get_asset_pricing",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "produce_asset",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "get_asset_status",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Launch and lifecycle",
      "purpose": "Launch, pause and resume a campaign, check its readiness and read every provider attempt. A booking request gives the supplier 12 hours to confirm, a person records the answer, and a request that runs past the deadline never counts as accepted.",
      "tools": [
        {
          "name": "launch_campaign",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "pause_campaign",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "resume_campaign",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "list_campaigns",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_readiness",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_bookings",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "request_campaign_booking",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "list_live_execution_grants",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_campaign_attempts",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_dead_letters",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Delivery and measurement",
      "purpose": "Read delivery, measurement and the journey view, set up tracking and a provider conversion goal, import outcomes and sync an audience. The prove_it tool turns down a test your spend cannot power.",
      "tools": [
        {
          "name": "get_delivery",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_measurement",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_tracking",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "set_campaign_tracking",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "list_campaign_conversion_goals",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "set_campaign_conversion_goal",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "import_outcomes",
          "readOnly": false,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "get_outcome_health",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_report",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "prove_it",
          "readOnly": false,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_campaign_insights",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_journeys",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "sync_audience",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "mmm_readiness",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "run_micro_mmm",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Brand-lift studies",
      "purpose": "Scope, preview, quote and launch a Cint brand-lift survey on a campaign, then read its results. A person approves the purchase. No Cint contract is signed yet, so no live study has been commissioned, and brand lift reports as not commissioned until a campaign has one.",
      "tools": [
        {
          "name": "list_brand_lift_studies",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "get_brand_lift_study",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "get_brand_lift_study_catalogs",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "preview_brand_lift_study",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "create_brand_lift_draft",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "create_brand_lift_study",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "update_brand_lift_study",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "request_brand_lift_quote",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "launch_brand_lift_study",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "refresh_brand_lift_results",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "get_brand_lift_results",
          "readOnly": true,
          "destructive": false,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "request_brand_lift_cancellation",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Optimisation",
      "purpose": "Each proposal carries its reasoning and waits for a person to decide on it before any budget moves.",
      "tools": [
        {
          "name": "generate_optimizations",
          "readOnly": false,
          "destructive": true,
          "idempotent": false,
          "openWorld": true
        },
        {
          "name": "list_optimizations",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "approve_optimization",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "reject_optimization",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        }
      ]
    },
    {
      "name": "Money, connections and audit",
      "purpose": "Read the billing summary, statements and top-ups, the supplier dossiers and the trail of who did what, and ask the server which product and channels it serves.",
      "tools": [
        {
          "name": "get_workspace_overview",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_platform_info",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_brand_analytics",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "list_connections",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_supplier_dossier",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "set_connection",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": false
        },
        {
          "name": "get_billing_summary",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_billing_statement",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "get_topup_status",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        },
        {
          "name": "top_up_wallet",
          "readOnly": false,
          "destructive": true,
          "idempotent": true,
          "openWorld": true
        },
        {
          "name": "get_audit",
          "readOnly": true,
          "destructive": false,
          "idempotent": false,
          "openWorld": false
        }
      ]
    }
  ],
  "humanOnly": {
    "note": "No MCP tool exists for any of these operations. A person performs them through the API or the dashboard, and an agent credential that tries gets a 403 saying which kind of person is required: an approver, a reconciler or a supplier authoriser.",
    "named": [
      "Resolving an approval",
      "Resolving a campaign provider attempt",
      "Acknowledging a booking-workflow step",
      "Resolving an asset job",
      "Replacing a mandate",
      "Revoking a mandate",
      "Closing a mission",
      "Saving a supplier dossier",
      "Verifying a supplier dossier",
      "Issuing a live execution grant",
      "Revoking a live execution grant"
    ],
    "alsoHumanOnly": [
      "Resolving a batch of approvals, or abandoning one",
      "Recording a supplier's answer to a booking line",
      "Recording a managed stop",
      "Resolving a spend lock or a spend stop",
      "Uploading and reconciling provider-spend evidence",
      "Requeuing a dead-lettered provider call",
      "Staging a cancellation",
      "Recording a line's creative approval",
      "Approving, settling and closing a brand-lift study purchase",
      "Importing, deleting or resolving an identity cohort"
    ]
  },
  "limits": {
    "bookingConfirmationHours": 12,
    "uploadMaxMiB": 20
  }
}
