MCP Architecture Guide

How to design, deploy and test an MCP server: primitives, Streamable HTTP, the two protocol eras, domain-scoped servers and a 20-point acceptance test matrix.

Type
Resource
Topic
MCP
Reading time
6 min
Updated
Author
GeekMidst Team
Reviewed by
Site owner
Talk to an expert
Banner for the GeekMidst free resource “MCP Architecture Guide”, covering The building blocks and Transports

This guide covers the decisions that shape an MCP server before and after the first tool works: which primitives to use, which transport and protocol versions to support, how to split servers, how to deploy and version them, and what to test before anyone relies on them. Protocol details come from the MCP specification as of October 2026. The diagram below is a reference design; we validate the APIs, permissions and identity set-up for each implementation.

The building blocks

MCP is an open protocol based on JSON-RPC 2.0. It is not a model and not an LLM API: it only standardises how AI applications get context and actions from external programs.

  • Host: the AI application, such as a chat app, IDE or agent platform.
  • Client: created by the host, one per server, each with a dedicated connection.
  • Server: a program that exposes three primitives.
  • Tools: functions the model can call, each with an inputSchema (JSON Schema, 2020-12 dialect by default).
  • Resources: data addressed by URIs, read with resources/read. Custom URI schemes are allowed if they follow RFC 3986.
  • Prompts: reusable templates that the user chooses.

Clients can offer elicitation. Sampling, roots and logging are deprecated in 2026-07-28, so avoid designing around them. For a diagram of the roles, see the MCP host, client and server architecture.

Transports

A server runs locally over stdio or remotely over Streamable HTTP. For remote servers:

  • The server exposes a single endpoint path, such as /mcp.
  • Every client message is a new HTTP POST, and the client's Accept header lists both application/json and text/event-stream.
  • The server may answer a request with plain JSON or with an SSE stream. Clients must support both, so a simple server may always answer with plain JSON.
  • Accepted notifications get 202 Accepted with no body.
  • The server must validate Origin and answer 403 when it is present and invalid, to block DNS rebinding.
  • JSON-RPC batching was removed in 2025-06-18: one message per POST.

Two protocol eras

The spec calls revisions up to 2025-11-25 "legacy"; the current revision is 2026-07-28.

Legacy and 2026-07-28 compared

TopicLegacy (2025-11-25 and earlier)2026-07-28
Start-upinitialize, then notifications/initializedNo handshake; mandatory server/discover
StateOptional MCP-Session-Id sessionsNo protocol sessions; list results must not vary per connection
Per-request dataMCP-Protocol-Version header after initialisation_meta with protocol version and client capabilities on every request, plus Mcp-Method and Mcp-Name headers
CachingNo cache fields in list resultsttlMs and cacheScope on list and read results
LivenesspingRemoved
Resource not found-32002-32602

Which era to target is a judgement, not something the spec states. The TypeScript SDK v2 client and the MCP Inspector default to the legacy handshake, while the Python client probes server/discover first and falls back. Supporting both eras on one endpoint is allowed: an initialize request selects legacy behaviour, and requests carrying _meta are served statelessly. That is what we did on the GeekMidst MCP server.

Server design

  • One server per domain. Separate adapters for, say, knowledge, CRM records and marketing operations, so each has its own permission review, credentials and kill switch.
  • Business logic separate from transport. Tool handlers call plain functions that you can unit test without an AI client. The JSON-RPC layer only parses, validates, dispatches and formats.
  • Narrow tools with strict schemas. Name operations after business tasks, reject unknown fields with additionalProperties: false, and set limits on strings and page sizes. Never offer unrestricted SQL or database credentials.
  • Use the two error channels correctly. An unknown tool is a protocol error (-32602). Validation, API and business failures are tool results with isError: true and a message the model can act on.
  • Honest annotations. Set readOnlyHint: true on read tools. Remember defaults: readOnlyHint is false and destructiveHint is true, and clients must treat annotations as untrusted hints.
  • Structured output. When you return structuredContent, also return the serialised JSON in a text block for older clients.

Reference MCP deployment: knowledge and action servers

Reference architecture: a reusable pattern, not a live client integration

