---
title: "JSON-RPC 2.0 endpoint for the gateway's MCP server"
method: POST
path: "/mcp"
tags: ["MCP"]
---

# JSON-RPC 2.0 endpoint for the gateway's MCP server

`POST /mcp`

JSON-RPC 2.0 endpoint exposing the gateway itself as an MCP server. It
aggregates every server configured in `MCP_SERVERS` behind one URL, so
MCP clients (opencode, `infer`, IDE assistants) configure a single entry
and get the whole fleet, with the gateway's auth, metrics and guardrails
applied to every tool call.

The endpoint lives at the root, not under `/v1` - `/v1/*` is the
OpenAI-compatible surface, MCP is its own protocol and clients expect a
plain `/mcp`.

Gated by `MCP_EXPOSE=true` (and `MCP_ENABLED=true`); otherwise the
gateway answers `403`. Gateway auth is global, so when `AUTH_ENABLE=true`
this endpoint requires a bearer token like every other route except
`/health`.

The endpoint speaks MCP protocol version `2026-07-28` only, over the
stateless Streamable HTTP transport with `application/json` responses.
There is no `initialize` handshake and no session: every request carries
its protocol version in `params._meta["io.modelcontextprotocol/protocolVersion"]`
(alongside the required `io.modelcontextprotocol/clientInfo` and
`io.modelcontextprotocol/clientCapabilities`), mirrored in the
`MCP-Protocol-Version`, `Mcp-Method` and, for `tools/call`, `Mcp-Name`
headers. `Mcp-Name` may use the `=?base64?<value>?=` encoding.

Supported methods:

| Method | Params | Result |
| --- | --- | --- |
| `server/discover` | `_meta` only | `DiscoverResult` - `supportedVersions` (`["2026-07-28"]`), `capabilities` (`tools`) |
| `tools/list` | optional `cursor` | `ListToolsResult` - the aggregated, namespaced tools of every healthy MCP server |
| `tools/call` | `CallToolRequestParams` (`name`, `arguments`) | `CallToolResult` |

Every result carries `resultType: "complete"` and identifies the gateway
in `_meta["io.modelcontextprotocol/serverInfo"]`.

Param and result shapes are the vendored MCP spec types in
[`mcp/mcp-schema.yaml`](https://github.com/inference-gateway/schemas/blob/main/mcp/mcp-schema.yaml)
(`RequestMetaObject`, `DiscoverResult`, `ServerCapabilities`,
`ListToolsResult`, `CallToolRequestParams`, `CallToolResult`); this spec
only describes the JSON-RPC envelopes the gateway puts them in.

`tools/list` tolerates partial availability: when one of the configured
MCP servers is unreachable its tools are omitted and the healthy servers'
tools are still returned, rather than failing the whole call. A
`tools/call` routed to an unavailable server fails with JSON-RPC error
code `-32603`.

Errors use JSON-RPC error envelopes:

| Code | Meaning | HTTP status |
| --- | --- | --- |
| `-32020` | header mismatch - a required header is missing, malformed or disagrees with the body; a legacy `initialize` request lands here | `400` |
| `-32022` | unsupported protocol version; `data` carries `requested` and `supported` | `400` |
| `-32601` | method not found | `404` |
| `-32700` | parse error | `200` |
| `-32600` | invalid request | `200` |
| `-32602` | invalid params (unknown tool name, bad arguments) | `200` |
| `-32603` | internal error (upstream MCP server failure) | `200` |

A request carrying an `Origin` header is rejected with `403`: MCP
clients are not browsers, and this blocks DNS-rebinding attacks. `GET`
and `DELETE` answer `405` - there is no standalone stream and no session
to terminate.

## Headers

- `MCP-Protocol-Version` string, required
- `Mcp-Method` string, required
- `Mcp-Name` string

## Request body

- MCPJSONRPCRequest — A JSON-RPC 2.0 request sent to `POST /mcp`, MCP protocol version `2026-07-28`. A message without `id` is a notification; this protocol version defines none over HTTP, so the gateway acknowledges it with `202` and ignores it. `params` and the corresponding `result` follow the vendored MCP spec types in `mcp/mcp-schema.yaml`. Every request's `params._meta` is a `RequestMetaObject` (`io.modelcontextprotocol/protocolVersion`, `io.modelcontextprotocol/clientInfo`, `io.modelcontextprotocol/clientCapabilities`); `server/discover` takes nothing else, `tools/list` takes an optional `cursor` and `tools/call` takes `CallToolRequestParams`. Tool names are namespaced `mcp_<server alias>_<tool name>`, e.g. `mcp_deepwiki_ask_question`. The alias comes from the `alias=url` syntax in `MCP_SERVERS` and is derived from the URL host when omitted; it must match `^[a-z0-9_-]+$` so the resulting tool name stays valid across all LLM providers. The same namespacing applies to the tools injected into `/v1/chat/completions`. `mcp_tools_get` and `mcp_tools_execute` are reserved for the gateway's own selector meta-tools and cannot be used by a configured server.
  - `jsonrpc` '2.0', required — JSON-RPC protocol version, always "2.0"
  - `id` union — Request identifier echoed back in the response. Absent for notifications.
    - string
    - integer
  - `method` 'server/discover' | 'tools/list' | 'tools/call', required — The MCP method to invoke
  - `params` object — Method parameters, as defined by the MCP specification

## Response `200`

JSON-RPC response envelope, carrying either a `result` or an `error`.

- MCPJSONRPCResponse — A JSON-RPC 2.0 response envelope. Exactly one of `result` or `error` is present. `result` carries the MCP result type for the requested method (`DiscoverResult` for `server/discover`, `ListToolsResult` for `tools/list`, `CallToolResult` for `tools/call`) as defined in `mcp/mcp-schema.yaml`.
  - `jsonrpc` '2.0', required — JSON-RPC protocol version, always "2.0"
  - `id` union, required — The `id` of the request this responds to
    - string
    - integer
  - `result` object — The method result, present on success
  - `error` MCPJSONRPCError — A JSON-RPC 2.0 error object
    - `code` integer, required — JSON-RPC error code: `-32700` parse error, `-32600` invalid request, `-32601` method not found, `-32602` invalid params, `-32603` internal error (including upstream MCP server failures), `-32020` header mismatch, `-32022` unsupported protocol version (`data` carries `requested` and `supported`).
    - `message` string, required — Short description of the error
    - `data` unknown

## Other responses

- `202` — Notification accepted; no response body
- `400` — Header mismatch (`-32020`) or unsupported protocol version (`-32022`), as a JSON-RPC error envelope.
- `401` — Unauthorized
- `403` — The MCP surface is not exposed. Both `MCP_ENABLED=true` and `MCP_EXPOSE=true` are required.
- `404` — Method not found (`-32601`), as a JSON-RPC error envelope.
- `500` — Internal server error

## Changes

- **2026-09-24** `a31ede1097b1` — 4 breaking, 4 info
  - added the new required `header` request parameter `MCP-Protocol-Version`
  - added the new required `header` request parameter `Mcp-Method`
  - removed the enum value `initialize` of the request property `method`
  - removed the enum value `notifications/initialized` of the request property `method`
  - …4 more
- **2026-09-24** `b12d4368f3a8` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/inference-gateway/apis/inference-gateway-api/changes/mcp/post.md)

---

[API](https://skmtc.dev/inference-gateway/apis/inference-gateway-api.md) · [All operations](https://skmtc.dev/inference-gateway/apis/inference-gateway-api/llms.txt) · [OpenAPI document](https://skmtc.dev/inference-gateway/apis/inference-gateway-api/revisions/a31ede1097b1?raw)
