A developer should build an MCP server as a focused, independently authorized capability boundary behind an MCP host and its per-server client. For revision 2026-07-28, implement stateless JSON-RPC exchanges in which each request carries its protocol version and client capabilities, advertise only supported server capabilities, expose tools, resources, and prompts according to their different interaction models, and choose either stdio or Streamable HTTP as the standard transport. Validate every request and result, minimize the context visible to the server, authorize the caller and resource on every operation, preserve user consent for consequential tools, and treat older session-oriented protocol behavior only as an explicit compatibility path.
Choose MCP only when the capability needs a protocol and deployment boundary that can be reused across compatible hosts or applications. Prefer an existing built-in tool for a supported platform capability, a direct custom tool for one application-owned execution loop, a Skill for reusable instructions and procedure, and a Claude Code plugin when several reviewed Claude Code extensions should ship together. MCP offers the strongest cross-host portability, but it also creates a service contract, transport, authorization surface, compatibility obligation, and operational lifecycle that simpler customization options do not require.
Architecture Overview: Host, Client, and Server
The current MCP 2026-07-28 architecture defines three distinct roles.
- MCP host: the application that coordinates the AI experience. It creates and manages clients, controls connection permissions and lifecycle, owns user authorization decisions, applies security and consent policy, and decides how context from multiple servers is aggregated.
- MCP client: a host-managed protocol component with a one-to-one relationship to one server. It attaches the protocol version and client capabilities to requests, routes messages, handles subscriptions and notifications, and preserves isolation from other servers.
- MCP server: a focused local process or remote service that exposes capabilities such as tools, resources, and prompts. It receives only the context required for its operation and must not assume access to the host's complete conversation or another server's state.
This separation is a security property as well as an integration pattern. A server should not become an informal back channel among unrelated applications, users, tenants, or other MCP servers. The host decides what is connected and surfaced; the client implements one protocol relationship; the server proves access for each operation and returns only the result the host needs.
Use the Current Stateless Protocol Model
Revision 2026-07-28 is a stateless protocol built on JSON-RPC. Each request is self-contained and carries required _meta fields for the protocol version, client identity information, and client capabilities. A client can call server/discover before other work to learn advertised server capabilities, and both sides must respect those declarations for the request.
Do not design a new 2026-07-28 implementation around a connection-scoped initialize session. The initialization handshake, protocol-level session state, and server-initiated JSON-RPC requests belong to earlier revisions and are relevant only when a client or server deliberately implements backward compatibility. If an operation needs durable state, represent it explicitly in the application or server and pass an opaque, authorized handle between requests rather than relying on implicit connection state.
Preserve JSON-RPC message responsibilities
MCP uses UTF-8 JSON-RPC messages. Under the current message pattern, clients send requests and notifications; servers return responses and notifications. A server does not initiate an independent JSON-RPC request. When it needs client-side input such as elicitation, sampling, or roots during an operation, that interaction is represented through the current input-required result and retry flow rather than an unsolicited server request.
Keep transport framing separate from protocol meaning. Request identifiers correlate JSON-RPC responses, but they do not establish user identity, authorization, idempotency, or business ownership. Validate the method, parameters, required metadata, supported protocol revision, advertised capability, and caller authorization independently.
Negotiate Only the Capabilities You Implement
Capability negotiation lets clients and servers evolve without pretending every feature is universal. The client declares supported features on every request. The server advertises capabilities such as tools, resources, prompt templates, subscriptions, or list-change behavior through discovery.
A robust server should:
- implement only capabilities it can support correctly for the selected revision;
- advertise those capabilities precisely;
- reject unsupported protocol versions, methods, or required client capabilities with the current defined error behavior;
- return only entities the request's authorization permits;
- keep discovery results stable and deterministically ordered when the underlying set has not changed; and
- emit change notifications only when the relevant capability and subscription path are active.
Do not treat discovery as authorization. Knowing that a server can expose tools does not prove that this caller may list or invoke every tool. Current tool and resource sets may vary by per-request authorization, and the server must re-evaluate that authorization on the operation itself.
Model Tools, Resources, and Prompts Deliberately
MCP's three primary server features differ in who controls their use. Mixing those interaction models makes consent and context behavior difficult to understand.
Tools are model-controlled capabilities
An MCP tool has a unique name, description, input JSON Schema, and optional output schema and annotations. A capable client discovers tools with tools/list and invokes one with tools/call. Tools are designed for model-controlled selection, but the host can choose how to expose them and should keep a human able to deny consequential invocations.
The server must validate inputs, enforce access control, rate-limit operations, and sanitize outputs. The client should show sensitive tool inputs before invocation, validate results, apply timeouts, log appropriate audit evidence, and obtain confirmation where required. Treat annotations as untrusted unless the server itself is trusted. Schema conformance describes shape; it does not grant authority.
Detailed design of descriptions, approval binding, idempotency, application dispatch, and safe result handling is the prerequisite procedure in Implementing Claude Tools with Safe Execution and Approval Patterns. MCP adds a protocol boundary but does not weaken those tool semantics.
Resources are application-driven context
An MCP resource exposes contextual data through a URI. The host application decides how users search, select, or automatically include resources; the protocol does not require one interface. Servers can provide resource listings, reads, templates, and supported update notifications.
Validate every requested URI, apply authorization before listing and reading, sanitize file paths, encode binary content correctly, and return a defined error rather than an ambiguous empty result for a missing resource. A file:// identifier does not require a physical local file, but it does require filesystem-like semantics and must never become a directory-traversal shortcut. Resource annotations help a client rank or display content; they are hints, not permission decisions.
Prompts are user-controlled templates
An MCP prompt is a reusable template that the client lists and the user chooses and completes. The current MCP Python SDK prompt documentation illustrates how a server registers prompt functions, names arguments, returns one or more messages, and notifies compatible clients when the prompt list changes.
A prompt distributes reusable interaction content; it does not execute a privileged operation or enforce organization policy. Validate prompt arguments, avoid embedding secrets, label any external material, and let the host show the generated content before it becomes model context when the risk warrants review.
Preserve the interaction-control distinction
Use tools for model-selectable actions, resources for application-selected context, and prompts for user-selected templates. The same business domain may expose more than one primitive—a resource for a customer record, a prompt for a reviewed analysis workflow, and a tool for an authorized update—but each must retain its own identity, authorization, and user-control boundary.
Choose a Standard Transport
The current MCP transport overview defines two standard bindings: stdio and Streamable HTTP. Protocol semantics remain the same across them; the transport defines message framing, delivery, metadata mirroring, cancellation, and termination.
Use stdio for a host-launched local process
With stdio, the client launches the MCP server as a subprocess and exchanges newline-delimited messages over standard input and output. This is a good fit for local integrations where the host owns process lifecycle and the capability should remain on the same machine.
Keep standard output reserved for protocol messages, send diagnostics to the appropriate logging channel, constrain the child process's environment, working directory, credentials, filesystem access, and network reach, and validate the exact executable and arguments before launch. The MCP HTTP authorization flow does not apply to stdio; the current authorization specification says stdio implementations should retrieve credentials from the environment. That makes the host's process and secret-delivery boundary especially important.
Use Streamable HTTP for a remote service boundary
Streamable HTTP sends each JSON-RPC message as an HTTP POST to one MCP endpoint. The response is either a JSON object or an SSE stream scoped to that request; long-lived change notifications use the current subscription response stream. SSE here is a response mechanism inside Streamable HTTP, not a separate current “SSE transport.” The deprecated HTTP+SSE binding from 2024-11-05 is compatibility history and should not be selected for a new implementation.
For a Streamable HTTP deployment, validate the Origin header to prevent DNS rebinding, bind local-only servers to localhost, authenticate connections, use protected network transport, and configure gateways and reverse proxies so they do not weaken header/body validation or authorization. Each request must carry the current protocol metadata; do not rely on a protocol session identifier that revision 2026-07-28 does not define.
Treat sockets as custom transports
A Unix-domain socket, raw TCP socket, WebSocket design, message queue, or other channel can carry MCP only as a custom transport. It is not one of the two current standard bindings. A custom transport must preserve JSON-RPC, current message directions, per-request metadata, cancellation, framing, and termination semantics. For reliable bidirectional byte streams such as Unix-domain sockets or TCP, the specification recommends reusing stdio's newline-delimited framing rather than inventing another wire format.
Choose a custom transport only when a documented deployment constraint outweighs the lost default interoperability. Define connection establishment, authentication, framing, cancellation, timeouts, backpressure, failure recovery, and compatibility tests explicitly.
Authorize the Remote Boundary and Every Operation
The current MCP authorization specification defines an optional authorization flow for HTTP-based transports. When implemented, it uses OAuth 2.1-related standards: the MCP server acts as a resource server, the MCP client acts on behalf of a resource owner, and an authorization server issues tokens for that MCP server.
Authorization architecture must preserve these boundaries:
- request only the scopes required for the current capability and use step-up authorization deliberately;
- bind access tokens to the intended MCP server audience;
- send bearer tokens in the Authorization header, never in the URI query string;
- validate token issuer, audience, expiry, and scopes on every protected request;
- never accept or pass through a token issued for another service;
- separate transport authentication from business authorization for tenant, resource, operation, and arguments; and
- return authorization errors without leaking protected resource details.
Origin validation is not authentication, and a valid access token does not approve a consequential action. The host still owns user consent, the server still owns operation-level authorization, and tool execution still needs the validation, approval, audit, and safe-failure controls established in the prerequisite article.
Design Deployment and Operational Boundaries
An MCP server is an independently maintained dependency. Define its owner, supported protocol revisions, capability contract, data classification, authentication mode, authorization policy, deployment environment, logging policy, retention, availability target, and deprecation path.
For each exposed capability:
- minimize the data accepted and returned;
- distinguish protocol errors from tool or business errors;
- use stable schemas and version deliberate breaking changes;
- cap request size, concurrency, execution time, and result size;
- prevent cross-tenant caching or state reuse;
- store explicit state under opaque handles only when necessary and reauthorize every use;
- observe calls without copying secrets or sensitive payloads into logs; and
- test unsupported versions, missing capabilities, denied scopes, malformed URIs, invalid schemas, cancellation, timeout, and partial dependency failure.
The host should inventory connected servers and show users which capabilities are exposed. Treat server updates as supply-chain and compatibility changes, especially when a plugin installs or configures the server automatically. Application-wide secret, monitoring, sandboxing, and incident-response architecture remains in Securing Claude Applications with Guardrails, Hooks, and Secret Management.
Choose the Smallest Customization Boundary
The correct extension is the smallest one that satisfies the required reuse, portability, execution, security, and maintenance boundary.
| Option | Best fit | Reuse and portability | Execution and security boundary | Maintenance cost |
|---|---|---|---|---|
| Built-in tool | A current platform or host capability already matches the task | Reusable within the surfaces that support that exact tool and version | Execution location and controls follow the tool's documented runtime; application still governs exposure and data | Lowest custom code, but availability, versions, and policy must be rechecked |
| Direct custom tool | One Claude application needs a focused callable operation | Reusable inside that application's API or agent harness; limited cross-host portability | Application owns schema, dispatch, authorization, approval, execution, and results | Moderate; one integration contract and handler lifecycle |
| Skill | A repeatable procedure needs instructions, references, or scripts | Portable only across hosts that support the Skill format and required dependencies | Guides model or user behavior; it is not a network service, authorization layer, or automatic security boundary | Low to moderate; review instructions, resources, triggers, and dependencies |
| Claude Code plugin | A reviewed bundle of Claude Code extensions should be installed and versioned together | Reusable across compatible Claude Code environments | Package can include Skills, agents, hooks, MCP servers, and configuration; each component keeps its own execution and trust boundary | Moderate to high; supply-chain review, version pinning, component inventory, rollout, and rollback |
| MCP server | Multiple compatible hosts or applications need a separately deployed capability or context provider | Highest protocol-level portability when clients support the same revision and capabilities | Local or remote server boundary with discovery, transport, per-request authorization, validation, consent, and operations | Highest; protocol compatibility, hosting, credentials, observability, upgrades, and incident response |
Use a built-in tool before duplicating a supported capability. Use a direct custom tool when the application already owns execution and no cross-host protocol is needed. Use a Skill when the reusable asset is knowledge and procedure rather than a service. Use a plugin when the unit of distribution is a reviewed Claude Code extension bundle. Use MCP when an independently governed tool, resource, or prompt service must interoperate across compatible hosts.
These options can compose. A plugin may install an MCP server, and a Skill may describe when to use a direct or MCP tool. Composition does not merge their security boundaries: the Skill remains guidance, the plugin remains a package dependency, the MCP server remains a protocol service, and the tool remains an operation requiring authorization.
Common MCP Architecture Mistakes
- Implementing the old initialization session as the current protocol. Revision 2026-07-28 carries version and capabilities per request; legacy initialization exists only for deliberate compatibility.
- Calling SSE a current standalone transport. Current standard bindings are stdio and Streamable HTTP; SSE is used within Streamable HTTP response streams.
- Calling any socket connection standard MCP. Unix-domain sockets, TCP, WebSocket, and other channels are custom transports that must preserve current protocol semantics.
- Letting a server see the complete conversation. The host should provide only the context required for that server's focused capability.
- Treating capability discovery as permission. Advertised support does not authorize a caller, tenant, resource, argument, or side effect.
- Using the same interaction model for every primitive. Tools are model-controlled, resources application-driven, and prompts user-controlled.
- Passing upstream tokens through to downstream systems. Validate audience and accept only tokens issued for the MCP server.
- Using a schema as access control. Validate inputs, then apply identity, scope, resource, approval, and business policy.
- Choosing MCP for a local prompt recipe. A Skill or direct tool may meet the requirement without creating a service lifecycle.
- Assuming a plugin makes bundled components trusted. Inventory and govern every installed Skill, hook, agent, configuration change, and MCP server.
Relevance to Claude Certified Developer – Foundations
The Claude Certified Developer – Foundations Exam Guide includes MCP server development, tools, resources, prompts, transports, authorization, deployment, and choices among Tools, Skills, plugins, and MCP within its public developer scope.
The durable skill is identifying the boundary before choosing the mechanism. Direct tools keep execution inside one application; Skills package reusable procedure; plugins distribute Claude Code extension bundles; MCP creates an interoperable client-server contract. A secure MCP design then preserves host control, one-client-to-one-server isolation, per-request capabilities, explicit transport behavior, least-privilege authorization, and meaningful user control.
Conclusion
Build an MCP 2026-07-28 server as a focused, stateless, independently authorized service. Keep the host responsible for aggregation and consent, each client isolated to one server, and the server limited to declared tools, resources, and prompts. Carry version and capability metadata on every request, preserve current JSON-RPC directions, and choose stdio or Streamable HTTP unless a documented requirement justifies a fully specified custom transport.
Choose MCP only when cross-host reuse and an independent service boundary justify its operational cost. Otherwise use the supported built-in tool, direct custom tool, Skill, or Claude Code plugin that owns the requirement more simply. Portability is valuable only when authorization, compatibility, deployment, and maintenance remain explicit.
Authoritative Sources
- MCP architecture
- MCP transport overview
- MCP tools
- MCP resources
- Prompts in the MCP Python SDK
- MCP authorization
- Claude Certified Developer – Foundations Exam Guide

