Update an MCP server
Partial update: only the fields you send change, and at least one must be sent. Use it to rotate a token, change the approval policy or per-tool decisions, or fix a wrong transport.
Changing serverUrl, name, description or transport re-registers the server with the
voice engine (the provider cannot edit those in place): a new registration is created, every
agent that uses the server is repointed, the old registration is deleted, and every per-tool
decision is re-applied. Its voice-engine registration id changes; the Jelliu id and the agent
assignments do not. Changing only secretToken, customHeaders or approvalMode updates
the existing registration.
For a server on a hosted provider’s host, a different transport and a null secretToken
are refused with 400; a token pasted in a provider URL is moved into the secret, and a wrong
stored transport is corrected. toolOverrides replaces all per-tool decisions and follows the
create rules, checked against the state the server will end up in: switching approvalMode
away from fine_grained while decisions remain is refused. Only one change per server runs at
a time; a concurrent update gets 409. Per-agent gateway rows managed by the platform answer 404.
Side effects. Updates or re-registers the server in the voice engine before
recording anything, repoints agents on re-registration, and pushes per-tool decisions. Writes
an mcp.manage audit entry.
Idempotency. Safe to retry with the same body: values equal to the stored ones do not
re-register. A retry after a 502 on per-tool decisions only re-pushes the decisions.
Webhook events. audit.log_recorded for the audit entry, if you subscribe to it. See Webhooks.
Access
- Required scope:
write. Any workspace role. - Rate limit: General API — 120 (Starter), 200 (Growth), 300 (Business) or 600 (Enterprise) requests/min per workspace, checked by two counters of the same size. See Rate limits.
- Plan: Requires an active subscription (
active,trialingorpast_due); without one the request is refused with403 BILLING_ERROR(metadata.kind: subscription_required).
Authentication
Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the
dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once,
at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.
Operations restricted to admins or owners reject keys without the full scope with 403, and say so in
their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret —
that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds.
See Authentication.
Path parameters
UUID of the MCP server registration. It must belong to the authenticated workspace; an id from another workspace answers 404, exactly like an unknown one. Returned as id by GET /api/mcp-servers.
Request
Unknown keys are ignored. Empty or whitespace-only strings are treated as absent. At least one field is required.
New display name, trimmed. Re-registers the server.
New agent-facing description; null clears it. Re-registers the server.
New MCP endpoint (http/https). Must not target private/internal addresses, directly or through a hostname that resolves to one (400). Re-registers the server.
New credential, stored encrypted; null clears it (refused for hosted providers).
Replaces all custom headers (at most 20). Stored encrypted and never returned.
New approval policy (always_ask, fine_grained or no_approval).
New transport (SSE or STREAMABLE_HTTP). Re-registers the server; hosted providers accept only theirs.
Replaces all per-tool decisions (auto_approved or requires_approval, keyed by tool
name). Only with fine_grained (sent or stored); at most 50; disabled is rejected.
Send {} to clear them.
Response
Updated. toolOverridesSync is present when decisions were pushed or re-applied.
A single MCP server as returned by the create, retrieve and update endpoints: the summary
fields plus deleted_at and the applied per-tool decisions. secret_token and
custom_headers are never returned.
What happened when per-tool decisions were pushed to the voice engine. Present only when decisions were sent, or re-applied after a re-registration or cleanup of legacy values.

