manage__* tools
The account-management tools on the MCP surface — API keys, agents, connected accounts, session, and remote MCP servers — with arguments and who may call each.
Every caller sees the manage__* tools in tools/list. They are the control
plane of an organization: keys, agents, connected accounts, the active session,
and remote MCP registrations. Two rules apply to all of them:
- Never wallet-gated. A billing hold or spend cap does not stop key management — an organization on hold must still be able to revoke or rotate.
- Most need a signed-in member. Called with any API key, the session-gated
tools return HTTP
200withisError: trueand codejwt_session_required. Themanage__remote_*family is the exception and is role-gated instead. See Authentication.
Amounts are always credits (1,000 credits = $1), and money fields on the
wire are decimal strings such as "1234.567".
API keys
Session-gated. Visibility follows role: a member sees their own keys and the
keys of agents they own; an org admin sees every key in the organization.
can_manage on each row says whether the caller may revoke, rotate, or update
it.
| Tool | Arguments | Effect |
|---|---|---|
manage__keys_create | name · spend_limit_credits? (whole credits, > 0) · expires_at? (ISO 8601) | Mints an sk-cs- key that acts as the caller. The plaintext is returned once. Unknown fields are rejected rather than ignored. |
manage__keys_list | — | Active keys visible to the caller, each with created_by_user_id, can_manage, spend_limit_credits, period_used_credits, usage_period (YYYY-MM), and lifetime used_credits. |
manage__keys_revoke | id | Permanently revokes a key. Keys outside the caller's scope answer "API key not found". |
manage__keys_rotate | id | Replaces the secret; name, cap, and the current month's usage are preserved, so rotation cannot reset a budget. |
manage__keys_update | id · name? · spend_limit_credits? (null removes the cap) · expires_at? (null removes the expiry) | Omit a field to leave it unchanged. Raising the cap above the month's usage unblocks the key; lowering it below blocks it on the next request. |
Agents
Session-gated. Any member may create an agent and becomes its owner; management is owner-or-admin; ownership transfer is admin-only. An agent can never call these tools to widen its own reach. See Authentication for what an agent principal is.
| Tool | Arguments | Effect |
|---|---|---|
manage__agents_create | name | Creates an agent principal; the caller becomes its owner. |
manage__agents_list | — | Every agent in the organization: id (agent_…), name, owner_user_id, status (active · suspended · retired), active_key_count, can_manage. |
manage__agents_update | id · name? · status? (active · suspended) · owner_user_id? | Rename, suspend or resume (reversible kill switch — every key of a suspended agent stops resolving), or transfer ownership (admin only; the new owner must be a member). |
manage__agents_retire | id | Terminal: revokes every active key and sets retired. The record stays for attribution. Use agents_update with suspended for a reversible stop. |
manage__agents_key_create | agent_id · name · spend_limit_credits? · expires_at? | Mints an sk-csa- key that authenticates as the agent. Owner or admin only. The plaintext is returned once. |
Connected accounts
Session-gated. The alias is the value connector tools take as their account
argument when more than one account is connected — see
Connectors.
| Tool | Arguments | Effect |
|---|---|---|
manage__accounts_list | — | Every connected account visible to the caller: connector, alias, identity (email or handle from provider metadata), member_scope (true = your private account, false = shared). |
manage__accounts_rename | connector · current_alias · new_alias | Renames one of your own accounts; the alias must stay unique for that connector in your scope. Shared accounts are not renamable here. |
manage__accounts_remove | connector · alias | Disconnects the account: deletes the credential and revokes the upstream token where the provider supports it. A private account by its member; a shared one by whoever connected it or an org admin. |
Session
Session-gated.
| Tool | Arguments | Effect |
|---|---|---|
manage__whoami | — | The caller's user id, active organization id, and organization name (orgName, null if unresolved). |
manage__switch_org | — | Revokes this agent's authorization so the next browser sign-in re-prompts organization selection, where the user picks. Not instant: tokens already issued keep working in the current organization until they expire. The agent cannot choose the organization. |
Remote MCP servers
Not session-gated: an API key may call these, and role checks bind to the
member who created the key. remote_list is open to any member; the three
writes require an org admin and answer admin_required otherwise. Writes also
respect the organization hold. Registered servers surface as
org__<slug>__<tool>; the concepts are on
Remote MCP servers.
| Tool | Arguments | Effect |
|---|---|---|
manage__remote_add | slug (kebab-case, ≤ 32 chars, unique in the org) · url (https, no IP literals or internal hosts; a query string may configure but never carry a credential) · auth_mode (oauth · static_bearer · none) · display_name? · token? (for static_bearer) · client_id? / client_secret? (for oauth when the server offers no dynamic registration) · headers? (static upstream headers, values encrypted and never returned; authorization is rejected) | Registers the server. For static_bearer and none it also takes the first tools/list snapshot; for oauth it runs RFC 9728 discovery and registers a client, after which members authorize in the dashboard. Calls to remote tools are free but hold-gated. Pass secrets from the environment, never from a conversation. |
manage__remote_list | — | Each registration with url, auth_mode, tool count, and snapshot freshness. Tool metadata is upstream-self-described and unverified. |
manage__remote_refresh | slug | Re-fetches the tools/list snapshot and recomputes schema hashes. One refresh per connector per 60 seconds. |
manage__remote_remove | slug · expected_status? (dcr_pending) · expected_registration_id? | Deregisters the connector, then best-effort deletes its dynamically registered upstream OAuth client. To clear a dcr_pending reservation, pass both optional fields from remote_list so a stale request cannot delete a registration that has since activated. |
Error shapes
A refused manage__* call is a tool result, never an HTTP failure:
{
"content": [
{
"type": "text",
"text": "{\"error\":{\"type\":\"forbidden\",\"message\":\"This operation requires a human session, not an API key.\",\"code\":\"jwt_session_required\"}}"
}
],
"isError": true
}Codes you will meet: jwt_session_required (an API key on a session-gated
tool), admin_required (a non-admin on a remote write), and no_active_org
(a sign-in that has not opened the dashboard yet). Every code is listed in
Errors & status codes.