# Model Context Protocol (MCP) with Claude AI
> [!metadata]- Metadata
> **Published:** [[2025-01-28|Jan 28, 2025]]
> **Tags:** #🌐 #ai-development #protocols #developer-tools #anthropic #claude-ai #learning
> [!info] **Understanding Model Context Protocol (MCP)**
> MCP is an open protocol that standardizes how applications provide context to LLMs, similar to how USB-C provides a standardized connection interface for devices.
>
> Imagine MCP as a universal adapter for AI models like Claude. Just like a USB-C port allows various devices to connect to your computer in a standardized way, MCP allows different applications to easily provide context to AI models. This means you can seamlessly connect your documents, code, or other data to Claude, enabling it to understand and work with your information more effectively for tasks like summarizing documents, debugging code, or automating workflows, all while ensuring your data is handled securely.
## Conceptual Diagram
```mermaid
graph LR
A[Applications - MCP Hosts] --> B(MCP Clients)
B --> C[MCP Servers]
C --> D{Local Data Sources}
C --> E[Remote Services]
C --> F[LLMs]
style A fill:#f9f,stroke:#333,stroke-width:2px
style F fill:#ccf,stroke:#333,stroke-width:2px
```
This diagram illustrates how MCP works: Applications (Hosts) use MCP Clients to communicate with MCP Servers. Servers then connect to local or remote data sources and LLMs to provide context.
## Core Benefits
- Pre-built integrations for LLM connectivity
- Flexibility to switch between LLM providers
- Secure data handling within infrastructure
## Architecture Components
1. **MCP Hosts**: Programs like Claude Desktop, IDEs, or AI tools
2. **MCP Clients**: Protocol clients maintaining 1:1 server connections
3. **MCP Servers**: Lightweight programs exposing capabilities through MCP
4. **Local Data Sources**: Computer files, databases, and services
5. **Remote Services**: External systems accessible via APIs
## Core Architecture
### Protocol Layer
- Handles message framing and communication patterns
- Manages request/response linking
- Key components:
- Protocol class
- Client interface
- Server implementation
### Transport Layer
1. **Stdio Transport**
- Uses standard input/output
- Ideal for local processes
2. **HTTP with SSE Transport**
- Server-Sent Events for server-to-client
- HTTP POST for client-to-server
- JSON-RPC 2.0 message format
### Message Types
```typescript
// Requests
interface Request {
method: string;
params?: { ... };
}
// Results
interface Result {
[key: string]: unknown;
}
// Errors
interface Error {
code: number;
message: string;
data?: unknown;
}
// Notifications
interface Notification {
method: string;
params?: { ... };
}
```
## Resources System
### Resource Types
1. **Text Resources**
- UTF-8 encoded text
- Source code, logs, configuration
- Plain text data
2. **Binary Resources**
- Base64 encoded data
- Images, PDFs, media files
- Non-text formats
### Resource URIs
```
[protocol]://[host]/[path]
Example: file:///home/user/documents/report.pdf
```
### Resource Discovery
```typescript
// Direct Resource
{
uri: string;
name: string;
description?: string;
mimeType?: string;
}
// Resource Template
{
uriTemplate: string;
name: string;
description?: string;
mimeType?: string;
}
```
## Prompt System
### Prompt Structure
```typescript
{
name: string;
description?: string;
arguments?: [
{
name: string;
description?: string;
required?: boolean;
}
]
}
```
### Dynamic Prompts
1. **Resource Context**
```json
{
"messages": [
{
"role": "user",
"content": {
"type": "resource",
"resource": {
"uri": "file:///path/to/code.py",
"text": "...",
"mimeType": "text/x-python"
}
}
}
]
}
```
2. **Workflow Steps**
```typescript
const workflow = {
name: "debug-workflow",
steps: [
{
role: "user",
content: "Initial query"
},
{
role: "assistant",
content: "Analysis step"
}
]
};
```
### Security Considerations
1. **Resource Security**
- URI validation
- Access control
- Path sanitization
- Rate limiting
2. **Prompt Security**
- Input validation
- Content sanitization
- Injection prevention
- Timeout handling
## Implementation
### Server Development
1. **Basic Server Setup**
```python
from mcp.server.fastmcp import FastMCP
# Initialize server
server = FastMCP("example-server")
# Configure server capabilities
server.configure(
capabilities={
'tools': {},
'sampling': {},
'roots': {}
}
)
# Start server
server.run(transport='stdio')
```
2. **Tool Implementation**
```python
@server.tool()
async def search_files(query: str, root: str = None) -> list:
"""Search for files matching query.
Args:
query: Search term
root: Optional root path to search in
"""
# Implementation
return matched_files
@server.tool()
async def analyze_code(file_path: str) -> dict:
"""Analyze code file and return metrics.
Args:
file_path: Path to code file
"""
# Implementation
return metrics
```
### Sampling Integration
```python
# Request LLM sampling
sampling_request = {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Analyze this code:"
}
},
{
"role": "user",
"content": {
"type": "text",
"text": code_content
}
}
],
"modelPreferences": {
"hints": [{"name": "claude-3"}],
"intelligencePriority": 0.8
},
"maxTokens": 500
}
response = await server.request_sampling(sampling_request)
```
### Root Management
```python
# Configure roots
roots = [
{
"uri": "file:///project/src",
"name": "Source Code"
},
{
"uri": "file:///project/docs",
"name": "Documentation"
}
]
# Register roots
server.set_roots(roots)
# Handle root changes
@server.on("roots_changed")
async def handle_roots_changed(new_roots):
# Update server state
pass
```
### Claude Desktop Configuration
```json
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/path/to/weather",
"run",
"weather.py"
]
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop",
"/Users/username/Downloads"
]
}
}
}
```
## Server Types & Capabilities
### 1. Resource Servers
- Provide file-like data access
- Handle API responses
- Manage file contents
### 2. Tool Servers
- Execute specific functions
- Require user approval
- Return structured data
### 3. Prompt Servers
- Manage template libraries
- Support workflow automation
- Handle context injection
## Integration Steps
1. **Server Setup**
- Install required SDKs (Python/TypeScript/Kotlin)
- Configure server endpoints
- Define tool implementations
2. **Client Configuration**
- Set up Claude Desktop
- Configure server connections
- Define access permissions
3. **Testing**
- Verify tool availability
- Test command execution
- Monitor server logs
## Troubleshooting
### Log Locations
- macOS: `~/Library/Logs/Claude/mcp*.log`
- Windows: `%APPDATA%\Claude\logs`
### Common Issues
1. **Server Connection**
- Verify configuration syntax
- Check absolute paths
- Restart Claude Desktop
2. **Tool Execution**
- Review server logs
- Verify implementation
- Check permissions
## Resources
- [Official Documentation](https://modelcontextprotocol.io/introduction)
- [GitHub Repository](https://github.com/modelcontextprotocol)
- [Specification](https://spec.modelcontextprotocol.io)
- [Python SDK](https://github.com/modelcontextprotocol/python-sdk)
- [TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
## Development with LLMs
### Preparation
1. Gather documentation:
- MCP full documentation
- SDK documentation (TypeScript/Python)
- Implementation examples
### Server Development Process
1. **Define Server Requirements**
```yaml
Server Specification Example:
- Resources to expose
- Tools to provide
- Required prompts
- External system integrations
```
2. **Core Implementation Steps**
- Start with basic functionality
- Iterate for additional features
- Test components individually
- Document implementation details
### Best Practices
1. **Architecture**
- Break down complex functionality
- Validate all inputs
- Implement proper error handling
- Follow MCP specifications
2. **Security**
- Limit access appropriately
- Validate user permissions
- Secure external connections
- Log security events
3. **Testing**
- Use MCP Inspector tool
- Test with Claude Desktop
- Validate edge cases
- Monitor performance
### Example Implementation
```python
from mcp.server.fastmcp import FastMCP
class CustomMCPServer:
def __init__(self):
self.mcp = FastMCP("custom_server")
self.setup_tools()
self.setup_resources()
def setup_tools(self):
@self.mcp.tool()
async def custom_tool(param: str) -> str:
"""Custom tool implementation
Args:
param: Input parameter
"""
return f"Processed: {param}"
def setup_resources(self):
# Resource implementation
pass
def run(self):
self.mcp.run(transport='stdio')
if __name__ == "__main__":
server = CustomMCPServer()
server.run()
```