跪拜 Guibai
← All articles
Frontend · Backend

MCP from Scratch: Build a Local Server and Wire It into a LangChain Agent

By 嘟嘟0717 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

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.

Summary

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.

Takeaways
An MCP server is a child process spawned by the agent; communication happens over stdin/stdout using JSON messages.
`MultiServerMCPClient` accepts a `command` and `args` per server and merges all tools into a single array via `getTools()`.
Resources registered on the server are read by the agent and injected as a SystemMessage so the LLM understands available capabilities.
Every `ToolMessage` returned to the LLM must carry the original `tool_call_id`, or the model cannot match results to concurrent calls.
The ReAct loop runs `invoke` in a `for` loop, checks for `tool_calls`, executes them, and exits when the response contains no further tool calls.
Swapping `StdioServerTransport` for `StreamableHTTPServerTransport` converts a local MCP server into a remote one with no logic changes.
Conclusions

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.

Concepts & terms
MCP (Model Context Protocol)
An open protocol that lets AI agents discover and invoke tools and resources provided by separate server processes, typically over stdio or HTTP.
StdioServerTransport
An MCP transport that communicates over standard input and output streams, used when the agent spawns the server as a child process.
ReAct loop
A reasoning-and-acting pattern where the LLM repeatedly decides whether to call a tool, the agent executes it, and the result is fed back into the conversation until a final answer emerges.
tool_call_id
A unique identifier attached to each tool call request that must be echoed in the corresponding ToolMessage so the LLM can correlate results when multiple tools are called in parallel.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