User's device and AI hostHOST APPLICATIONMCP CLIENTSEDGE AND IDENTITYMCP SERVERSUPSTREAM SYSTEMSUserAI hostchat app, IDE or agentMCP client: knowledgeMCP client: actionsHTTP edgeTLS, origin check, rate limitBAuthorization serverOAuth 2.1 with PKCECKnowledge serverread-only tools and resourcesBActions servernarrow tools, OAuth resource serverBApproved content storeCBusiness system APIone domain per serverCAudit log and metricsBquestion or promptconfirm actiontool and resource callsconfirmed tool callsOAuth 2.1 + PKCEStreamable HTTP POSTPOST with bearer tokenvalidated requestvalidated requestread approved contentscoped API callaudit eventrequest log
  • Data and analytics
  • AI and agents
  • Integration layer
  • Identity, policy and governance
  • External or custom system
  • People
  • User's device and AI host
  • BYour MCP deployment
  • CIdentity and systems of record
  • Dashed: asynchronous, optional or feedback
Diagram source (Mermaid)

Select a component to see what it is responsible for and how data moves to and from it.

Reference design. Servers, identity provider and upstream APIs are chosen and validated per implementation.
Components and data flows (text version)
ComponentTypeResponsibility
UserPeopleAsks questions, chooses prompts and confirms any action that would change data.
AI hostchat app, IDE or agentAI and agentsThe AI application. It runs the model, creates one MCP client per server and decides when to ask the user before a tool runs.
MCP client: knowledgeAI and agentsKeeps a dedicated connection to the knowledge server, discovers its tools and resources and sends requests.
MCP client: actionsAI and agentsConnects to the actions server. Obtains an OAuth access token for the signed-in user and sends it on every request.
HTTP edgeTLS, origin check, rate limitIdentity, policy and governanceTerminates TLS, rejects invalid Origin headers with 403, applies rate limits and request size limits before the server code runs.
Authorization serverOAuth 2.1 with PKCEIdentity, policy and governanceYour identity provider. Issues short-lived tokens whose audience is the MCP server, with the minimum scopes for the user's role.
Knowledge serverread-only tools and resourcesIntegration layerSearches and returns approved documentation as cited passages and URI-addressed resources. Has no write path.
Actions servernarrow tools, OAuth resource serverIntegration layerValidates each token's audience and scope, validates input against the tool schema, then calls one domain API. Write tools are few and named.
Approved content storeData and analyticsPublished documentation, policies or product knowledge that has been cleared for assistant use.
Business system APIone domain per serverExternal or custom systemThe system of record. Its own permissions, limits and validation still apply to every call.
Audit log and metricsData and analyticsRecords caller, tool, outcome and timing for every call. Sensitive arguments are excluded or masked by default.

Data flows

  1. User → AI host: question or prompt. The user asks a question or picks a server prompt. Prompts are user-chosen templates, not instructions the server can inject.
  2. AI host → User: confirm action. Before a write tool runs, the host shows the call and its arguments. If the user declines, nothing is sent.
  3. AI host → MCP client: knowledge: tool and resource calls. The model chooses tools from the discovered list; the host routes the call to the right client.
  4. AI host → MCP client: actions: confirmed tool calls. Only calls the host is allowed to make, after any confirmation, reach the actions client.
  5. MCP client: actions → Authorization server: OAuth 2.1 + PKCE. Authorisation code flow with PKCE and the resource parameter naming the MCP server. On failure the user is asked to sign in again.
  6. MCP client: knowledge → HTTP edge: Streamable HTTP POST. One JSON-RPC message per POST. Rejected requests get a 4xx and the client surfaces the error.
  7. MCP client: actions → HTTP edge: POST with bearer token. The token travels in the Authorization header on every request, never in the URL. Missing or expired tokens get 401.
  8. HTTP edge → Knowledge server: validated request. Requests that pass origin, size and rate checks are forwarded. Over the limit, the edge answers 429.
  9. HTTP edge → Actions server: validated request. Same checks, plus routing to the server that owns the domain.
  10. Knowledge server → Approved content store: read approved content. Read-only queries against the content index. If the index is down, the tool returns isError with a clear message.
  11. Actions server → Business system API: scoped API call. Uses the server's own credentials or a token issued for the upstream API, never the client's MCP token. Timeouts return a tool error.
  12. Actions server → Audit log and metrics: audit event. Every call writes who, what, outcome and timing. If audit writing fails, write tools should fail closed.
  13. Knowledge server → Audit log and metrics: request log. Anonymous or pseudonymous request metrics for capacity and abuse detection.

