Implementing an MCP Server From Scratch — Five Things the Guide Skips

The MCP server *official guide* gets you to PoC. The *production deployment* that follows hits five things the guide doesn't cover — JSON-RPC translation, per-tool authorization, error semantics, lifecycle, isolation.

John Baek
John Baek
Founder, CollabOps
Implementing an MCP Server From Scratch — Five Things the Guide Skips

If you've implemented an MCP server, the official guide takes you through tool definitions → server boot → connection verification. After that, the path to production hits five things the guide doesn't cover.

This post is the field notes for those five.

1 — The JSON-RPC translation traps

MCP runs on JSON-RPC 2.0. The guide assumes you're using JSON-RPC. Our internal RPC was gRPC. We needed a translation layer, and the details of that layer matter.

Most-frequent breakage:

  • Streaming responses — JSON-RPC assumes single response. MCP fakes streaming via progress notifications. Doesn't map cleanly to gRPC streaming
  • Cancellation — client cancel must stop progress + clean up. JSON-RPC has no native cancel — needs a separate cancel notification
  • Binary data — JSON requires base64. Large binaries (images, files) should ride separate transport

2 — Authorization branches at the tool level, not the server

The guide assumes a server exposes all tools to all clients. In practice, one server exposes partial tools to clients with different permissions.

Fix: per-call evaluation of (client, tool, args). Our graph permission model applies directly. → Permission model on a graph

Receive call →
  Verify client identity →
  Is the tool call within client's permission? →
  Are the args within client's scope? →
  Execute

Without this branching inside the server, every call shares one permission — security risk.

3 — Error semantics — JSON-RPC codes + MCP meaning

JSON-RPC standard error codes (-32600 to -32099) + additional MCP-defined errors + your domain errors.

Trap — JSON-RPC errors are standard, but MCP-domain errors have ambiguous representation.

Our answer:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,                          // JSON-RPC server-defined error
    "message": "Authorization failed",
    "data": {
      "type": "mcp.authorization.denied",     // our semantic
      "tool": "deploy.production",
      "reason": "missing scope: prod.deploy",
      "audit_id": "audit-xyz"                 // for audit trail
    }
  }
}

Domain-error meaning sits in data. Clients use it to show the user a precise message.

4 — Server lifecycle

The guide says initialize → use → terminate. In practice, connections drop and reconnect frequently. Clients assume state survives; servers assume stateless. Conflict.

Fix: separate session store on the server. On client reconnect, restore by session ID. The session holds current tool permissions / in-progress work / context cache.

Default session expiry — 30-minute idle. Infinite while active.

5 — Isolation — one client doesn't affect another

Multiple clients use one server concurrently. While one is in a long-running tool call, others' fast calls must not block.

The guide doesn't address concurrency.

Our answer:

  • Separate worker pools per client
  • A client's long call only blocks that client's next call
  • Global resources (DB connection, external API) get separate rate limits

Without this isolation, one user's heavy request escalates into total service degradation.

What we learned from the five

An MCP server that doesn't address all five runs fine in PoC, then incidents hit 1–3 months into production. The pattern is what we saw — permission leaks, error illegibility, lost sessions, broken isolation.

The MCP server official guide is a get-started guide, not a production guide.

Before you go to production

If you're implementing an MCP server or building MCP-based agent infrastructure, hard-coding explicit answers to even two or three of the five questions above avoids 3–6 months of rework later. Running fine in PoC proves nothing — the incidents arrive 1–3 months into production.

Tags#mcp#ai-agent#protocol#implementation#devops