Providers & Search

MCP Gateway

Quick answer
Prism runs a single MCP endpoint at http://127.0.0.1:11434/mcpthat aggregates every Model Context Protocol server you have enabled. Agents authenticate with Prism's own token and never see upstream credentials, and each agent can be restricted to its own set of servers through /mcp/<agent>.

Last updated Reviewed against Prism v0.3.26

Why route MCP through Prism

Problem without a gatewayWhat Prism does
Every agent needs every server configured separatelyConfigure a server once in Prism; every agent reaches it from one URL.
Each agent stores its own copy of API keys and OAuth tokensPrism holds the credentials and brokers OAuth, so agents hold only Prism's token.
Adding a server means editing one config file per agentOne write in Prism, then re-sync agent access.
No visibility into which agent used which toolPrism owns the connection and reports server health in /mcp/status.
Different agents support different transportsPrism speaks stdio, Streamable HTTP and the older HTTP+SSE upstream.

Endpoints

EndpointReachesMethod
/mcpEvery enabled server in your config.POST (Streamable HTTP), plus GET /mcp/status
/mcp/<agent>Only the servers allowed for that agent id.POST
/mcp/statusHealth of every server, plus the agent bindings map.GET
/mcp/controlAdmin control channel: status, restart, probe.POST
# Every enabled server
POST http://127.0.0.1:11434/mcp
Authorization: Bearer prism
Content-Type: application/json

# One agent's allowlist only
POST http://127.0.0.1:11434/mcp/claude-code
Authorization: Bearer prism

The whole gateway sits behind the same token as the rest of the proxy, so Authorization: Bearer prism and x-api-key: prism both work. Agent ids are the same 14 ids Prism uses in the Agents tab, such as claude-code, codex or zed.

Supported methods

JSON-RPC methodPrism's behaviour
initializeLegacy handshake, kept so older clients connect. Echoes the client's protocol version, defaults to 2025-06-18.
server/discoverThe stateless revision's discovery call. Returns the 2026-07-28 version, TTL and a private cache scope.
tools/listEvery tool from every reachable server, namespaced. Servers that fail are reported in the status instead of failing the call.
tools/callRoutes a namespaced tool call to its upstream server with that server's credentials.
pingReturns an empty result.
resources/list, prompts/listReturn empty lists. Prism exposes tools only.

Prism identifies itself as the server prism version 1.0.0, and tells the agent that tool names follow the mcp__<server>__<tool> convention.

Tool namespacing

Two servers can both expose a tool called search. To keep them distinguishable, Prism prefixes every tool name with its server id.

Upstream servers                 What the agent sees
────────────────                 ───────────────────
weather    → get_forecast        mcp__weather__get_forecast
github     → search              mcp__github__search
filesystem → read_file           mcp__filesystem__read_file

Server ids are whatever you named the server in Prism — which the marketplace prefills from the registry entry. Only the first __ after the server id splits the name, so upstream tool names that contain double underscores still route correctly.

Unnamespaced calls are rejected
A tools/call with a bare tool name returns a JSON-RPC invalid-params error telling the agent to use the names from tools/list.

Transports

TransportUse it whenFields
stdioThe server is a local process — npx, uvx, docker, a binary.command, args, env, cwd
httpThe server exposes the Streamable HTTP transport.url, headers
sseThe server only exposes the deprecated HTTP+SSE transport.url, headers

For stdio servers, Prism resolves the command from your PATH and then from the places a GUI process does not inherit — /opt/homebrew/bin, ~/.local/bin, ~/.npm-global/bin, ~/.cargo/bin, ~/go/bin and the platform npm config directory. On Windows, .cmd and .bat shims such as npx are run through cmd.exe, which exec cannot do directly.

Authentication to upstream servers

ModeMeaning
noneThe server needs no credentials.
staticPrism sends the headers or bearer token you supplied.
oauthPrism runs the MCP OAuth 2.1 flow and stores the resulting token for you.

Brokered OAuth

With oauth, Prism discovers the server's authorization server, registers a client, opens your browser for consent, and stores the access and refresh tokens in config.json with file mode 0600. Tokens are refreshed automatically 60 seconds before expiry, and an upstream 401 triggers a refresh attempt before the call is retried.

Prism supports three registration modes and caches a registered client per authorization server, so a second MCP server on the same provider reuses the existing registration instead of registering again.

Registration modeHow the client id is obtained
dcrDynamic client registration (RFC 7591) — the default when the server supports it.
preregisteredA client id you already have, entered manually.
cimdClient ID Metadata Document — off by default because it needs a stable HTTPS document you host yourself.
auto_connect
When auto_connect is on (the default), the first agent call to an unauthorized OAuth server opens the sign-in window by itself and the call is retried once you approve. Set it to false in the MCP tab if you would rather authorize servers manually, up front.

Add an MCP server

1

Open the MCP tab

In the Admin UI, select MCP.
2

Search the marketplace or add manually

Search the registry for a server, or add one yourself and fill in the transport: a command for stdio, or a URL for HTTP and SSE.
3

Set the auth mode

Choose none, static (paste the header or token) or oauth. For oauth, click Authorize and complete the browser flow.
4

