Every Content Architect feature is callable over the Model Context Protocol. The web UI is one client; AI agents are equal-class clients of the same API surface. Mutations route through the Agent Inbox so every agent-initiated action is policy-gated, idempotent, and audit-logged.
POST /api/mcpAuthorization: Bearer <agent_token>Owners issue tokens from Settings → API (coming soon). For local development:
npx tsx --env-file=.env.local scripts/issue-mcp-token.ts <brand_id> [name]
The raw token is shown once at creation. Store it; it can't be recovered. Tokens are scoped per brand, allow a subset of agent_types, and carry a per-minute rate limit independent of the brand-wide daily cap.
The MCP Inspector is Anthropic's official browser-based debugger. No install needed:
npx @modelcontextprotocol/inspector # In the UI: # Transport: Streamable HTTP # URL: http://localhost:3000/api/mcp # Headers: Authorization: Bearer vsp_test_...
The Inspector renders the tool catalog, lets you fill in arguments from the live JSON Schema, and shows raw JSON-RPC responses. Recommended for any new tool you build.
stdio MCP clients (Claude Desktop, Cursor) connect via the mcp-remote bridge:
// claude_desktop_config.json (or cursor mcp.json)
{
"mcpServers": {
"ads-architect": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:3000/api/mcp",
"--header",
"Authorization: Bearer vsp_test_..."
]
}
}
}Every mutation creates an agent_proposal. A human reviewer or auto-approve policy must approve before the action ships downstream.
Every state transition is one row in agent_decisions , proposed, approved, edited, rejected, executed, failed. Latency tracked per transition.
Mutation tools use an idempotency key so re-running the same logical call upserts one row instead of piling up duplicates.
Each token has its own per-minute budget. Brand-wide daily_cap is enforced independently. 429 on exceed.
Tokens carry an allowed_agent_types allowlist. Tools outside the scope return a clear error.
Mutation tools accept dry_run=true to preview the would-be payload without writing.
The runtime catalog is also discoverable by calling tools/list via JSON-RPC, or interactively via MCP Inspector.
list_influencersList influencersSearch the brand's influencer DB with optional filters and pagination.
| search | string | name or @handle substring |
| tier | nano | micro | mid | macro | mega | |
| grade | A++ | A+ | A | B | C | X | |
| category | string | |
| minFollowers | integer ≥ 0 | |
| maxFollowers | integer ≥ 0 | |
| page | integer ≥ 1 | |
| perPage | integer 1–100 |
{ influencers: Influencer[], total: number }list_inboxList agent-inbox proposalsList proposals in the brand's agent-inbox. Use this to self-correct: see which of your past proposals were approved, edited, or rejected.
| status | pending | approved | edited | rejected | auto_approved | expired | executed | failed | all | default: pending |
| agent_type | string | e.g. 'dm_generation', 'influencer_discovery' |
| limit | integer 1–200 | default: 50 |
AgentProposal[]get_agent_first_metricsGet agent-first ratio metricsDaily breakdown of how often this brand's proposals got approved unchanged. Use this for self-evaluation and drift detection.
| days | integer 1–365 | default: 30 |
Array of { agent_type, day, proposed/approved/edited/rejected counts, agent_first_ratio, avg_review_latency_ms }generate_dmGenerate DM / email draftGenerate three AI DM/email variants for an influencer on a campaign. Routes through the Agent Inbox, a human reviewer (or auto-approve policy) must approve before the message ships.
| influencerId* | uuid | |
| campaignId* | uuid | |
| tone | friendly | professional | casual | default: friendly |
| language | en | ko | default: en |
| channel | dm | email | force a channel; default auto-picks based on contact methods |
| dry_run | boolean | preview model output without writing to DB or creating a proposal |
{ dry_run, draft_id, proposal_id, channel, variants, subject, grade, proposal_data }