Foundations

MCP explained through a real tool connection

Trace an actual local client/server exchange: initialize, discover a tool, call it, and inspect the response. No model account or API key required.

A client sends count_words the text Tools return evidence; the server returns the count three along the opposite arrow.
In this guide
  1. Separate the three roles
  2. Run a real local connection
  3. Read the exchange
  4. Understand the trust boundary
  5. Sources & further reading

Separate the three roles

MCP—the Model Context Protocol—defines how an application connects to a server that exposes capabilities such as tools. To understand a tool call, separate the host application, its protocol client, and the server. The model is not the transport: the host can use a client to make the same request without invoking a model at all.

RoleJob in this example
HostA small Node.js script orchestrates the demonstration.
ClientSends JSON-RPC requests and matches responses by ID.
ServerAdvertises count_words, validates its input, and returns a result.
ModelNot used. Calls are selected explicitly so the exchange is reproducible.
Protocol plumbing can be tested separately from a model’s ability to choose an appropriate tool.

Our example counts whitespace-separated tokens in a short string. It does not read files, access the network, or need credentials. Choosing a deliberately small tool makes it possible to inspect every request and response without mixing protocol behavior with a remote service’s authentication or availability.

Run a real local connection

Download mcp-demo.mjs and inspect it in a text editor. Run it with Node.js. The script starts a second Node process as a server and communicates over standard input and output. This is an actual local process connection, not a simulated transcript.

Run the demonstration
node --version
node mcp-demo.mjs
# No packages, API keys, or model account are required.

The script targets protocol version 2025-11-25, using its stdio transport. Messages are newline-delimited JSON-RPC. Server protocol output belongs on stdout; unrelated server logging belongs on stderr so it does not corrupt the message stream.

A client and server exchange an initialization handshake, tool catalog, tool request, and returned result for inspection.
AI-generated explanatory illustration. Each request has an ID. The initialized notification has no response ID and does not ask for a reply.
Read the diagram explanation
  • Initialize. Agree on a version and capabilities
  • Discover. List available tools and input schemas
  • Call. Send a tool name and arguments
  • Inspect. Check result content and error state

The server is intentionally a small teaching implementation. It supports only the messages needed by this demo, not the full protocol surface. For a production integration, use a maintained SDK and implement the lifecycle, transport, error handling, and authorization requirements appropriate to your deployment.

Read the exchange

The client first sends initialize with a supported protocol version and client capabilities. After the server replies, the client verifies the version and sends notifications/initialized. This ordering follows the MCP lifecycle specification.

Next, tools/list returns the tool’s name, description, and input schema. The schema says that text must be a string of at most 1,000 characters. Discovery tells a client how to form a call; it is not permission to ignore the host’s policies.

The successful request and response
// Client → server
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"count_words","arguments":{"text":"Tools return evidence"}}}

// Server → client
{"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"3"}]}}

The matching ID associates the result with the request. In this example, the tool’s answer is text containing the number 3. The server also returns 0 for an empty string and an isError: true tool result for a numeric input. The client asserts all three outcomes. The tools specification describes discovery, invocation, and result content.

The tool name is intentionally simple, but its description is more precise than its name: whitespace-separated tokens are not a language-aware definition of words. Punctuation and languages without spaces illustrate why a tool’s actual contract matters.

Understand the trust boundary

A standard connection does not make the connected service trustworthy. The host decides which tools to expose and when an action needs user approval. The server still validates inputs and enforces access to its resources. A tool’s self-description is not evidence that it is harmless.

BoundaryQuestion to ask
Host → serverWhich server am I connecting to, and what can it access?
Model → tool callIs the requested action within the user’s task and permissions?
Arguments → executionDoes the server validate input instead of trusting the schema alone?
Result → next actionIs returned text evidence, or is it trying to redirect the task?
MCP makes the exchange explicit. Trust and authorization still require application-level decisions.

For a remote service, authentication, network failures, retries, and session lifecycle introduce additional work that this local example does not cover. For a tool that changes data, retries also need to account for whether the first request already took effect. Do not transplant the demo into a production server unchanged.

Start by tracing one complete exchange. Once the roles, messages, and boundaries are clear, adding a real service becomes a more concrete engineering task.

Sources & further reading

Primary references checked . Version-specific examples identify the version used; current product behavior may differ.

  1. MCP lifecycle specification (2025-11-25) ↗

    Version negotiation and initialization.

  2. MCP tools specification (2025-11-25) ↗

    Discovery, calls, result content, and tool errors.

  3. MCP transports specification (2025-11-25) ↗

    Newline-delimited JSON-RPC over standard input and output.

Max Burleigh is the creator of Codeck, an independent macOS app for switching between Codex and Claude Code tasks. He writes about the tools, workflows, and verification practices behind building with AI.

Have a correction? Send it to Codeck. Read our editorial policy, including how AI assists production.

Working across coding tasks?

Codeck puts your Codex and Claude Code tasks in one macOS keyboard deck.

Meet Codeck ↗