Skip to main content

MCP client

Mecatl connects agents to Model Context Protocol servers. Connected tools enter the catalog as mcp__<server>__<tool> and use the same permission, dispatch, guardrail, and audit paths as built-in tools.

Transport​

Mecatl supports the streaming-HTTP (streamable-HTTP JSON-RPC) transport. It does not start stdio MCP servers as subprocesses. To use a stdio server, place it behind an HTTP proxy such as ToolHive.

Configuration​

Add a global server with the repeatable --mcp-server name=URL flag:

mecated serve \
--mcp-server github=https://mcp.example.com/github \
--mcp-server linear=https://mcp.example.com/linear \
--workspace /path/to/workspace

mecated, mecatequi, and mecak8s accept this flag. Embedded mecatui servers instead read operator profiles from ~/.config/mecatl/settings.yaml.

For bearer authentication, set MCP_<NAME>_TOKEN, where <NAME> is the uppercased server name. Mecatl sends the value in the Authorization header and does not log it. Names must match [A-Za-z0-9_]+ and must be unique without regard to case.

A token-bearing URL must use HTTPS, except for loopback HTTP. The repeatable --mcp-server-insecure-http <name> flag permits one named server to use off-host HTTP. Use it only when network controls and short-lived tokens make cleartext transport acceptable.

export MCP_GITHUB_TOKEN=<TOKEN>
mecated serve --mcp-server github=https://mcp.example.com/github

OAuth operator profiles​

For OAuth, configure an operator mcp.servers profile. Authorize a mutable local profile once:

mecated mcp login SERVER [--no-browser] [--file PATH | --permission-config PATH ...]

Serving restores the encrypted record at startup and persists refresh-token rotation. It never opens a browser. Environment-backed profiles are read-only; update their Secret and restart the process to rotate them.

A named direct/global profile may instead use client: {mode: dcr, dcr: {}} with a mutable local credential store. Direct DCR is a public-client, explicit-consent path: it requests only openid, persists the registration separately from its generation-bound access grant, and never requests or uses refresh. Restart reuses an unexpired grant. Expiry returns login-required without browser launch; an explicit mecated mcp login SERVER reuses the registration and obtains a new grant. For an interrupted registration with the same profile, principal, canonical resource, and exact issuer, use --retry-dcr-registration; pending identity drift is reported as pending-identity-mismatch and requires restoring that matching configuration before retry. To replace a valid ready registration and grant use --reset-dcr-registration. These mutually exclusive flags fail closed on the wrong or corrupt state and never revoke the upstream client. See MCP OAuth and credentials for profile configuration and recovery.

ToolHive discovery​

Mecatl keeps one immutable direct MCP runtime and reconciles ToolHive discovery on one bounded polling loop. A successful complete candidate publishes additions and removals together. If source consultation or candidate construction fails, Mecatl keeps the last usable runtime and marks the cached source status stale. Use --toolhive=false to disable discovery or --toolhive-group <group> to select a group.

Tool namespacing​

Every remote tool is registered as mcp__<server>__<tool>. The namespace prevents a remote tool from shadowing a built-in tool. The complete catalog name must be valid UTF-8, contain no control characters, and fit within 256 bytes. Mecatl rejects malformed names rather than rewriting their identity.

ServerRemote toolCatalog name
githubcreate_issuemcp__github__create_issue
linearsearch_issuesmcp__linear__search_issues
exaweb_search_examcp__exa__web_search_exa

Use the complete catalog name in permission rules. A prefix such as mcp__github__* matches every tool from that server.

permissions:
allow:
- mcp__github__create_issue
deny:
- mcp__linear__delete_issue

Reconnect behavior​

Mecatl reconnects once after a connection drop and retries the interrupted operation. Concurrent operations share that reconnect attempt. If reconnecting fails, the model receives MCP server "<name>" unavailable after reconnect.

Mecatl does not automatically replay a server-declared failure, including structured JSON-RPC 400/404 responses and HTTP 429/502/503/504 responses. This avoids running a mutating operation twice when its first response is ambiguous.

