MCP
MCP server
Connect Claude, Cursor, VS Code, Codex, n8n or any MCP client to your workspace with one API key.
The overads MCP server is the same publishing, workflow and analytics surface as the REST API, spoken as tools. Server URL https://api.overads.io/public/v1/mcp, transport Streamable HTTP, auth Authorization: Bearer sk_live_.... The tools a client sees are the ones the key is scoped for.
| Endpoint | https://api.overads.io/public/v1/mcp |
| Transport | Streamable HTTP (POST for JSON-RPC, GET for the standalone stream, DELETE to end the session) |
| Auth | Authorization: Bearer sk_live_YOUR_KEY |
| Session | Minted on initialize, returned in Mcp-Session-Id, idle timeout 30 minutes |
| Rate limit | Shares the workspace's REST budget, see Rate limits |
| Managed workspaces | x-overads-workspace: <id> on the request is honoured by every tool, see Managed workspaces |
| Setup document | https://api.overads.io/public/v1/mcp/setup, the snippets below as JSON, no key needed |
Create the key in Settings > API Keys & MCP. For an assistant that only reads, give it connections:read, posts:read and analytics:read; add posts:write and media:write when it should schedule, and workflows:run when it should run automations.
Client setup
Claude Desktop
{
"mcpServers": {
"overads": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.overads.io/public/v1/mcp",
"--header",
"Authorization:Bearer sk_live_YOUR_KEY"
]
}
}
}Claude Desktop reaches remote servers through mcp-remote. Settings > Developer > Edit Config, paste, then restart Claude Desktop.
Claude Code
claude mcp add --transport http overads https://api.overads.io/public/v1/mcp --header "Authorization: Bearer sk_live_YOUR_KEY"Run once in a terminal. Check with claude mcp list; the tools appear in every session.
Cursor
{
"mcpServers": {
"overads": {
"url": "https://api.overads.io/public/v1/mcp",
"headers": {
"Authorization": "Bearer sk_live_YOUR_KEY"
}
}
}
}Project-level in .cursor/mcp.json, or global in ~/.cursor/mcp.json. Cursor > Settings > MCP shows the connection.
VS Code
{
"servers": {
"overads": {
"type": "http",
"url": "https://api.overads.io/public/v1/mcp",
"headers": {
"Authorization": "Bearer sk_live_YOUR_KEY"
}
}
}
}For GitHub Copilot agent mode. Open the file and press Start above the server entry.
Codex
[mcp_servers.overads]
url = "https://api.overads.io/public/v1/mcp"
http_headers = { Authorization = "Bearer sk_live_YOUR_KEY" }OpenAI Codex CLI reads MCP servers from config.toml. Restart Codex after editing.
Windsurf
{
"mcpServers": {
"overads": {
"serverUrl": "https://api.overads.io/public/v1/mcp",
"headers": {
"Authorization": "Bearer sk_live_YOUR_KEY"
}
}
}
}Windsurf > Settings > Cascade > MCP servers, or edit the file directly and refresh.
n8n
Node: MCP Client Tool
Endpoint: https://api.overads.io/public/v1/mcp
Server transport: HTTP Streamable
Authentication: Bearer auth
Token: sk_live_YOUR_KEYAttach the node to an AI Agent; every tool the key is scoped for is offered to the agent.
Zapier
Zapier Agents > Tools > Add MCP server
Server URL: https://api.overads.io/public/v1/mcp
Authentication: Custom header
Header: Authorization
Value: Bearer sk_live_YOUR_KEYAvailable on Zapier plans that allow custom MCP servers. The agent sees the same tool list as any other client.
Any MCP client
curl -sS https://api.overads.io/public/v1/mcp \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'Streamable HTTP: POST initialize, keep the Mcp-Session-Id response header, send it on every later request, DELETE to end the session.
What the server tells the model
The initialize response carries instructions every client should surface. Three rules matter for anyone building on top:
- Approvals. When the workspace requires approval for scheduled posts,
create_postandupdate_poststill succeed, but the post lands withapprovalStatus: "pending"and the result carries a warning with codeAPPROVAL_REQUIRED. The post will not publish until a member approves it in the app. The model should say so, not retry, and not call publish now to get around it (it is refused with the same code). - Idempotency. Every write tool (
create_post,update_post,delete_post,get_upload_url,complete_media,delete_media,run_workflow) accepts an optionalidempotencyKey. A fresh one per intended write, reused on retry: same key and arguments replays the first result, different arguments isIDEMPOTENCY_KEY_CONFLICT, still running isIDEMPOTENCY_IN_FLIGHT. Keys live 24 hours. - Null is not zero. A counter that is null was not measured. Analytics results carry
dataandprovenance; the model must readprovenancebefore stating a conclusion fromdata.
Sessions and errors
- A session belongs to the workspace whose key opened it. A valid key for another workspace with a session id it did not mint gets
404, the same answer as an unknown session. - An expired session (30 minutes idle) answers
404with a message saying to sendinitializeagain. - A tool that is not in the key's scopes, is gated off on this deployment, or does not exist all answer the same way:
Unknown tool. This is deliberate; the error does not enumerate what the deployment holds. - Tool errors come back as MCP tool results with
isError: trueand the samecodestrings as the REST catalogue.
Legacy single-POST clients
A POST with no Mcp-Session-Id header and no Accept: text/event-stream is treated as a first-generation single-request JSON-RPC call and answered with plain JSON: initialize, ping, tools/list and tools/call only. This path is kept for one release. New integrations should use the Streamable HTTP transport.
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_connections","arguments":{}}}