How to Build an MCP Server in 2026: Complete Beginner Guide
How to Build an MCP Server (2026)
MCP (Model Context Protocol) lets your AI connect to anything. Here’s how to build your first server from scratch.
What You’ll Build
An MCP server that exposes custom tools to AI assistants. Once connected, your AI can call these tools to fetch data, run queries, or perform actions — all through natural conversation.
Prerequisites
- Python 3.10+ or Node.js 18+
- An MCP-compatible client (Claude Desktop, Cursor, Antigravity, etc.)
- Basic programming knowledge
Option 1: Python (Recommended for Beginners)
Step 1: Install the SDK
pip install mcp
Step 2: Create Your Server
Create a file called my_server.py:
from mcp.server.fastmcp import FastMCP
# Create the server
mcp = FastMCP("My First MCP Server")
@mcp.tool()
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
# In production, call a real weather API
return f"Weather in {city}: 22°C, partly cloudy"
@mcp.tool()
def search_notes(query: str) -> str:
"""Search through personal notes."""
# In production, search a database
notes = [
{"title": "Meeting Notes", "content": "Discussed Q2 roadmap"},
{"title": "Ideas", "content": "Build an MCP server for my notes"},
]
results = [n for n in notes if query.lower() in n["content"].lower()]
return str(results) if results else "No matching notes found"
@mcp.tool()
def add_note(title: str, content: str) -> str:
"""Add a new note."""
# In production, save to a database
return f"Note '{title}' saved successfully"
if __name__ == "__main__":
mcp.run()
Step 3: Configure Your AI Client
For Claude Desktop, add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["/path/to/my_server.py"]
}
}
}
For Cursor, add to .cursor/mcp.json in your project:
{
"mcpServers": {
"my-server": {
"command": "python",
"args": ["my_server.py"]
}
}
}
Step 4: Test It
Restart your AI client. You should see your tools available. Ask: “What’s the weather in Tokyo?” — your AI will call your get_weather tool.
Option 2: TypeScript
Step 1: Set Up
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
Step 2: Create the Server
Create index.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "My MCP Server",
version: "1.0.0",
});
server.tool(
"get_weather",
"Get current weather for a city",
{ city: z.string().describe("City name") },
async ({ city }) => ({
content: [{ type: "text", text: `Weather in ${city}: 22°C, partly cloudy` }],
})
);
server.tool(
"search_database",
"Search the product database",
{ query: z.string().describe("Search query") },
async ({ query }) => ({
content: [{ type: "text", text: `Found 3 results for "${query}"` }],
})
);
const transport = new StdioServerTransport();
await server.connect(transport);
Real-World MCP Server Examples
Database Query Server
import sqlite3
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Database Server")
@mcp.tool()
def query_database(sql: str) -> str:
"""Run a read-only SQL query against the database."""
conn = sqlite3.connect("my_database.db")
try:
cursor = conn.execute(sql)
results = cursor.fetchall()
columns = [desc[0] for desc in cursor.description]
return str([dict(zip(columns, row)) for row in results])
finally:
conn.close()
API Integration Server
import requests
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("API Server")
@mcp.tool()
def search_github(query: str, language: str = "python") -> str:
"""Search GitHub repositories."""
response = requests.get(
"https://api.github.com/search/repositories",
params={"q": f"{query} language:{language}", "per_page": 5}
)
repos = response.json()["items"]
return "\n".join([f"- {r['full_name']} ⭐{r['stargazers_count']}" for r in repos])
Transport Options
stdio (Default)
The AI client launches your server as a subprocess. Simplest setup. Works with all clients.
Streamable HTTP (For Remote Servers)
Run your MCP server on a remote machine. Better for team environments and production.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Remote Server")
# ... define tools ...
if __name__ == "__main__":
mcp.run(transport="streamable-http", host="0.0.0.0", port=8080)
Security Best Practices
MCP servers run with the same permissions as your user account. Follow these rules:
- Read-only by default — Don’t give write access unless necessary
- Validate inputs — Never pass user input directly to shell commands
- Limit scope — One server per concern (database, API, files)
- Use environment variables for secrets — Never hardcode API keys
- Audit tool calls — Log what your AI does through MCP
Known Vulnerabilities (2026)
- Prompt injection through tool responses — Malicious data in API responses can influence AI behavior
- Tool poisoning — Untrusted MCP servers can expose harmful tools
- Credential leakage — AI may expose secrets passed through MCP contexts
The MCP Ecosystem (March 2026)
| Stat | Number |
|---|---|
| Published MCP servers | 10,000+ |
| Monthly SDK downloads | 97 million |
| Supported clients | 15+ major tools |
| Official server registry | mcp.run |
Popular Pre-Built Servers
- Postgres/MySQL — Query databases
- GitHub — Issues, PRs, repos
- Slack — Messages, channels
- Filesystem — Read/write local files
- Google Cloud — BigQuery, Maps, GCE
- Playwright — Browser automation
The Bottom Line
Building an MCP server is easier than building a REST API. The SDK handles all the protocol complexity — you just write functions. Start with a simple tool, connect it to Claude Desktop or Cursor, and expand from there. The MCP ecosystem in 2026 is mature enough that most common integrations already have pre-built servers you can use immediately.
Last verified: March 2026