Deployment

  • Stateless where possible. Without sessions, any instance can answer any request, which suits load balancers and serverless hosting.
  • Secrets stay server side. Upstream API credentials live in the server's secret store, never in tool arguments, prompts or responses.
  • Sandbox first. Point new servers at sandbox or test environments, with test users whose permissions match real roles.
  • Protect with OAuth when data is not public. The server becomes an OAuth 2.1 resource server and publishes RFC 9728 protected resource metadata. The detail is in MCP security and governance and MCP security and authorisation.

Versioning

Three versions move independently: the protocol revision, the SDK, and your tool contract. Pin SDK versions and read their changelogs before upgrading. Treat a tool's name and input schema as a public API: add optional fields freely, but publish a new tool name for breaking changes and keep the old one for a stated period. The spec keeps deprecated features for at least 12 months, which is a sensible model for your own tools.

Testing matrix

These 20 acceptance tests should pass in every environment before go-live, and again after each SDK or protocol upgrade.

MCP server acceptance tests

TestWhat to check
Startup and healthThe server starts cleanly and a basic request succeeds through the real HTTP path
Version compatibilitySupported versions are negotiated; unsupported ones are rejected with the documented error
Capability discoveryinitialize and server/discover report only capabilities that work
Tool discoverytools/list returns every tool with a valid schema, in a stable order
Resource accessListing, templates and reads work; a missing resource returns an error, never empty contents
Prompt discoveryPrompts list and render; a missing required argument returns -32602
Input validationWrong types, unknown fields and oversized values are rejected as tool errors
AuthenticationNo token, an expired token or a token for another audience gets 401
AuthorisationA valid token without the needed scope gets 403 with insufficient_scope
Tool executionEach tool returns correct results for known test data
Read-only boundariesRead tools cannot change data, whatever arguments are sent
Human confirmationWrite tools run only after the host's confirmation step
Error handlingUpstream failures become clear tool errors without stack traces
Rate limitingExcess requests are slowed or refused without affecting other users
Audit loggingEvery call produces an audit record with caller, tool and outcome
Timeouts and retriesSlow upstreams time out; retries do not duplicate writes
Upstream unavailableThe server stays up and reports the outage clearly
Secret protectionNo credentials appear in responses, logs or error messages
Cross-user isolationOne user's token never returns another user's data
Client compatibilityThe SDK clients, MCP Inspector and your target hosts connect and call tools

MCP Inspector 2.12.0 has a CLI mode that makes many of these tests scriptable, for example npx @modelcontextprotocol/inspector --cli https://example.com/mcp --method tools/list, with --protocol-era legacy|auto|modern to test each era.

Questions we hear

Should we build for 2026-07-28 only?
Not yet for most servers. The official TypeScript SDK client and the MCP Inspector default to the legacy handshake, so a dual-era server is the safer baseline.
Do we need SSE?
No. Clients must accept plain JSON responses, so a server without long-running streams can skip SSE.
How many tools should one server have?
Enough for one domain and one permission review. If a tool needs very different rights, it probably belongs in another server.
Where do vendor servers fit?
Use them where they fit and register them alongside your own. See MCP integrations.

Sources

  • https://modelcontextprotocol.io/docs/learn/architecture
  • https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http
  • https://modelcontextprotocol.io/specification/2026-07-28/changelog
  • https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning
  • https://modelcontextprotocol.io/specification/2026-07-28/server/tools
  • https://www.npmjs.com/package/@modelcontextprotocol/inspector

Review your MCP design

Send us your planned tools and deployment. We will check them against this matrix and suggest changes.

Book a consultation →

Tell us what you are trying to fix.

Share your Salesforce setup, goals and constraints. A practitioner reads every message and replies with questions, first thoughts or an honest view of whether you need outside help at all.

Talk to a Salesforce Expert
Book a Consultation