This article was drafted with AI assistance and checked against the sources listed.
Key takeaways
- Use an app-scoped management key with read permission to review one app's campaigns without granting write access.
- Check the key with whoami, then request campaign reports and decisions for the same explicit reporting period.
- Keep verified, matched, estimated, and organic or unknown results separate when explaining campaign performance.
- Report the decision tool's call unchanged, including insufficient data, and review missing spend or revenue before acting.
- An app key cannot reach sibling apps, workspace ad integrations, or workspace usage controls.
Claude Code marketing analytics means asking Claude Code to read campaign data through connected tools and explain what supports a budget decision. For AttriKit, the connection is its Model Context Protocol server, with access bounded by a management key. Start with an app-scoped key that has read permission, then ask which campaigns need attention and why.
Connect the client and check the key
Model Context Protocol, or MCP, is an open-source standard for connecting AI applications to external systems. Anthropic's MCP documentation describes how Claude Code connects to tools, databases, and APIs through MCP servers.
AttriKit exposes 39 management tools through its MCP server. These include campaign reports, attribution totals, spend, recent events, and campaign decisions. The server also exposes write tools, so choosing the key is part of setting up the workflow.
Create the first management key in the AttriKit dashboard under Settings, API keys & MCP. Select the app you want to review and give the key read permission. Keep write permission off for this reporting session.
Follow the MCP setup guide for the client configuration. AttriKit's Claude Code configuration goes in the project's .mcp.json. It starts @attrkit/mcp through npx and forwards ATTRKIT_API_KEY from the environment. The macOS login command provides another route: it checks the key and stores it in the Keychain.
Keep the secret out of the conversation and configuration file. Anthropic documents environment variable expansion in .mcp.json, so the configuration can reference a variable without containing its value.
Run claude mcp list to inspect the client connection. Then ask the agent to call whoami. AttriKit returns the authenticated workspace, app restriction, and read/write scopes. Check those before requesting campaign data.
A connected process is not proof of a valid key. AttriKit's troubleshooting guide specifically recommends whoami when the client connects but tool calls fail authentication.
What an app-scoped key cannot reach
App scope and read permission answer different questions. App scope determines which app the key can reach. Read permission determines whether the session can inspect data without changing it.
The Management API capability matrix applies to MCP too. An app key stays clamped to its app even when it has write permission.
| Resource or operation | App-key boundary |
|---|---|
| Campaign reports, decisions, events, links, and spend | Its app only |
| Other apps in the workspace | Outside its scope |
| Creating another app | Not allowed |
| Ad integrations | Workspace-only operations; not allowed |
| Workspace usage cap and alert email | Not allowed |
| Billing, login, membership, workspace deletion, and internal administration | Not exposed through MCP |
This matters when a reporting task encounters missing data. If the agent cannot inspect a workspace integration, do not replace the key with a workspace key just to complete the answer. Have it name the unavailable check. Review that configuration separately.
An app-scoped key with write permission can still change resources belonging to its app. The documented capabilities include updating or archiving that app, rotating its publishable key, and managing keys clamped to it. App scope alone does not make a session read-only.
For a solo developer reviewing one product, start with the narrower combination: one app and read permission. Expand access only for a separate task that needs a specific write.
Ask for a campaign review with a defined period
"Which campaign should I cut?" leaves the reporting period and decision basis unspecified. Give the agent both before it starts.
Use a prompt like this:
Review only the app allowed by this key. Call whoami first and report the app restriction and permissions without showing the key. Ask me to choose a reporting period, then use that same period for campaign reports, the attribution rollup, and campaign decisions. Page the campaign reports through every next_cursor. In get_campaign_decision, keep the current calls in suggestions apart from the recorded history in data, and name any campaign that has no current call. Report each decision call exactly as returned. Explain the supporting spend, revenue, evidence labels, and missing data. Do not call write tools.
The period instruction prevents a specific mismatch. AttriKit's tool definitions document different defaults for list_campaigns and get_campaign_decision. An explicit shared period avoids comparing one report with a decision covering another window.
Use list_campaigns for the campaign report and get_campaign_decision for the engine's scale, cut, or hold call. The decision tool instructs the agent to report that call verbatim. When it returns not_enough_data, the answer should say that.
Ask the agent to distinguish the returned decision from its own explanation. A useful answer says which tool supplied the call, which period it covered, and which missing inputs limit the interpretation.
Do not accept a complete-looking ranking from an incomplete list. The reports support pagination. An agent should follow next_cursor until there are no more pages before claiming it reviewed every campaign.
The decision tool pages differently. Its next_cursor pages the recorded decision history in data, while the current calls arrive in suggestions, which are capped at the request's limit and do not page. Following the cursor therefore does not bring in more current calls. Ask the agent to name any campaign that has no current call instead of assuming one.
Read the evidence labels before accepting the explanation
AttriKit's product copy distinguishes verified, matched, estimated, and organic or unknown results. Preserve those labels in the answer. A sentence that replaces them all with "attributed installs" removes information you need for the decision.
The attribution rollup returns evidence-class totals, revenue, marketing efficiency ratio, and data freshness. Ask the agent to show the returned categories separately and explain any field it cannot interpret from the response.
Estimated campaign totals should remain estimates. AttriKit's reporting documentation also distinguishes campaign-level modeled remainders from results allocated to individual ads. If a remainder has no ad allocation, the agent should leave it at campaign level.
Organic or unknown should stay separate too. AttriKit's documentation says the organic residual is never reassigned to a campaign. Do not ask the agent to distribute it across campaigns to make the report look complete.
A useful follow-up prompt is:
Restate the recommendation without merging evidence categories. Identify any estimated amount and any campaign-level remainder that is not allocated to an ad. Leave unknown values unknown. Show which returned fields support each conclusion.
Ranges need the same care. The campaign tool exposes aggregation_basis and tells the agent to read it before describing a lower endpoint. A sum of component endpoints is a scenario, not a guaranteed floor.
You do not need to interpret those fields from memory. Ask the agent to include the returned basis beside its explanation. Reject wording that turns a scenario into a promise about the campaign's worst possible result.
Check missing spend and revenue before cutting
A campaign review should include data completeness, not just a ranking.
AttriKit's get_spend tool returns imported spend, cost models, completeness, and spend freshness. Ask for those checks before accepting a recommendation based on return after costs.
Reading spend and refreshing spend are different operations. get_spend reads the stored data. pull_network_spend fetches and imports data, and its tool definition marks it as a write. A reporting session should report stale spend rather than silently refreshing it.
Revenue needs an explicit basis too. Ask the agent to identify the period, currency information, and missing revenue fields in the report. AttriKit documents that campaign and ad report revenue can be null when it spans multiple currencies. Null is not zero.
If the question is whether subscription revenue has joined the correct installs, use the RevenueCat attribution guide as the separate diagnostic reference. Do not turn an unresolved revenue question into a confident campaign cut.
Before accepting the campaign review
- The key names the intended app and has read permission without write permission.
- Every report and decision uses the same explicit period.
- Every paginated list has been read through its final page.
- The answer preserves the returned decision call and evidence categories.
- Spend completeness, freshness, and missing revenue are stated.
- The answer separates the proposed budget action from any recorded or executed change.
Keep write tools separate from the analysis
AttriKit's MCP tools include mutations as well as reports. Examples include importing spend, changing a campaign link's status, and recording a campaign decision. The Management API requires write scope for mutations.
The tool definitions label read tools with readOnlyHint: true and write tools with readOnlyHint: false. Those labels describe the tools. Use the key's permissions to restrict this reporting session.
Do not assume every write has a confirmation screen or preview. The record_campaign_decision schema has no confirmation or dry-run argument. It takes the app, campaign, decision call, reporting period, and an optional idempotency key, then submits the write.
For AI agent campaign analytics, keep the first session focused on the answer. If you later want a decision recorded, authorize that as a separate action with an appropriate key.
record_campaign_decision freezes the reviewed period's current campaign range, spend, costs, revenue basis, and model version server-side. Its description says callers cannot author that receipt provenance. Record only a returned scale, cut or hold call, with the same period you reviewed. A not_enough_data call is reported, not recorded: the tool accepts only scale, cut and hold.
Recording a decision is not evidence that an advertising budget changed. Likewise, update_link_status changes an AttriKit tracking link's status; do not describe that result as pausing an advertising campaign.
If a write times out, follow AttriKit's documented retry rule: reuse the same idempotency key for the same request. A timeout can leave the result uncertain. Starting a new request does not resolve what happened to the first one.
End with a decision you can inspect
The output of a Claude MCP attribution review should be short enough to check against its inputs. Ask for the app, reporting period, returned campaign call, supporting figures, evidence categories, and unresolved checks.
A campaign may be a candidate to cut. It may also need a spend correction, a revenue investigation, or more data. The answer should preserve that distinction.
Finish with a concrete next action for each campaign. Read-only analysis ends with a recommendation and its evidence. Any recording or operational change gets its own authorization and result.
Sources
- What is the Model Context Protocol (MCP)?, Model Context Protocol · read Oct 30, 2026
- Connect Claude Code to tools via MCP, Anthropic · read Oct 30, 2026
Originally published on the AttriKit blog. AttriKit is web-to-app attribution for iOS and Android, built by Clashware Sàrl in Lausanne.
Top comments (0)