ChangeGamer

← All resources

Building an MCP Server

Guide · updated 2026-09-28 · Markdown variant

Implementation guide for MCP servers: architecture roles, the three server primitives, stdio vs Streamable HTTP transports, official SDKs, server lifecycle, remote-server concerns, testing with MCP Inspector, and publishing to the official registry.


The Model Context Protocol (MCP) gives a host application a uniform way to connect an AI model to external tools, data, and prompt templates. This guide covers what you need to implement a server — from wire format to deployment. For finding and evaluating existing servers see /resources/mcp-server-discovery; for OAuth 2.1 auth on remote servers see /resources/mcp-server-authentication.

Key facts

Architecture: host, client, server

Three roles exist in every MCP deployment:

All messages between client and server are JSON-RPC 2.0 objects: requests carry an id, method, and optional params; responses carry the same id plus result or error. Notifications are one-way (no id, no response expected).

The three server primitives

Tools are model-invoked functions. The client calls tools/list to discover them; the model selects and calls one via tools/call. Each tool has a name, description, and an inputSchema (JSON Schema). Results are returned as typed content blocks (text, image, audio, resource link). Use tools when the agent needs to do something — query an API, run a calculation, write to a database.

Resources are read-only data the client can subscribe to: files, database rows, live feeds. They are identified by URI. Use resources when the agent needs to read structured data that may change over time.

Prompts are named, parameterised prompt templates served by the server. The client fetches them via prompts/get and injects them into the conversation. Use prompts to share curated instruction fragments without embedding them in the client.

Transports: stdio and Streamable HTTP

The current MCP spec (stable revision: 2026-07-28 — the largest revision of the protocol since launch, superseding 2025-11-25; treat as a snapshot, verify at modelcontextprotocol.io. See /resources/mcp-2026-spec-revision for the full changelog) defines two standard transports.

stdio (local) — the host launches the server as a child process. JSON-RPC messages are exchanged over stdin/stdout, delimited by newlines. The server MUST NOT write anything to stdout except valid MCP messages; use stderr for logs. stdio carries zero network exposure and is the right choice for local tools running on the same machine.

Streamable HTTP (remote) — the server runs as an independent network process. All client messages are HTTP POST requests to a single MCP endpoint; the server may respond with application/json (single response) or text/event-stream (SSE stream for multi-message responses). As of the 2026-07-28 spec revision, the protocol-level Mcp-Session-Id header and the session it carried were removed entirely (SEP-2567/SEP-2575) — a server needing cross-call state now mints its own handle and has the model pass it back as an ordinary tool argument, so any request can land on any server instance without sticky routing. Requests instead carry dedicated Mcp-Method and Mcp-Name headers (SEP-2243) so gateways can route on the operation without inspecting the body. The server MUST validate the Origin header on every incoming connection to prevent DNS rebinding attacks.

Official SDKs

All SDKs are under the modelcontextprotocol GitHub org. Treat version numbers as a snapshot; verify current releases before pinning.

Language Package Install
TypeScript @modelcontextprotocol/server / @modelcontextprotocol/client (v2.1.0, implements the current 2026-07-28 spec, confirmed via npm this session); legacy single-package @modelcontextprotocol/sdk (v1.30.1) still published for the pre-2026-07-28 protocol model npm install @modelcontextprotocol/server @modelcontextprotocol/client
Python mcp (v2.2.0, implements the current 2026-07-28 spec, confirmed via PyPI this session) pip install mcp (or uv add "mcp[cli]")
Kotlin modelcontextprotocol/kotlin-sdk Maven/Gradle — maintained with JetBrains
Go modelcontextprotocol/go-sdk go get — maintained with Google
Swift modelcontextprotocol/swift-sdk Swift Package Manager
C# modelcontextprotocol/csharp-sdk NuGet (ModelContextProtocol, current release v2.2.0, confirmed via nuget.org this session) — maintained with Microsoft; past the v1.0 milestone previously cited

Minimal server lifecycle

This is the lifecycle under the current 2026-07-28 spec revision, which dropped the explicit initialize/initialized handshake that pre-2026-07-28 servers used — see /resources/mcp-2026-spec-revision for the full before/after. Servers built against the older handshake (below, still common while the ecosystem migrates) continue to work against most deployed clients; new servers should target the current model:

  1. (optional) discover — a client MAY call server/discover before any other request to learn the server's supported protocol versions, capabilities, and identity up front, or use it as a backward-compatibility probe on stdio.
  2. per-request version/capability negotiation — every request (not a one-time handshake) carries the client's protocol version and capabilities in _meta (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities); a version the server does not support returns UnsupportedProtocolVersionError.
  3. discovery — client may call tools/list, resources/list, prompts/list to enumerate what the server offers; list results are stateless (no per-connection variance) and carry ttlMs/cacheScope metadata for client-side caching.
  4. invocation — client sends tools/call (or equivalent) with the tool name and arguments; server runs the handler and returns a content array tagged resultType: "complete" (or "input_required" for a multi-round-trip interim result).
  5. shutdown — for stdio, the host closes stdin; Streamable HTTP has no protocol-level session to close (there is no Mcp-Session-Id to send an HTTP DELETE against) — the client simply stops sending requests.