A reconnect keeps the operation's pinned runtime revision. Source reconciliation publishes a complete replacement only after all desired servers connect and list their tools, resources, and prompts successfully.

Resources and prompts​

Mecatl enables two optional MCP capabilities by default:

  • --mcp-resource-tools=true registers ListMcpResources and ReadMcpResource when a server exposes resources.
  • --mcp-prompts=true exposes named prompts as /mcp__<server>__<prompt> key=value commands. Prompts can steer the model, so enable them only for trusted servers.

Typed tool results​

MCP results can contain text, images, audio, embedded resources, resource links, and structured JSON. Mecatl preserves typed blocks in ToolResult.Parts; older string-only results leave Parts empty. The active provider and model determine whether image and audio blocks can reach the model; text, resource links, embedded resources, and structured content always can.

An MCP server's Audience value is a display hint, not an access control. Mecatl still sends every block to the model because the remote server is not trusted to suppress model-visible content.

Mecatl does not automatically follow a resource_link. For HTTPS resources, the model can call FetchMcpResource, which rejects private and metadata addresses and revalidates redirects. For other URI schemes, use ReadMcpResource with the server that owns the resource.

Large and structured results​

Mecatl truncates oversized plain-text results before they enter context. It returns an error for oversized structured results because truncating JSON can make it invalid. A result is structured when the tool declares an outputSchema, returns structuredContent, or returns a JSON content block. Remote tool errors remain plain text and use normal bounded truncation.

To reduce a structured result, use the remote tool's pagination or filtering arguments. You can also call the tool through CallMcpWithQuery, which applies a jq expression before the result enters context:

  • server and tool select the remote operation.
  • args contains the remote tool arguments.
  • jq_filter selects the required JSON fields.

The filter runs in memory without file, standard input, or environment access. Compute, input, and output limits bound its resource use. Broker sessions use their existing attachment and authorization without a second upstream connection.

Server-initiated notifications​

When a current server sends tools/list_changed, prompts/list_changed, or resources/list_changed, Mecatl reconciles all three contract lists through the same bounded path as ToolHive polling. Notifications from a retired runtime do not affect the current publication.

A run or direct team operation keeps the runtime revision it started with. The next operation pins the current publication, so it sees a successful addition or removal without mixing old schemas with new dispatch targets.

Refresh MCP tools for a session​

Automatic reconciliation updates availability but does not grant newly added names to an existing session. Run /mcp-refresh in mecatui, call RefreshMcpSources, or send a bodyless POST to /v1/sessions/<SESSION_ID>/mcp-refresh while the owned root session is idle or completed. The operation adds currently active direct MCP names to that session's existing name authority. It preserves completed state and does not reopen the conversation.

A name that disappears is unavailable but remains in the session's durable name authority. If the exact name returns, the existing grant applies again. A refresh response reports the runtime revision pinned for that operation, which may no longer be the latest revision when the response arrives, and whether that operation's reconciliation cycle or authority union changed anything. Inspect ListMcpSources for the cached current revision, source diagnostics, stale, and reconciliation status; the status call does not probe upstream servers.

Refresh failures use generic client messages. Inspect ListMcpSources to decide whether reconciliation is stale or still running, then retry after the reported condition clears. A save or transport failure can be ambiguous once persistence starts: retry the same refresh. The stable union is idempotent, so a retry either confirms the committed names or applies the still-missing names without removing existing authority.

Authentication and credentials​

MCP OAuth and credentials covers OAuth login, encrypted credential storage, rotation, and Kubernetes provisioning.

Global vs per-session MCP servers​

Server typeLifecycleAvailability
GlobalConfigured at process startup and shared by all sessions--mcp-server, operator profiles, or ToolHive discovery
Per-sessionCreated with one session and closed with itAccepted only by deployments that advertise mcp_servers_on_create

Per-session servers are added to the global catalog. The server limits how many per-session engines can remain open, so close sessions you no longer need with CloseSession or DELETE /v1/sessions/{id}.

What's next​