MCP from Scratch: Build a Local Server and Wire It into a LangChain Agent
Tool definitions that live inside agent code create a maintenance bottleneck: every new project copies the same functions, and a Python tool team can't serve a Node agent. MCP's stdio transport makes tools a deployable artifact that any agent runtime can spawn, which shifts tool authorship from the agent developer to the domain expert who owns the data or API.
Instead of hardcoding tools inside an agent, MCP runs them as independent processes that an agent spawns and talks to over stdin/stdout. A single `command` + `args` config replaces copy-pasted tool definitions, and `MultiServerMCPClient` merges tools from every connected server into one array automatically.
The server side registers tools with a name, a Zod schema, and a handler function; resources act as a system-level manual that gets injected as a SystemMessage so the LLM knows what tools are available. The agent side follows a fixed ReAct loop: invoke, check for `tool_calls`, execute matching tools, feed results back with the correct `tool_call_id`, and repeat until the LLM produces a final answer.
Swapping the transport from `StdioServerTransport` to `StreamableHTTPServerTransport` turns the same server logic into a remote service. The pattern works identically whether the server is written in Node, Python, or Rust, because the protocol is just JSON over pipes.
Tool authorship flips from agent-developer to domain-owner: the person who understands the database or API writes the server, and any agent team can consume it.
The `tool_call_id` requirement is easy to overlook but becomes critical the moment an agent issues parallel tool calls; dropping it produces silent mismatches that are hard to debug.
Resources double as prompt-engineering infrastructure: they let a server author control exactly what the LLM believes the server can do, without touching the agent's system prompt.