What is MCP?
Model Context Protocol (MCP) is an open standard developed by Anthropic that enables seamless integration between AI models and external tools and data sources. Just as USB-C provides a universal interface for connecting devices, MCP offers a standardized interface connecting Claude to the outside world.
With MCP, Claude can:
- Read and write to local file systems
- Execute database queries
- Call external APIs
- Run custom business logic
MCP Core Architecture
MCP adopts a client-server architecture.
Claude (MCP Client)
↕ MCP Protocol (JSON-RPC over stdio/SSE)
MCP Server (Custom Tools)
There are three main concepts:
Tools: Functions that Claude can call, such as read_file, query_database, or send_email.
Resources: Data that Claude can reference — files, database records, API responses, and more.
Prompts: Reusable prompt templates optimized for specific tasks.
Building Your First MCP Server
Let's build a simple MCP server in TypeScript. We'll implement a tool that returns the current time.
1. Project Setup
mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node2. Server Implementation
// src/index.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: {},
},
}
);
// Return available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get_current_time",
description: "Returns the current date and time",
inputSchema: {
type: "object",
properties: {
timezone: {
type: "string",
description: "Timezone (e.g., America/New_York)",
},
},
},
},
],
};
});
// Tool execution handler
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "get_current_time") {
const timezone =
(request.params.arguments?.timezone as string) || "America/New_York";
const now = new Date().toLocaleString("en-US", { timeZone: timezone });
return {
content: [
{
type: "text",
text: `Current time (${timezone}): ${now}`,
},
],
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);3. Connecting to Claude Desktop
Add the following to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["/path/to/my-mcp-server/dist/index.js"]
}
}
}After restarting Claude Desktop, this tool becomes available in your Claude conversations.
Real-World Use Cases
Use Case 1: Internal Database Integration
// Tool to query a PostgreSQL database
{
name: "query_sales_data",
description: "Query sales data from the database",
inputSchema: {
type: "object",
properties: {
start_date: { type: "string", description: "Start date (YYYY-MM-DD)" },
end_date: { type: "string", description: "End date (YYYY-MM-DD)" },
},
required: ["start_date", "end_date"],
},
}With this tool, a natural language instruction like "analyze last month's sales data" causes Claude to automatically query the database and return an analysis.
Use Case 2: File Automation
// Tool to read/write files in a project directory
{
name: "write_report",
description: "Save an analysis report to a file",
inputSchema: {
type: "object",
properties: {
filename: { type: "string" },
content: { type: "string" },
},
required: ["filename", "content"],
},
}Use Case 3: External Service Integration
By creating tools that integrate with external APIs like Slack, Notion, or GitHub, Claude can directly operate these services.
// Tool to create a GitHub issue
{
name: "create_github_issue",
description: "Create an issue on GitHub",
inputSchema: {
type: "object",
properties: {
repo: { type: "string", description: "Repository name (owner/repo)" },
title: { type: "string", description: "Issue title" },
body: { type: "string", description: "Issue body" },
},
required: ["repo", "title"],
},
}Best Practices for MCP Development
Keep tool granularity appropriate: Don't pack too many features into a single tool. Follow the single responsibility principle.
Handle errors carefully: Claude reads error messages to determine its next action. Clearly communicate the cause of the error and recommended remediation.
Security considerations: When your MCP server handles API keys or sensitive information, manage them with environment variables and avoid hardcoding credentials.
Write clear tool descriptions: Claude reads the description field to decide when to use a tool. Write precise, clear descriptions so Claude can apply them accurately.
Conclusion
MCP dramatically expands Claude's potential. Whether integrating internal tools, querying databases, or operating external services, MCP applies to virtually any use case.
Anthropic has published MCP as an open standard, and the official repository features numerous samples and community-built servers. Build your own MCP server tailored to your specific use case and deepen your integration with Claude.