Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

What is ContextForge Gateway?

Welcome to the ContextForge Gateway book.

contextforge-gateway-rs is the Rust dataplane for ContextForge: a single MCP entry point that sits in front of many backend MCP servers and makes them look like one. If you have used an API gateway or reverse proxy for HTTP APIs, this is the same idea for the Model Context Protocol (MCP).

Concretely, the gateway accepts MCP streamable HTTP traffic from a client, authenticates the caller, loads that caller’s runtime configuration, opens MCP client sessions to the backend MCP servers that configuration allows, and presents those backends to the client as one merged MCP server.

Throughout this book, downstream means the client side of the gateway and upstream means the backend side.

Gateway overview

Blue arrows show request traffic. Green arrows show backend responses returning to the gateway and the merged MCP response going back to the client.

LayerWhat happens
Client edgeAn MCP client calls /contextforge-rs/servers/{virtual_host_id}/mcp with a bearer token and MCP session headers.
Gateway hot pathThe gateway validates identity, loads runtime config, selects the virtual host, and routes MCP methods.
Backend edgeThe gateway opens or reuses MCP client sessions to configured backend MCP servers and merges what the client sees.

Key idea: downstream clients interact with one logical MCP server. The gateway decides which configured backend sessions are involved.

The gateway is not the management application. It does not own the UI, IAM lifecycle, tenant administration, durable metrics storage, or long-lived configuration editing. Those concerns stay in the external ContextForge control plane. This repository owns the hot request path and the runtime pieces needed to make that path fast, observable, and enforceable.

Most operators should not think about backend MCP servers directly. They should think about one client-facing MCP endpoint:

/contextforge-rs/servers/{virtual_host_id}/mcp

Behind that endpoint, the gateway has three main boundaries:

  • the downstream boundary, where clients connect over streamable HTTP and present their bearer token and MCP session id
  • the configuration boundary, where the gateway turns the JWT subject into a runtime UserConfig
  • the upstream boundary, where the gateway opens or reuses MCP client sessions to the configured backend servers

Most bugs in this service come from confusing those boundaries. A downstream request is not allowed to pick arbitrary upstream backends. Redis is not the routing model; it is the current config-store transport. Backend sessions are not durable cluster state; they are local process state today.

BoundaryInputOutputOwner
DownstreamHTTP request, JWT, MCP headersrequest extensions and downstream session idgateway
ConfigurationJWT subject and virtual host idUserConfig and selected VirtualHostcontrol plane data, gateway enforcement
Upstreamselected backend names and URLsrunning backend MCP client servicesgateway

Key terms

These words appear on almost every page. It is worth pinning them down once.

TermMeaning in this book
DataplaneThe process on the live request path (this repository). It handles MCP traffic.
Control planeThe external ContextForge application that authors config, policy, and identity. It is not in this repository.
DownstreamThe client side of the gateway: the calling MCP client and its requests.
UpstreamThe backend side of the gateway: the configured backend MCP servers.
Virtual hostA named routing group inside the caller’s config. The URL path selects exactly one.
BackendOne configured MCP server behind the gateway. Its map key becomes a routing prefix when a virtual host has multiple backends.
PrincipalThe authenticated caller identity, taken from the JWT sub claim.
SessionAn initialized MCP session, tracked by Mcp-session-id, that owns the per-caller backend client sessions.

Mental model

The gateway is easiest to understand as one logical MCP server assembled from a set of configured backend MCP servers.

On initialize, the gateway validates the caller, resolves the requested virtual host, and creates upstream MCP client sessions for that virtual host’s backends. On list calls, it fans out to those backends and merges the result. On targeted calls, it uses an explicit tool alias, the only configured backend, or a multi-backend prefix to route to exactly one backend.

For a stateful MCP call to work, five facts must line up:

JWT subject
  -> user config
  -> virtual host id
  -> downstream MCP session id
  -> backend session map entries

If any part is missing, the gateway should fail at the layer that owns that fact: auth, config lookup, virtual host resolution, session lookup, routing, or upstream transport.

Operational consequence: stateful MCP traffic needs session affinity until backend session state moves out of the gateway process.

Non-goals

This repository should not grow control-plane behavior by accident. It should not become the admin UI, tenant management API, policy authoring system, credential store, or durable observability backend.

It also should not expose backend topology as more than the MCP routing contract requires. Backend map keys are visible when multi-backend identifiers need prefixes, but clients should still experience one gateway endpoint and one logical MCP server.

Where to go next