Model Context Protocol (MCP) Guide: Build Custom Tools for Claude & Cursor
What You Will Master in This Tutorial
- Understand the MCP client-server protocol and JSON-RPC 2.0 transport.
- Build a production MCP server in Python using FastMCP.
- Expose secure database queries and file readers as agent tools.
- Configure Cursor, Windsurf, and Claude Desktop to consume custom MCP servers.
1. What is Model Context Protocol (MCP)?
Model Context Protocol (MCP) is an open standard introduced by Anthropic that standardizes how AI applications connect to external data sources, developer tools, and proprietary environments. Think of MCP as the USB-C port for AI agents.
from mcp.server.fastmcp import FastMCP
# Initialize MCP Server
mcp = FastMCP("PostgresTools")
@mcp.tool()
def run_read_only_query(query: str) -> str:
"""Execute a safe SELECT query against the staging database."""
if not query.strip().lower().startswith("select"):
raise ValueError("Only read-only SELECT queries are permitted.")
# Execute query against database pool
return "Query executed: 24 records returned."
if __name__ == "__main__":
mcp.run(transport="stdio")
Knowledge Check: Test Your Understanding
Frequently Asked Questions
Going deeper: MCP servers in practice
Building the FastMCP server from this tutorial is the first step; operating one safely is the practice that follows. The read-only guard in the example β rejecting any query that does not start with SELECT β is the pattern to generalize across everything you expose: each tool should do one thing, validate its inputs as if the model were an untrusted caller, and return bounded, shaped results. Transport follows deployment. A stdio server suits local tools consumed by Cursor, Windsurf, or Claude Desktop on your own machine, while a remote server over SSE serves a whole team β and raises the authentication bar accordingly. Build to the standard, and one server serves every MCP client.
Common mistakes
- Exposing write access by default. The tutorial's example tool deliberately enforces read-only SELECT queries. A generic 'run any SQL' tool hands the model your entire database, including the DROP statements β scope every tool to the minimum it needs.
- Returning unbounded results into the context window. A query tool that can return a whole table floods the model's context and buries the relevant rows. Cap row counts, select specific columns, and summarize where possible.
- Hard-coding credentials inside the server. Database passwords and API keys belong in environment variables or configuration the server reads at startup β never in tool code you commit, share, or paste into documentation.
- Building for exactly one client. MCP is a standard protocol over JSON-RPC 2.0, and the tutorial's FAQ confirms Cursor, Windsurf, Claude Desktop, and modern VS Code all consume custom servers from a settings JSON. A server that only works in one client is usually a configuration bug, not a limitation.
Frequently asked questions
What exactly does MCP standardize?
How AI applications connect to external data sources and tools: a client-server protocol, introduced by Anthropic, that runs over JSON-RPC 2.0 on stdio or HTTP with SSE. The tutorial's analogy is apt β MCP is the USB-C port for AI agents, one connector shape for many devices.
Which programming language should I build my MCP server in?
The tutorial uses Python with FastMCP, where a decorator turns an ordinary function into an agent-callable tool. In practice, choose the SDK that matches the systems you are exposing β the protocol is language-agnostic, so the server should live near the data it serves.
Should my MCP server run locally or remotely?
Locally over stdio for personal development tools β it starts with the client and inherits your machine's permissions. Remotely over SSE when a team shares one server, but add authentication and input validation first, because a network listener is a very different exposure than a local subprocess.