Technical
MCP Servers in Production: What Actually Ships
MCP solves a real problem: every agent framework reinvented tool calling, and none of them agreed. MCP gives you one protocol and many implementations. After shipping three production agents backed by MCP servers, here is what I learned.
Keep Server Tools Narrow
The first MCP server I wrote exposed 18 tools. The agent got confused, picked wrong tools, and the results were erratic. I split the server into three focused ones: one for file operations, one for the database, one for deployment. Each agent loads only the servers it needs.
Narrow tool surfaces lead to more accurate tool selection. This is a general pattern: the fewer wrong choices the agent has, the more right ones it makes.
Make Tools Idempotent
Agents retry. They retry when network calls fail, when responses are malformed, when the orchestrator loses state. If your tool is not idempotent, retries cause damage. My tools either check-and-act or use natural idempotency keys like post slugs and user IDs.
# Not idempotent: retries create duplicates
@tool
def create_post(title: str, body: str) -> dict:
return db.insert(title=title, body=body)
# Idempotent: slug is the natural key
@tool
def upsert_post(slug: str, title: str, body: str) -> dict:
existing = db.get_by_slug(slug)
if existing:
return db.update(slug, title=title, body=body)
return db.insert(slug=slug, title=title, body=body)Error Messages Are User Interface
When a tool call fails, the error message goes back to the model. The model reads it and decides what to do next. Vague errors like 'bad request' lead to confused retries. Specific errors like 'slug already exists with different body' lead to correct recovery.
I now treat tool error messages as agent-facing UI. They get the same care as user-facing error messages in a web app.
Logging Everything
Every MCP tool call gets logged: input arguments, output, duration, agent identity. This log is gold when debugging agent behavior. When an agent does something weird, I replay the exact tool sequence and usually spot the issue in minutes.
The MCP spec is simple by design. The discipline is in the tools you expose. See the Model Context Protocol documentation for the spec and reference implementations.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read