There is one tool registry — read, write, automation, cross-store, and skills tools — and three doors into it: Otto in the dashboard, the MCP server for AI clients, and the public REST API for code. Same tools, same permissions model, same audit trail, whichever door you use.
REST
curl -X POST https://app.magistry.io/api/v1/tools/get_store_overview \
-H "Authorization: Bearer mag_sk_live_..." \
-H "Content-Type: application/json" \
-d '{}'Every tool is POST /api/v1/tools/{tool} with a Bearer API key (mag_sk_live_…). The OpenAPI document at /api/v1/openapi.json describes the full surface; keys are minted on the Developers page, which also shows the tool catalog with each tool tagged read, write, or write-approval.
MCP
The MCP server is a remote endpoint at the dashboard domain, /api/mcp (Streamable HTTP). Claude connects as a claude.ai custom connector, Claude Desktop via mcp-remote, Cursor and other clients natively. Auth is OAuth 2.1 — authorize, token, and dynamic client registration — with store and scope selection in the consent flow, or an API key as Bearer for clients that can't do OAuth.
Scopes
Scopes are fine-grained per resource and action — ads:read, catalog:write — with read, write, and admin bundles for broad grants. Reads run under row-level security: a credential sees exactly the store and data its grant covers, nothing else. Rate limit is 120 requests per minute per credential.
Writes: auto_write vs propose_write
Write tools come in two kinds. auto_write tools apply directly. propose_write tools create an approval card in the dashboard — the external caller proposes, a human approves in Magistry, and only then does the write execute. Auto-apply for propose_write tools is an explicit per-connection opt-in in Settings → Developers, never a default. The result: you can hand an external AI real capability while every consequential change still passes through a human by construction.