The pre-2026-07-28 handshake model, for reference: client sends initialize with protocolVersion and capabilities, server responds with its own protocolVersion/capabilities/serverInfo, client sends notifications/initialized, then discovery/invocation/shutdown as above (shutdown over Streamable HTTP used HTTP DELETE with the now-removed session ID).

TypeScript minimal example, written against the legacy 1.x-line @modelcontextprotocol/sdk package (still published on npm at v1.30.1; implements the pre-2026-07-28 initialize/initialized handshake shown above) — the SDK implementing the current spec split into @modelcontextprotocol/server/@modelcontextprotocol/client (both v2.1.0); consult those packages' own docs for the current-model API surface, which is not reproduced here:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "example", version: "1.0.0" });

server.registerTool("ping", {
  description: "Return a pong",
  inputSchema: { message: z.string().optional() },
}, async ({ message }) => ({
  content: [{ type: "text", text: `pong: ${message ?? ""}` }],
}));

const transport = new StdioServerTransport();
await server.connect(transport);

Remote-server concerns

Authentication — remote Streamable HTTP servers should implement OAuth 2.1 with PKCE. Full detail is in /resources/mcp-server-authentication.

Statelessness — servers that do not issue an Mcp-Session-Id are effectively stateless: each POST is independent. This simplifies horizontal scaling but means the server cannot hold in-memory state across requests.

CORS — if the server will be called from browser-hosted clients, set Access-Control-Allow-Origin appropriately. Restrict origins to known client domains where possible.

Session handling — if issuing session IDs, use cryptographically random values (UUID v4 or equivalent). Clients that receive HTTP 404 on a session-bearing request must start a new initialize exchange.

Testing: MCP Inspector

The official interactive testing tool is MCP Inspector (@modelcontextprotocol/inspector on npm). Run it with:

npx @modelcontextprotocol/inspector

It provides a UI to connect to any MCP server, browse its tools/resources/prompts, send calls manually, and inspect the raw JSON-RPC messages. Source: github.com/modelcontextprotocol/inspector.

Publishing and discovery

The official registry is at registry.modelcontextprotocol.io. To publish, add a server.json file to your repository (schema: https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json) describing your server's name, version, transport type, and endpoint URL, then use the mcp-publisher CLI (mcp-publisher login github → mcp-publisher publish). Publishing to the registry seeds downstream aggregators and client-vendor marketplaces. For evaluation criteria and security checks to apply before connecting to third-party servers, see /resources/mcp-server-discovery.

ChangeGamer's /mcp endpoint

ChangeGamer runs a remote MCP server at https://changegamer.ai/mcp using the Streamable HTTP transport. It is unauthenticated — no OAuth flow is required to connect. It is open and read-only. Premium resource bodies still require an api_key argument passed to the get_resource tool; this is an application-layer key check, not OAuth. ChangeGamer does not implement RFC 9728 Protected Resource Metadata.

Verified sources

Re-verified 2026-09-28 (M221 corpus pass #14) — found and corrected a real drift: this page still described the 2025-11-25 spec as current, but 2026-07-28 shipped as final (confirmed by M178/M179 and its own dedicated resource, /resources/mcp-2026-spec-revision, back on 2026-07-31) and this implementation guide had not been updated to match. Directly fetched this session (via the spec repo's raw GitHub content, since modelcontextprotocol.io itself refused the connection under this session's egress policy): the repo README (confirms 2026-07-28 is the schema/spec directory referenced as current) and the 2026-07-28 changelog (confirms the initialize/initialized-handshake removal, Mcp-Session-Id removal, server/discover RPC, _meta-based per-request versioning, and resultType field — all now reflected in the "Minimal server lifecycle" section above). Also directly confirmed this session: the registry's server.schema.json at the 2025-12-11 path still resolves live (unchanged, no drift there), mcp on PyPI is at v2.2.0, @modelcontextprotocol/server/client on npm are at v2.1.0 (with the legacy single-package @modelcontextprotocol/sdk still published at v1.30.1), and ModelContextProtocol on NuGet is at v2.2.0 — well past the "reached v1.0" claim previously cited for the C# SDK, corrected in the table above.

#mcp #tools #protocols #agents #implementation

Category: Guide

Free to read, always. Want this whole reference corpus inside your own agents? €5 unlocks every premium reference for one agent; €25 licenses the full corpus as RAG / fine-tuning data with an AI-use grant (procurement one-pager: /corpus-license); €150 adds redistribution rights.

Machine formats: Markdown · JSON · offers at /api/pricing.json · payment at /api/payment.json. Preview the exact corpus format free as NDJSON.