MCP Architecture
This page explains where the MCP Gateway boundary is drawn: hosted tools versus federation tools, the inbound and outbound request paths, and which capabilities the self-hosted Node runtime and the hosted edge runtime provide.
Management routes versus tool gateway#
Management routes register servers, inspect the catalog, seal credentials, publish tools, and write policies. The tool gateway speaks the streamable-HTTP MCP protocol to external clients and enforces the catalog and policy on every call.
- On the hosted edge, management routes and the tool gateway run as separate services; the tool
gateway owns the MCP origin (
/v1?mcp=<id>). - On the self-hosted Node runtime, several products share one origin, so the tool gateway keeps the
/mcp/v1?mcp=<id>prefix. - The
?mcp=<id>parameter selects a built-in target (provon,duckduckgo) or a registered server id; omitting it returns400 MCP_ID_REQUIREDbefore authentication.
Hosted versus federation#
| Hosted tools | Federation tools | |
|---|---|---|
| Origin | Built-in read-only capabilities with no upstream connection | Proxied to a registered upstream server |
| Execution | Executed by the gateway itself | Outbound over streamable-HTTP MCP or REST |
| Mutations | Read-only | Read or write, per upstream |
| Discovery gating | Registered allowlist; nothing wildcarded | Catalog publish state |
| Default access | Usable out of the box by an mcp:invoke caller |
Default-deny; needs an allow policy |
| Current tools | Web search; trace and Finding readers | Whatever you register and sync |
A tool's publish state (draft / published / deprecated / archived) decides eligibility.
Only published and deprecated tools are eligible for listing and invocation; draft and
archived are closed. Deprecated tools stay eligible but surface a migration notice. Publish
state is orthogonal to principal authorization: a federation tool can be published yet invisible
to a principal with no allow policy, and it cannot be called until that principal is authorized.
Hosted default-allow tools are the exception.
Hosted tools ship with a default-allow flag, so an mcp:invoke caller reaches them even without a
matching access policy; an explicit deny still overrides. Federation tools stay closed until a
policy allows them.
Inbound path (external client to gateway)#
- The tool gateway resolves the caller from the Bearer credential. The ingress accepts only a
project API key carrying
mcp:invoke; a session or any non-API-key caller receives401 UNAUTHORIZED, and a caller the project cannot place receives403 FORBIDDEN. - Per request, the gateway evaluates the project's policies for that principal for the
readorinvokeaction. There is no cached allow-list: every call re-checks authorization, publish state, and the current catalog revision. A tool listed attools/listis not automatically callable. tools/listreturns onlypublishedordeprecatedtools inside the principal's scope, plus the default-allow hosted tools.tools/callre-adjudicates, runs the input guardrail over the arguments, executes the hosted tool or proxies to the upstream, then runs the output guardrail over the result.
Outbound path (gateway to registered service)#
- For a native MCP server, the gateway opens a streamable-HTTP connection and calls
tools/list/tools/call. - For an OpenAPI server, the call is a direct REST request: path parameters come from the tool arguments, remaining arguments become the query string for GET or a JSON body for write methods.
- The sealed upstream credential is injected server-side. The inbound Bearer presented by the caller is never forwarded upstream.
- Every outbound target must be a permitted public host; see Security.
- When a credential fails authentication, the cached connection is dropped so the next call uses the current sealed secret.
Runtime capability matrix#
| Capability | Self-hosted Node | Hosted edge |
|---|---|---|
| List, create, update, delete servers | Yes | Yes |
| Create, list, pause, resume, promote, and revoke credentials | Yes | Yes |
| Create, list, and delete access policies | Yes | Yes |
| Project-wide read-only tool catalog | Yes | Yes |
| Set tool publish state | Yes | Yes |
| OpenAPI document import | Yes | Yes |
| Catalog sync for OpenAPI servers | Yes | Yes |
| Catalog sync for native HTTP MCP servers | Yes | Yes |
| Upstream reachability test | Yes | Yes |
| Hosted tools (web search, trace and Finding readers) | Yes | Yes |
Tool gateway tools/list and tools/call |
Yes | Yes |
| Guardrail budgets, rate limits, and audit attributes on tool calls | Yes | Yes |
Management and invocation are both wired on the hosted edge; the matrix below lists default limits so you can size a self-hosted deployment honestly.
Default runtime limits#
These are per-runtime defaults; the rate-limit bucket dimension differs between the two runtimes.
| Limit | Default | Notes |
|---|---|---|
| Federation calls per minute, fixed window | 120 | Node: per (server, tool) in one process; edge: per (project, principal, tool) in shared project state |
| Hosted-tool calls per minute, fixed window | 60 on Node; shares the edge bucket | Node keeps a separate per-process hosted bucket; on the edge hosted calls share the 120 calls/minute project bucket |
| Concurrent in-flight calls per server | 4 | Node runtime only |
| Per-call timeout | 30 s | Applies to outbound calls |
| Upstream connect timeout | 15 s | Applies to the MCP handshake |
| Tool arguments guardrail budget | 64 KiB | Both runtimes |
| Tool output guardrail budget | 256 KiB | Both runtimes |
| OpenAPI response cap | 1 MB | Both runtimes; larger bodies are withheld rather than truncated |
| OpenAPI direct-fetch timeout | 30 s | Both runtimes |
On Node, the federation and hosted rate gates live in one process and are not distributed across
multiple Node instances. On the edge, the fixed-window bucket is shared across the project's
requests and bucketed per principal and tool. Upstream 429 responses are surfaced independently of
these local limiters.