Create an MCP server
Registers an MCP server with the voice engine and stores it for the workspace. There are two ways to create one.
A custom server needs name and serverUrl. Its approval mode defaults to always_ask
and its transport to the voice engine’s default (SSE) unless you send transport. Most
hosted MCP servers speak streamable HTTP: with the wrong transport the server registers but
never answers a tool call. A custom server reaches no agent until you call
POST /api/agents/{agentId}/mcp-servers.
A hosted provider (provider: zapier, alegra or make; see
GET /api/mcp-servers/providers) needs only its token in secretToken: name, description,
endpoint, transport (STREAMABLE_HTTP) and approval mode (no_approval) come from the
catalogue. Make hosts per region, so serverUrl is required for it. Alegra authenticates
with HTTP Basic: send usuario:token as secretToken. A provider URL pasted without
provider is recognised from its host and held to the same rules; a token found in its query
string or path is moved into the secret so the stored URL never carries a credential. A
hosted provider server is attached to every provisioned agent right away (agents at their
plan cap, or still provisioning, are skipped silently).
Refused with 400 and the field in details.fieldErrors: a transport other than the
provider’s, a missing token, a serverUrl on another host than the provider’s, a malformed
Alegra secret, or a URL that is not http(s) or targets a private/internal address. A hostname
that passes that check but resolves to a private or internal address is also refused with 400,
without details and without naming the address. toolOverrides requires approvalMode: fine_grained, accepts at most 50 entries and rejects
disabled (these three answer 400 without details). When decisions are sent, the
response carries toolOverridesSync; if any failed to apply the status is 207 instead of
201, the server is still created, and toolOverrides shows only what was applied.
Side effects. Creates the server in the voice engine and pushes per-tool approval
decisions; with a hosted provider, also updates every agent’s MCP server list in the voice
engine. The token and custom headers are stored encrypted. Writes an mcp.manage audit entry.
Idempotency. Not idempotent. A retry registers a second, independent server (and, for a
hosted provider, attaches that copy to every agent too, using another slot of each agent’s
cap). After a timeout, check GET /api/mcp-servers before retrying.
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). Automatic attachment of a hosted provider respects the MCP-servers-per-agent cap (Starter 1, Growth 3, Business 10).
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.
Request
Unknown keys are ignored. Empty or whitespace-only strings are treated as absent.
Hosted provider preset: zapier, alegra or make. When set, name and
description are optional and default to the provider’s.
Display name, trimmed. Required without provider.
Sent to the voice engine and read by the agent to decide when to use the server’s
tools. Defaults to the provider’s agent-facing description when provider is set.
The server’s MCP endpoint (http or https). Required without provider, and for
make. Must not target localhost or private/internal addresses; with a provider it
must be on the provider’s host.
Credential, stored encrypted and never returned. Sent to the server as
Authorization: Bearer <token>, or as HTTP Basic for alegra (send usuario:token).
Required with a provider unless customHeaders already carries Authorization.
Extra HTTP headers sent to the server on every request (at most 20; names up to 200 characters, values up to 2000). Stored encrypted and never returned.
Approval policy for the server’s tools: always_ask, fine_grained or
no_approval. Defaults to always_ask for a custom server and to no_approval
with a provider.
SSE or STREAMABLE_HTTP. Fixed to STREAMABLE_HTTP for providers (a different
value is refused). Omitted on a custom server, the voice engine’s default (SSE)
applies and transport is stored as null.
Per-tool approval keyed by the tool name the server advertises: auto_approved or
requires_approval. Only with approvalMode: fine_grained; at most 50 entries;
disabled is rejected with 400 (remove the assignment instead). A tool the server
does not advertise is reported in toolOverridesSync.failures.
Response
Created. toolOverridesSync is present only when per-tool decisions were sent.
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.

