Before MCP, every agent framework had its own way to wire up tools — switch from LangChain to CrewAI and you rewrote every integration. MCP standardizes that interface so tools become portable building blocks. Launched in late 2024 by Anthropic, it's now supported by Claude, Cursor, Windsurf, LangChain, LlamaIndex, CrewAI, and Dify.
Why MCP Matters
- Write once, use anywhere — any MCP-compatible client can call your server.
- No vendor lock-in — swap models or frameworks without rebuilding integrations.
- Better security — tools run in isolated server processes, not inline with the model.
- Composable — mix and match servers like modules.
How MCP Works
MCP is a client-server protocol with three roles: the Host (the AI app that needs tools, e.g. Claude Desktop), the Client (manages server connections, built into the host), and the Server (provides the capabilities). A server can expose three things: Tools (functions the AI calls), Resources (data it can read), and Prompts (reusable templates).
Official MCP Servers (Free)
| MCP Server | What It Does | Free? |
|---|---|---|
| filesystem | Read/write local files and directories | Yes |
| github | Search repos, create issues, manage PRs | Yes (with GitHub token) |
| brave-search | Web search via Brave Search API | Key required; every Brave plan now needs a card on file — $5 free credits/month (~1,000 queries) |
| sqlite / postgresql | Query and modify databases | Yes (bring your own DB) |
| slack | Send messages, search channels | Yes (with Slack token) |
| puppeteer | Control headless Chrome for automation | Yes |
| memory | Persistent key-value memory for agents | Yes |
| fetch | Fetch any web URL and return content | Yes |
Get Started with Claude Desktop
Claude Desktop has built-in MCP support. Add servers to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%/Claude/claude_desktop_config.json (Windows), then restart — the tools appear automatically:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/yourname/Documents"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "your_token_here" }
},
"brave-search": {
"command": "npx",
"args": ["-y", "@brave/brave-search-mcp-server"],
"env": { "BRAVE_API_KEY": "your_brave_api_key" }
}
}
}
Build Your First MCP Server (Python)
Install the SDK with pip install mcp, then expose a tool. This one gets weather via the free, keyless Open-Meteo API:
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import httpx
server = Server("weather-server")
@server.list_tools()
async def list_tools():
return [Tool(
name="get_weather",
description="Get current weather for a city",
inputSchema={
"type": "object",
"properties": {"city": {"type": "string", "description": "City name"}},
"required": ["city"]
}
)]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
city = arguments["city"]
async with httpx.AsyncClient() as client:
geo = await client.get(
f"https://geocoding-api.open-meteo.com/v1/search?name={city}&count=1")
r = geo.json()["results"][0]
lat, lon = r["latitude"], r["longitude"]
w = await client.get(
f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}"
f"¤t=temperature_2m,wind_speed_10m")
d = w.json()["current"]
return [TextContent(type="text",
text=f"{city}: {d['temperature_2m']}°C, Wind: {d['wind_speed_10m']} km/h")]
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Use MCP in an Agent Framework
MCP servers plug straight into Python frameworks. Loading a server's tools into LangChain takes a few lines:
from langchain_mcp_adapters.tools import load_mcp_tools
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-3-5-sonnet-20241022")
server_params = StdioServerParameters(
command="npx",
args=["-y", "@brave/brave-search-mcp-server"],
env={"BRAVE_API_KEY": "your_key"})
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await load_mcp_tools(session) # MCP -> LangChain tools
model_with_tools = model.bind_tools(tools)
response = await model_with_tools.ainvoke(
"Search for the latest news about Model Context Protocol")
CrewAI works the same way via MCPServerAdapter(server_params), which wraps a server's tools for an agent.
MCP vs Traditional Tool Calling
| Feature | Traditional Tool Calling | MCP |
|---|---|---|
| Reusability | Framework-specific | Universal across all MCP hosts |
| Security | Code runs inline | Isolated server process |
| Discovery | Manually defined | Auto-discovery via protocol |
| Transport | In-process calls | stdio, HTTP with SSE |
| Maintenance | Update per framework | Update once, works everywhere |
Transport Methods
stdio is the common local transport — the host spawns the server as a child process and talks over stdin/stdout. Best for desktop apps and local dev. HTTP with SSE is for remote servers multiple clients hit over the network — best for production and cloud-hosted tools:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("My API Server")
@mcp.tool()
def search_database(query: str) -> str:
"""Search the product database"""
return f"Results for: {query}"
mcp.run(transport="sse") # http://localhost:8000/sse
Popular Community Servers
Beyond the official set, the community has published 1,000+ servers — vector DBs (uvx mcp-server-qdrant), Docker, Redis, Notion, Playwright (npx @playwright/mcp), Linear, and more. Browse them at github.com/modelcontextprotocol/servers and mcp.so.
Security Best Practices
- Least privilege — scope each server to only what it needs (e.g. limit filesystem to specific directories).
- Review server code before running community servers.
- Environment variables for keys — never hardcode them in config.
- Sandbox untrusted servers in Docker, and audit tool calls in production.
Frequently Asked Questions
Are the official MCP servers really free?
Yes. Anthropic's official servers are free and open-source. Some need a token or key for the underlying service (a GitHub token, a Brave Search key — note Brave now requires a card on every plan and gives $5 credits/month, roughly 1,000 queries), but the servers themselves cost nothing.
Do I need to code to use MCP?
No, to consume it. Adding servers to Claude Desktop is just editing a JSON config and restarting. You only write code when you build your own server or wire MCP into an agent framework.
What's the difference between MCP and normal tool calling?
Traditional tool calling is framework-specific and runs inline. MCP standardizes the interface across every host, isolates tools in their own process, and supports auto-discovery — so one server works everywhere without rewrites.
stdio or HTTP/SSE — which transport?
Use stdio for local, single-user setups (desktop apps, development). Use HTTP with SSE when the server is remote or multiple clients need to connect, such as a cloud-hosted production deployment.
The Verdict
MCP is fast becoming the standard way to give AI models clean, secure, portable access to the real world. Start with the filesystem and brave-search servers in Claude Desktop, then build your own as needs grow. Official docs and spec live at modelcontextprotocol.io.