SpendSignoffSpendSignoff
Deep Dive8 min read··SpendSignoff

Claude MCP server for advertising: how the connection works

"Claude is connected to your ad accounts" is a three-line marketing sentence. The actual system has five distinct layers, and the interesting one — the layer that determines whether your budget is safe — is the policy enforcement in the MCP server, not the AI model.

The five-layer architecture

Starting from the user and working inward: (1) you, talking to Claude Desktop or Claude Code; (2) the AI model, reasoning and generating tool calls; (3) the MCP transport layer, serializing those calls over Streamable HTTP; (4) the SpendSignoff policy server, receiving the call and deciding what to execute; (5) the platform APIs — Google Ads and Meta — receiving authenticated requests.

Each layer has a job. The model reasons. The transport carries structured payloads. The policy server enforces what the model is allowed to request. The platform APIs execute what the policy server permits.

Layer 1-2: what the model sees and how it reasons

When you type a request to Claude, the model receives the conversation history plus the tool manifest from SpendSignoff. The manifest lists available tools with their schemas: list_ad_accounts, get_account_snapshot, query_entities, propose_change, and others. The model decides which tool to call based on your request.

The model does not know the underlying API. It knows: "I have a tool called propose_change that takes these inputs." It does not know whether propose_change calls Google Ads directly or deposits to a queue. That is intentional — the model's job is reasoning, not policy.

Layer 3: MCP transport and the call format

SpendSignoff uses the Streamable HTTP transport, which means tool calls arrive as JSON over an HTTP POST. The payload identifies the tool name and the typed input parameters. The server returns a structured JSON result.

The MCP session is initiated with an OAuth 2.1 handshake. Claude Desktop handles this as part of the server connection. The resulting token identifies your organization and is scoped to the operations SpendSignoff permits. The token has no elevated platform permissions beyond what the server itself holds on your behalf.

Example tool call payload (Streamable HTTP)

POST /mcp/v1/call
Authorization: Bearer <session_token>

{
  "tool": "query_entities",
  "params": {
    "account_id": "customers/1234567890",
    "entity_type": "campaign",
    "filters": { "status": "ENABLED" },
    "fields": ["name", "daily_budget_micros", "metrics.cost_micros"]
  }
}

Layer 4: the policy server and the draft queue

This is where spend protection lives. The policy server validates that the requested tool and parameters are within the session's scopes. For read tools, it calls the platform API and returns data. For draft tools, it writes to the draft queue — a Postgres table with a pending status — and returns a draft ID.

The policy server is the sole source of approval authority. There is no path from "model calls propose_change" to "platform API receives a write request" without a human approving the draft. The approve action is a separate HTTP endpoint, authenticated separately, not exposed to the model via MCP.

Why the boundary is server-side

Client-side restrictions can be bypassed with prompt injection. If "do not approve changes" lives only in the system prompt, an adversarial user-turn message can override it. SpendSignoff's approval boundary is server-side: the approve endpoint is not in the model's tool manifest, full stop.

Layer 5: platform API calls and KMS-signed audit trail

When a draft is approved in the dashboard, the policy server calls the platform API with the change. The call is logged as an audit entry signed with Cloud KMS — the log cannot be modified after the fact without breaking the signature chain.

The audit log records: who approved, what was the before state, what was the after state, when, and which platform API call was made. This is the recovery surface. If a change produces unexpected results, you have a complete, tamper-evident record of every decision in the chain.

FAQ

Where are my ad platform tokens stored?
OAuth tokens for Google Ads and Meta are stored in Postgres with application-level envelope encryption using Cloud KMS. The plaintext token never persists to disk; only the KMS-encrypted blob is stored. SpendSignoff decrypts at call time and does not cache the plaintext.
What happens if SpendSignoff's server has an outage?
Read and draft operations fail; no platform API calls are made. Approved drafts that were already submitted continue executing against the platform API, but no new approvals can be processed until service is restored. Your live campaigns are not modified during an outage.
Can I audit which drafts were approved and by whom?
Yes. The KMS-signed audit log is available in the SpendSignoff dashboard under Audit. Each entry shows the approving user's identity, the exact before and after values, and the timestamp. Export to CSV is available for external audit review.

Connect an account read-only and watch the operator work.

Reads are free on every plan. Nothing spends without your two-step approval.

Book a demo

Related reading

    Claude MCP server for advertising: how the connection works — SpendSignoff · SpendSignoff