Optionally restrict its tools

A per-server tool allowlist narrows what Prism exposes. An empty allowlist means every tool the server defines.
5

Grant agents access

In the Agent access panel, tick which agents may reach this server. Prism writes an entry into each agent's own MCP config with the Prism token.

The marketplace

Prism ships with the official registry (registry.modelcontextprotocol.io) seeded and searches its catalog locally, so typing in the search box is instant and works offline once synced. Any registry that speaks the same OpenAPI shape can be added as an extra source — a private or company catalog becomes a drop-in addition rather than a separate client.

Install pathWhat Prism does
Package manager entryWrites a stdio server using npx or uvx, with the registry's declared arguments and secrets.
.mcpb bundleDownloads the archive and verifies its published SHA-256 before unpacking — nothing runs unless the digest matches. Downloads are capped at 512 MB.
Git importPoint Prism at a repository containing an mcp.json and every server it declares is added, with ${PLUGIN_ROOT} and ${PLUGIN_DATA} resolved for you.
Verified publishers
The registry enforces reverse-DNS namespaces, and Prism additionally checks that the namespace and the source repository owner agree. A server whose namespace matches its repository is shown as verified, so a copied namespace cannot borrow someone else's repository.

Per-agent access

Access is an allowlist per agent. An agent reaching /mcp/<agent> sees only its own servers, and a tools/call for a server outside that list is rejected with "server is not enabled for this endpoint". The unrestricted /mcp endpoint reaches every enabled server.

Prism writes the gateway entry into each agent's own MCP config file:

AgentMCP config fileServer map
Claude Code~/.claude.jsonmcpServers
Codex~/.codex/config.tomlTOML tables
Factory Droid~/.factory/mcp.jsonmcpServers (with oauth: false)
OpenCode~/.config/opencode/opencode.jsonmcp (type: remote)
ZCode~/.zcode/cli/config.jsonmcp.servers
ZedZed settings.json (JSONC)context_servers
Grok Build~/.grok/config.tomlTOML tables
Pi~/.pi/agent/mcp.jsonmcpServers (read by the pi-mcp-adapter extension)
Oh My Pi (OMP)~/.omp/agent/mcp.jsonmcpServers
Kimi Code$KIMI_CODE_HOME/mcp.json or ~/.kimi-code/mcp.jsonmcpServers
Prime Agent~/.prime/agent/settings.jsonmcpServers (user scope only)
Empryo%LOCALAPPDATA%\Empryo\config.json or ~/.empryo/config.jsonarray-shaped server list
Hermes%LOCALAPPDATA%\hermes\config.yaml or ~/.hermes/config.yamlserver list
DeepSeek Harness$DSH_HOME/cordis.patch.yml (default ~/.dsh)one insert row
Every entry carries the same header
Prism writes Authorization: Bearer prisminto each agent's entry — never an upstream key. Removing access deletes only Prism's entry, leaving any servers you configured yourself untouched.

Limits and lifecycle

LimitValueWhy
Request body cap8 MBA malformed or hostile agent cannot exhaust memory.
Idle stdio reap300 seconds (configurable)Local server processes are shut down when unused, and restarted on demand.
Tool list cache30 secondsKeeps tools/list fast without going stale.
Tool list timeout20 secondsOne slow server cannot stall a tools/list across many servers.
Tool call timeout10 minutesLong-running tools still have a bound.
Crash recoveryOne restart per failureA dead process is replaced once before the error is reported.

Remote HTTP and SSE servers are left connected because keeping them costs nothing; only child processes are reaped. Changing the idle timeout in the MCP tab sets idle_timeout_sec.

Server states

StateMeaning
readyConnected and answering.
idleConfigured but not started yet — normal for stdio servers between calls.
needs_authThe upstream rejected the credentials. Authorize it, or let auto-connect do it.
runtime_missingThe command could not be found — install Node or uv, or give an absolute path.
errorAny other failure. The message is reported in /mcp/status and the MCP tab.
disabledTurned off in Prism, so agents do not see it.

Configuration

{
  "mcp": {
    "servers": [
      {
        "id": "weather",
        "name": "Weather",
        "transport": "stdio",
        "enabled": true,
        "command": "npx",
        "args": ["-y", "@example/weather-mcp"],
        "env": { "WEATHER_API_KEY": "..." },
        "auth_mode": "none"
      },
      {
        "id": "linear",
        "name": "Linear",
        "transport": "http",
        "url": "https://mcp.linear.app/mcp",
        "enabled": true,
        "auth_mode": "oauth"
      }
    ],
    "agent_servers": {
      "claude-code": ["weather", "linear"],
      "zed": ["weather"]
    },
    "idle_timeout_sec": 300,
    "auto_connect": true,
    "registries": [
      { "id": "official", "name": "Official MCP Registry", "base_url": "https://registry.modelcontextprotocol.io", "enabled": true, "builtin": true }
    ]
  }
}
Tokens live in config.json
OAuth tokens, client secrets and upstream headers are stored in config.json with mode 0600 and masked on the way to the admin UI. Everything MCP-related stays on your machine.