How to set up and use MCP (Model Context Protocol) servers with Claude Code. Extend Claude's capabilities with custom tools, databases, and APIs.
Claude Code MCP Servers: Complete Setup Guide
MCP (Model Context Protocol) servers extend Claude Code's capabilities. Connect to databases, APIs, file systems, and custom tools—all accessible to Claude.
This guide covers everything: what MCP is, how to set it up, and practical examples.
What is MCP?
MCP (Model Context Protocol) is Anthropic's open standard for connecting AI models to external tools and data sources.
Think of it like this:
- Claude Code = the brain
- MCP servers = the hands (tools Claude can use)
Without MCP, Claude Code can read files and run commands. With MCP, Claude Code can:
- Query databases directly
- Call APIs
- Access cloud services
- Use specialized tools
- Read from any data source
How MCP Works
You → Claude Code → MCP Server → External Service
↓
Response
- You ask Claude Code something
- Claude Code recognizes it needs external data
- Claude Code calls the appropriate MCP server
- MCP server fetches/processes data
- Results return to Claude Code
- Claude Code uses the data to answer you
Setting Up MCP Servers
Configuration Location
Claude Code reads MCP configuration from:
~/.claude/claude_desktop_config.json
Basic Configuration Structure
{
"mcpServers": {
"server-name": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {
"API_KEY": "your-key"
}
}
}
}
Example: Database Server
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost:5432/mydb"
}
}
}
}
Now Claude Code can query your PostgreSQL database directly.
Popular MCP Servers
1. Filesystem Server
Access files beyond the current project:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/directory"]
}
}
}
2. GitHub Server
Interact with GitHub repos, issues, PRs:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_your_token"
}
}
}
}
3. Postgres Server
Query PostgreSQL databases:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://..."
}
}
}
}
4. SQLite Server
Query SQLite databases:
{
"mcpServers": {
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "/path/to/database.db"]
}
}
}
5. Brave Search Server
Web search capabilities:
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {
"BRAVE_API_KEY": "your-api-key"
}
}
}
}
Using MCP in Claude Code
Once configured, Claude Code automatically uses MCP servers when relevant.
Database Queries
> What are our top 10 customers by revenue?
Claude Code:
- Recognizes this needs database access
- Uses the postgres MCP server
- Writes and executes the query
- Returns formatted results
File Access
> Summarize the logs from /var/log/app.log
Claude Code uses the filesystem server to read the file.
GitHub Operations
> Create an issue in our repo for the bug we just discussed
Claude Code uses the GitHub server to create the issue.
Building Custom MCP Servers
Basic Server Structure
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({
name: "my-custom-server",
version: "1.0.0"
});
// Define tools
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "my_tool",
description: "Does something useful",
inputSchema: {
type: "object",
properties: {
query: { type: "string" }
}
}
}
]
}));
// Handle tool calls
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "my_tool") {
const result = await doSomething(request.params.arguments.query);
return { content: [{ type: "text", text: result }] };
}
});
// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
Example: Custom API Server
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
const server = new Server({
name: "company-api",
version: "1.0.0"
});
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "get_customer",
description: "Get customer details by ID",
inputSchema: {
type: "object",
properties: {
customerId: { type: "string" }
},
required: ["customerId"]
}
},
{
name: "search_products",
description: "Search products by name or category",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
category: { type: "string" }
}
}
}
]
}));
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "get_customer") {
const customer = await api.getCustomer(args.customerId);
return { content: [{ type: "text", text: JSON.stringify(customer) }] };
}
if (name === "search_products") {
const products = await api.searchProducts(args.query, args.category);
return { content: [{ type: "text", text: JSON.stringify(products) }] };
}
});
MCP Resources
Besides tools, MCP servers can expose resources (data Claude can read):
server.setRequestHandler("resources/list", async () => ({
resources: [
{
uri: "config://app/settings",
name: "App Settings",
description: "Current application configuration"
}
]
}));
server.setRequestHandler("resources/read", async (request) => {
if (request.params.uri === "config://app/settings") {
const settings = await getAppSettings();
return {
contents: [{ uri: request.params.uri, text: JSON.stringify(settings) }]
};
}
});
Security Considerations
Environment Variables
Never hardcode secrets:
{
"mcpServers": {
"api": {
"command": "node",
"args": ["server.js"],
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}
Scoped Access
Limit filesystem access:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/specific/allowed/path"
]
}
}
}
Database Permissions
Use read-only connections when possible:
{
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://readonly_user:pass@host/db"
}
}
Debugging MCP Servers
Enable Logging
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"],
"env": {
"DEBUG": "mcp:*"
}
}
}
}
Test Manually
Run your server directly:
node server.js
Send test requests to verify it works.
Common Issues
- Server not starting - Check command path and args
- Tools not showing - Verify tools/list handler
- Errors on tool calls - Check input validation
- Timeout issues - Increase timeout or optimize server
Practical Use Cases
1. Analytics Dashboard
> Show me user signups for the last 30 days,
broken down by source.
MCP server queries your analytics database and returns data.
2. Deployment Status
> What's the status of our production deployment?
MCP server checks your CI/CD system.
3. Documentation Search
> Find examples of using our payment API.
MCP server searches internal documentation.
4. Slack Integration
> Post a summary of today's work to #dev channel.
MCP server sends message to Slack.
Best Practices
1. One Purpose Per Server
Don't cram everything into one server. Create focused servers:
db-server for database
github-server for GitHub
slack-server for Slack
2. Clear Tool Descriptions
Claude uses descriptions to decide when to use tools:
{
name: "get_user_orders",
description: "Retrieves all orders for a specific user, including order status, items, and totals. Use when asked about a user's purchase history.",
}
3. Handle Errors Gracefully
try {
const result = await doOperation();
return { content: [{ type: "text", text: result }] };
} catch (error) {
return {
content: [{ type: "text", text: `Error: ${error.message}` }],
isError: true
};
}
4. Type Your Inputs
Use JSON Schema properly:
{
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "The user's unique ID" },
limit: { type: "number", default: 10, maximum: 100 }
},
required: ["userId"]
}
}
The Bottom Line
MCP servers transform Claude Code from a coding assistant into a connected agent that can interact with your entire tech stack.
Start with pre-built servers for common needs (databases, GitHub, filesystems). Build custom servers for your specific tools and APIs.
The setup takes effort, but the payoff is Claude Code that truly understands your systems.
Need help building MCP integrations for your team? Cedar Operations helps companies extend AI tools for their specific workflows. Book a consultation →
Related reading: