The Model Context Protocol (MCP) is Anthropic's open standard for connecting AI models to external data and tools. Instead of baking integrations into the model, MCP lets you plug in any data source or capability at runtime.
What MCP Actually Is
MCP is a JSON-RPC protocol that defines how an AI host (Claude, Cursor, Cline) communicates with external servers. An MCP server exposes:
- Tools: Functions the AI can call (like calling an API or running a query)
- Resources: Data the AI can read (like a file or database record)
- Prompts: Reusable prompt templates
When Claude has an MCP server connected, it can call those tools the same way it calls built-in capabilities.
Building Your First MCP Server
npm install @modelcontextprotocol/sdk
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
const server = new Server(
{ name: 'my-mcp-server', version: '1.0.0' },
{ capabilities: { tools: {} } }
)
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'get_weather',
description: 'Get current weather for a city',
inputSchema: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name' },
},
required: ['city'],
},
},
],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === 'get_weather') {
const { city } = request.params.arguments as { city: string }
const weather = await fetchWeather(city) // your implementation
return {
content: [{ type: 'text', text: JSON.stringify(weather) }],
}
}
throw new Error(`Unknown tool: ${request.params.name}`)
})
const transport = new StdioServerTransport()
await server.connect(transport)
Connecting to Claude Desktop
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {
"API_KEY": "your-api-key"
}
}
}
}
Restart Claude Desktop and your tools appear automatically.
Connecting to Claude Code
// .claude/settings.json in your project
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["tsx", "./mcp-server/server.ts"]
}
}
}
Resources (Read-Only Data)
import { ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js'
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
resources: [
{
uri: 'database://users',
name: 'User database',
mimeType: 'application/json',
},
],
}))
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
if (request.params.uri === 'database://users') {
const users = await db.user.findMany({ take: 100 })
return {
contents: [{
uri: request.params.uri,
mimeType: 'application/json',
text: JSON.stringify(users),
}],
}
}
throw new Error('Resource not found')
})
Security Considerations
MCP servers run locally and can execute code on your machine. Security matters:
- Validate all inputs: Sanitize tool arguments before using them in queries or shell commands
- Principle of least privilege: Only expose what the AI actually needs
- No hardcoded secrets: Use environment variables
- Audit MCP servers you install: They run with your user permissions
The MCP Security Scanner at whoffagents.com scans any MCP server for prompt injection, path traversal, and command injection vulnerabilities.
Build your own MCP server with the Crypto Data MCP as a reference implementation at github.com/Wh0FF24/crypto-data-mcp — open source, free to use and fork.
Top comments (0)