Skip to main content
The MCP server registers 24 tools: everything the dashboard can do except ingest, which is your own server talking and has no business being reachable by an agent. The three destructive ones are delete_mcp, revoke_key and remove_member.

Permissions are the API’s, not the connector’s

Nothing in the MCP layer decides who may do what. Every tool calls the same service function the REST route calls, and hits the same guard — assertMcpWriteAccess, or an account role check. So a member asking an agent to delete an MCP gets refused with the same sentence they would get in the dashboard, and an admin acting on an owner gets refused for the same reason. Exposing writes over MCP needed no new permission code. See Roles and permissions.
Annotations are hints to your client, not enforcement. A client may call a read tool without asking and will usually confirm a destructive one. The enforcement is the service guard underneath, which no hint can bypass.

Shared arguments

Four inputs recur, and three of them take a human-readable handle rather than an id. Each resolver refuses ambiguity rather than guessing, and each error lists the valid options so a model can retry correctly instead of reporting a dead end.
  • Email for a member, because that is what someone says out loud — “remove ada@…” — and because it is the only stable handle for an invited person, who has no user id until they first sign in.
  • Prefix for a key, because the key itself is hashed and never stored, so the prefix is all a list can show. An ambiguous prefix is refused: revoking the wrong key is a silent outage that looks like the SDK breaking.
last_days exists because it is what a model actually has. Asked for “the last 30 days” with only dates available, a model must know today and do arithmetic — and one that is a day out reports a number that is quietly wrong rather than visibly broken. Explicit dates still win when given. Omitting all three gives the last 30 days. See Date ranges.

MCPs and keys

create_mcp returns the MCP with its id but no ingest key — see below. delete_mcp cannot be undone and the data is not recoverable, so confirm with the user first. revoke_key is worth a specific warning: any server still using that key stops reporting, and the SDK swallows the failure, so nobody gets an error — the data simply stops.

Metrics

Narrowing get_overview

metrics takes any of: Summary — returned when metrics is omitted: calls · first_call_success · latency · cost · sessions · outcomes · response_size Detail — returned only when named, because each is an array long enough to swamp an answer: daily · tools · clients · follows · sparklines Ask for only what was wanted. metrics: ["calls"] returns calls and nothing else; prefer that over pulling the whole overview to read one field. range, nightly_as_of and filters are always present — without them every figure is a number with no idea what it is a number of. With a tools filter on, sessions and cost per session come back null. A session belongs to the server, not to a tool. See The overview.

Account and team

Three details that change what an agent should do: invite_member — ask for the name. Without full_name the team list shows an address where a person should be, until they sign in and fill in their own profile. update_profilenull clears, omitting changes nothing. They are different instructions. update_notifications replaces, it does not merge. Call get_notifications first and send it back changed, or every event you leave out falls back to its default. The event keys are enumerated in the schema, so a model can see the valid options rather than guessing one and being silently ignored.

Two tools that deliberately don’t exist

No create_key

Every other write is reachable over MCP because an agent doing it is the point. Minting a key is the exception. The full key exists exactly once, in the response — and a tool result goes straight into a model’s context, and from there into a conversation transcript, a provider’s logs, and whatever the model says next. That is a credential leaked to three places nobody audited, to save one visit to the dashboard. Keys are made on /m/:id/keys, shown once, and never again. list_keys and revoke_key stay, because a prefix is not a secret and revoking is the thing you want to do in a hurry. See Create a key.

No delete_account

It was built with the dashboard’s own safeguard — type the account name — and removed anyway, because that safeguard is the wrong shape here. In the dashboard a person types the name into a box. Over MCP a model would already be holding the name, having read it from get_account a moment earlier, so the one thing the confirmation was supposed to prove is the one thing it cannot. It is the only action in the product with nothing to come back from. That belongs behind a person and a screen: /settings/my-account.

Errors

Two kinds, treated oppositely. A caller error is repeated verbatim, because it is actionable — “No MCP named ‘orders’. Yours are: Acme Orders, Staging”, or “This action requires the admin role”. A model can act on both. Permission messages carry most of the weight now that writes exist: a refused write should say why rather than fail obscurely. Anything else returns “Internal error. The failure has been logged.” Database errors carry column names, constraint names and sometimes values, and a tool result goes somewhere worse than a log.