MCP Servers Explained: What They Are, and When You Shouldn't Bother

MCP (Model Context Protocol) gets pitched as the default way to give an agent tools now, which means it’s also getting reached for in situations where a plain function call would have been simpler, faster, and easier to debug. Both things are true at once: MCP solves a real problem, and it’s not free.

If you haven’t seen the layering first, read tool-calling vs. function-calling vs. MCP first — this piece assumes you know MCP sits underneath the tool-calling loop, not next to it.

What an MCP server actually gives you

A running process that speaks a standard protocol (JSON-RPC over stdio or HTTP) and exposes three kinds of things to any connected host: tools (functions the agent can call), resources (data the agent can read, like files or query results), and prompts (reusable prompt templates the host can surface).

from mcp.server.mcpserver import MCPServer  # mcp 2.x — see note below if you're on 1.x

mcp = MCPServer("reporting-db")

@mcp.tool()
def query_database(sql: str) -> str:
    """Run a read-only SQL query against the reporting database."""
    return run_readonly_query(sql)

@mcp.resource("schema://tables")
def list_tables() -> str:
    """Expose the current schema so the agent doesn't have to guess column names."""
    return get_schema_summary()

if __name__ == "__main__":
    mcp.run()

(If you’re still on mcp 1.x, the class you want is FastMCP from mcp.server.fastmcp instead — it was renamed to MCPServer in the 2.x release. The decorators and everything else below work identically either way; only the import and class name changed.)

Once this is running, it works identically whether it’s connected to Claude Code, Claude Desktop, or a custom agent host you wrote yourself. That portability is the entire value proposition — and it’s real when you actually need it.

When MCP is genuinely the right call

When it’s overhead you don’t need

The actual decision rule

Ask: will more than one agent host ever need this tool, or am I distributing it for others to plug in? If yes, MCP is the right layer — that portability is exactly what it’s for. If no — one agent, one codebase, one use — a direct function call in your tool-calling loop does the same job with one less network boundary between you and the bug you’re chasing at 11pm.

MCP is infrastructure. Infrastructure is worth building when more than one thing depends on it. Before that point, it’s usually just overhead wearing infrastructure’s clothes.

← Back to all articles