Design a multi-tenant remote MCP server that exposes each customer's Postgres database. Walk through transport, auth, isolation, and observability.
Design a multi-tenant remote MCP server that exposes each customer's Postgres database. Walk through transport, auth, isolation, and observability.
Streamable HTTP, OAuth 2.1 with tenant_id claim, per-tenant DB credentials and async contexts, token-bucket rate limits per (tenant, tool), OTEL spans tagged per tenant. MCP provides none of this.
Imagine a building where many companies share one management office. Each company has its own locked room with its own key, its own water meter, and its own usage cap. The front desk checks every visitor's badge before letting them in, writes their name on a log with the company they belong to, and only lets them visit their own room. If one company starts running loud equipment that slows the elevator for everyone, the building manager notices because each floor has its own speed meter. Some situations force a remodel: one company wants a custom lobby sign that confuses the directory, another company's government says their mail must stay in a different building, and sometimes a visitor's task takes so long the front desk forgets they came in. A multi-tenant MCP server is the same building with code in place of doors and meters.
Detailed answer & concept explanation~9 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
Open by framing that MCP provides a wire protocol and discovery model, not safety. Walk six layers in order: streamable HTTP transport (why stdio fails), OAuth 2.1 with PKCE and tenant claim (why bearer alone fails), per-tenant Postgres credentials with connection pool and bounded async context (why shared superuser fails), token-bucket per (tenant, tool) returning JSON-RPC -32000 plus retry_after, two separate OTEL spans tagged tenant_id on the handler and Postgres call. Name three redesign-forcing failure modes: dynamic per-tenant tools defeating client cache, regional residency, long-running tool timeouts. Close with tool-definition hash for rug-pull defense and prompt injection fencing.
Real products, models, and research that use this idea.
- Cloudflare Workers MCP runs remote servers at the edge with OAuth 2.1 auth and per-tenant isolation enforced by the Workers runtime, serving as the reference architecture for streamable HTTP deployment in 2026.
- Vercel's MCP integration ships OAuth 2.1 with PKCE as the default for human users and bearer tokens for server to server, matching the spec's resource-server design.
- Anthropic's hosted MCP connectors enforce per-tenant rate limits and publish the JSON-RPC error -32000 plus retry_after convention for rejection responses.
- Smithery tracks tool-definition hashes per server to detect post-approval mutations, addressing the rug-pull gap the protocol leaves to implementers.
- Production remote MCP servers in 2026 commonly use FastAPI plus the Python `mcp` SDK or Node frameworks plus the `@modelcontextprotocol/sdk` TypeScript package.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow would you handle a tenant that needs custom tool descriptions when most MCP clients aggressively cache tools/list?
QWalk through what happens when a tenant runs a 5 minute analytical query and the host's silent timeout is 2 minutes.
QTenant A says tenant B's queries are slowing their requests. What spans and metrics do you pull first?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Sharing a single Postgres superuser across tenants and scoping with SET ROLE at runtime. One SQL injection in any tool reads every tenant's data, collapsing the isolation model entirely.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.