mcp-integration-expert
Expert guidance for researching, documenting, and integrating Model Context Protocol (MCP) servers and tools. Covers MCP architecture, server/client implementation patterns, tool discovery, integration workflows, security best practices, and multi-language SDK usage (Python, TypeScript, C#, Java, Rust). Enables seamless integration of MCP tools into Claude Code and AI applications.
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- Updated: 2025-11-22
Download the latest version (v1.0.0) from this page.
SKILL.md
---
name: mcp-integration-expert
description: Expert guidance for researching, documenting, and integrating Model Context Protocol (MCP) servers and tools. Covers MCP architecture, server/client implementation patterns, tool discovery, integration workflows, security best practices, and multi-language SDK usage (Python, TypeScript, C#, Java, Rust). Enables seamless integration of MCP tools into Claude Code and AI applications.
---
# MCP Integration Expert
Comprehensive skill for researching, documenting, and integrating Model Context Protocol (MCP) servers and tools into Claude Code and AI applications.
## When to Use This Skill
Use this skill when you need to:
- Research and evaluate MCP servers for integration
- Build custom MCP servers or clients
- Integrate existing MCP tools into Claude Code
- Document MCP server capabilities and usage patterns
- Troubleshoot MCP integration issues
- Implement MCP security and authentication patterns
- Create multi-language MCP implementations (Python, TypeScript, C#, Java, Rust)
- Design MCP-based AI agent workflows
- Evaluate MCP server trust scores and documentation quality
## Model Context Protocol (MCP) Overview
### What is MCP?
The **Model Context Protocol (MCP)** is an open standard introduced by Anthropic in November 2024 that standardizes how AI applications and Large Language Models (LLMs) integrate with external data sources, tools, and systems.
**Key Analogy**: MCP is like a "USB-C port for AI" - providing a universal, standardized interface for connecting AI models to diverse data sources and tools.
### Core Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ MCP Client │
│ (AI Application) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Claude │ │ ChatGPT │ │ Custom │ │
│ │ Code │ │ Desktop │ │ App │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ MCP Protocol
│
┌─────────────────────────────────────────────────────────────┐
│ MCP Servers │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Linear │ │ Postgres │ │ GitHub │ │ Custom │ │
│ │ Server │ │ Server │ │ Server │ │ Server │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### MCP Protocol Communication Flow
```mermaid
sequenceDiagram
autonumber
actor User as 👤 User
participant ClientApp as 🖥️ Client App
participant ClientLLM as 🧠 Client LLM
participant Server1 as 🔧 MCP Server 1
participant Server2 as 📚 MCP Server 2
%% Discovery Phase
rect rgb(220, 240, 255)
Note over ClientApp, Server2: TOOL DISCOVERY PHASE
ClientApp->>+Server1: Request available tools/resources
Server1-->>-ClientApp: Return tool list (JSON)
ClientApp->>+Server2: Request available tools/resources
Server2-->>-ClientApp: Return tool list (JSON)
Note right of ClientApp: Store combined tool<br/>catalog locally
end
%% User Interaction
rect rgb(255, 240, 220)
Note over User, ClientLLM: USER INTERACTION PHASE
User->>+ClientApp: Enter natural language prompt
ClientApp->>+ClientLLM: Forward prompt + tool catalog
ClientLLM->>-ClientLLM: Analyze prompt & select tools
end
%% Tool Execution
rect rgb(220, 255, 220)
Note over ClientApp, Server1: TOOL EXECUTION PHASE
ClientLLM->>+ClientApp: Request tool execution
ClientApp->>+Server1: Execute specific tool
Server1-->>-ClientApp: Return results
ClientApp->>+ClientLLM: Process results
ClientLLM-->>-ClientApp: Generate response
ClientApp-->>-User: Display final answer
end
```
### MCP Core Primitives
MCP provides three core primitives for context exchange:
1. **Resources**: Expose data sources (files, databases, APIs)
2. **Tools**: Enable actions and operations
3. **Prompts**: Provide reusable prompt templates
## MCP Integration Workflow
### Phase 1: Research & Discovery
#### 1.1 Identify MCP Server Needs
Questions to ask:
- What data sources do you need to access?
- What actions/tools do you need to perform?
- Are there existing MCP servers for your use case?
- Do you need to build a custom MCP server?
#### 1.2 Research Available MCP Servers
**Official MCP Server Repository**: https://github.com/modelcontextprotocol
**Popular MCP Servers (2025)**:
- **Linear MCP**: Project management and issue tracking
- **Playwright MCP**: Browser automation and testing
- **Context7 MCP**: Library documentation retrieval
- **GitHub MCP**: Repository management and automation
- **Postgres MCP**: Database queries and operations
- **Google Drive MCP**: File storage and retrieval
- **Slack MCP**: Team communication
- **Stripe MCP**: Payment processing
- **Puppeteer MCP**: Web scraping and automation
#### 1.3 Evaluate MCP Server Quality
**Trust Score Criteria** (1-10 scale):
- **9-10**: Highly authoritative (official SDKs, major platforms)
- **7-9**: Well-maintained community projects
- **5-7**: Experimental or niche implementations
- **<5**: Proof-of-concept or unmaintained
**Documentation Coverage**:
- **High**: 500+ code snippets
- **Medium**: 100-500 code snippets
- **Low**: <100 code snippets
### Phase 2: MCP Server Architecture
#### 2.1 MCP Server Components
```typescript
// TypeScript MCP Server Structure
import { FastMCP } from '@modelcontextprotocol/typescript-sdk';
const mcp = new FastMCP({
name: "My MCP Server",
version: "1.0.0"
});
// 1. Resources: Expose data
mcp.resource("greeting://{name}", (name: string) => {
return `Hello, ${name}!`;
});
// 2. Tools: Enable actions
mcp.tool("calculate", {
description: "Perform calculations",
parameters: {
operation: { type: "string" },
a: { type: "number" },
b: { type: "number" }
}
}, async (params) => {
// Tool implementation
});
// 3. Prompts: Reusable templates
mcp.prompt("code-review", {
description: "Code review template",
arguments: ["language", "code"]
});
```
#### 2.2 Transport Mechanisms
MCP supports multiple transport mechanisms:
**1. Stdio Transport** (Default for local servers)
```python
from mcp.server.fastmcp import FastMCP
from mcp.transports.stdio import serve_stdio
mcp = FastMCP("Demo")
# Run with stdio
asyncio.run(serve_stdio(mcp))
```
**2. HTTP/SSE Transport** (For remote servers)
```typescript
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/typescript-sdk';
const transport = new StreamableHTTPServerTransport(8000);
await server.connect(transport);
```
### Phase 3: MCP Client Integration
#### 3.1 Client Setup (Python)
```python
from mcp.client import stdio_client, ClientSession
async def run_client():
server_params = {
"command": "python",
"args": ["server.py"]
}
async with stdio_client(server_params) as (reader, writer):
async with ClientSession(reader, writer) as session:
# Initialize connection
await session.initialize()
# Discover tools
tools = await session.list_tools()
# Call a tool
result = await session.call_tool("add", arguments={"a": 5, "b": 7})
print(f"Result: {result}")
```
#### 3.2 Client Setup (TypeScript)
```typescript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
class MCPClient {
private client: Client;
constructor() {
this.client = new Client({
name: "example-client",
version: "1.0.0"
}, {
capabilities: {
prompts: {},
resources: {},
tools: {}
}
});
}
async connectToServer(transport: Transport) {
await this.client.connect(transport);
}
async listTools() {
return await this.client.listTools();
}
async callTool(name: string, args: any) {
return await this.client.callTool({
name: name,
arguments: args
});
}
}
```
#### 3.3 Client Setup (C#)
```csharp
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
var clientTransport = new StdioClientTransport(new()
{
Name = "Demo Server",
Command = "/path/to/server/executable",
Arguments = [],
});
await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
// List tools
var tools = await mcpClient.ListToolsAsync();
foreach (var tool in tools)
{
Console.WriteLine(quot;Tool: {tool.Name}");
Console.WriteLine(quot;Description: {tool.Description}");
}
// Call a tool
var result = await mcpClient.CallToolAsync("add", new { a = 5, b = 7 });
```
### Phase 4: Building Custom MCP Servers
#### 4.1 Python MCP Server (FastMCP)
```python
from fastmcp import FastMCP
from fastmcp.transports.stdio import serve_stdio
import asyncio
mcp = FastMCP(
name="Weather MCP Server",
version="1.0.0"
)
@mcp.tool()
def get_weather(location: str) -> dict:
"""Gets current weather for a location."""
# Implementation would call weather API
return {
"temperature": 72.5,
"conditions": "Sunny",
"location": location
}
@mcp.resource("weather://{location}")
def weather_resource(location: str) -> str:
"""Get weather data as a resource"""
return f"Current weather in {location}"
class WeatherTools:
@mcp.tool()
def forecast(self, location: str, days: int = 1) -> dict:
"""Gets weather forecast"""
return {
"location": location,
"forecast": [
{"day": i+1, "temperature": 70 + i, "conditions": "Partly Cloudy"}
for i in range(days)
]
}
weather_tools = WeatherTools()
if __name__ == "__main__":
asyncio.run(serve_stdio(mcp))
```
#### 4.2 TypeScript MCP Server
```typescript
import { FastMCP } from '@modelcontextprotocol/typescript-sdk';
import { serve_stdio } from '@modelcontextprotocol/typescript-sdk/transports/stdio';
const mcp = new FastMCP({
name: "Weather MCP Server",
version: "1.0.0"
});
mcp.tool("get_weather", {
description: "Gets current weather for a location",
parameters: {
location: { type: "string", required: true }
}
}, async (params) => {
return {
temperature: 72.5,
conditions: "Sunny",
location: params.location
};
});
mcp.resource("weather://{location}", async (location: string) => {
return `Current weather in ${location}`;
});
// Start server
serve_stdio(mcp);
```
#### 4.3 Java MCP Server
```java
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpToolDefinition;
import io.modelcontextprotocol.server.transport.StdioServerTransport;
public class WeatherMcpServer {
public static void main(String[] args) throws Exception {
McpServer server = McpServer.builder()
.name("Weather MCP Server")
.version("1.0.0")
.build();
server.registerTool(McpToolDefinition.builder("weatherTool")
.description("Gets current weather for a location")
.parameter("location", String.class)
.execute((ctx) -> {
String location = ctx.getParameter("location", String.class);
WeatherData data = getWeatherData(location);
return ToolResponse.content(
String.format("Temperature: %.1f°F, Conditions: %s",
data.getTemperature(),
data.getConditions())
);
})
.build());
try (StdioServerTransport transport = new StdioServerTransport()) {
server.connect(transport);
Thread.currentThread().join();
}
}
}
```
### Phase 5: LLM Integration Patterns
#### 5.1 Integrating MCP with OpenAI
```typescript
import OpenAI from "openai";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
class MCPOpenAIClient {
private openai: OpenAI;
private mcpClient: Client;
constructor() {
this.openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
this.mcpClient = new Client({
name: "openai-mcp-client",
version: "1.0.0"
}, {
capabilities: { tools: {} }
});
}
// Adapt MCP tools to OpenAI format
mcpToolToOpenAITool(tool: any) {
return {
type: "function" as const,
function: {
name: tool.name,
description: tool.description,
parameters: {
type: "object",
properties: tool.input_schema.properties,
required: tool.input_schema.required,
},
},
};
}
async processRequest(userMessage: string) {
// Get MCP tools
const mcpTools = await this.mcpClient.listTools();
const openaiTools = mcpTools.map(t => this.mcpToolToOpenAITool(t));
// Call OpenAI with tools
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: userMessage }],
tools: openaiTools,
});
// Handle tool calls
const toolCalls = response.choices[0].message.tool_calls;
if (toolCalls) {
for (const toolCall of toolCalls) {
const result = await this.mcpClient.callTool({
name: toolCall.function.name,
arguments: JSON.parse(toolCall.function.arguments),
});
console.log("Tool result:", result);
}
}
}
}
```
#### 5.2 Integrating MCP with Azure OpenAI (C#)
```csharp
using Azure.AI.Inference;
using Azure;
using ModelContextProtocol.Client;
using System.Text.Json;
var endpoint = "https://models.inference.ai.azure.com";
var token = Environment.GetEnvironmentVariable("GITHUB_TOKEN");
var client = new ChatCompletionsClient(new Uri(endpoint), new AzureKeyCredential(token));
var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
// Convert MCP tools to Azure format
ChatCompletionsToolDefinition ConvertFrom(string name, string description, JsonElement schema)
{
FunctionDefinition functionDefinition = new FunctionDefinition(name)
{
Description = description,
Parameters = BinaryData.FromObjectAsJson(new
{
Type = "object",
Properties = schema
})
};
return new ChatCompletionsToolDefinition(functionDefinition);
}
// Get tools from MCP server
var mcpTools = await mcpClient.ListToolsAsync();
var toolDefinitions = new List<ChatCompletionsToolDefinition>();
foreach (var tool in mcpTools)
{
JsonElement propertiesElement;
tool.JsonSchema.TryGetProperty("properties", out propertiesElement);
var def = ConvertFrom(tool.Name, tool.Description, propertiesElement);
toolDefinitions.Add(def);
}
// Use tools in chat completion
var chatHistory = new List<ChatRequestMessage>
{
new ChatRequestSystemMessage("You are a helpful assistant"),
new ChatRequestUserMessage("What's the weather in Seattle?")
};
var response = await client.CompleteAsync(chatHistory,
new ChatCompletionsOptions { Tools = toolDefinitions });
```
### Phase 6: MCP Configuration in Claude Code
#### 6.1 Claude Code MCP Configuration
Claude Code automatically discovers and loads MCP servers configured in `claude_desktop_config.json`:
**Location**:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
**Configuration Format**:
```json
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp-server"],
"env": {
"LINEAR_API_KEY": "your-api-key"
}
},
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp-server"]
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "postgresql://user:pass@localhost/db"
}
},
"custom-server": {
"command": "python",
"args": ["/path/to/custom/server.py"]
}
}
}
```
#### 6.2 Verify MCP Server Connection
Once configured, MCP servers automatically connect when Claude Code starts.
**Available MCP tools in Claude Code**:
```typescript
// All MCP tools are prefixed with "mcp__<server-name>__<tool-name>"
mcp__linear__create_issue
mcp__linear__list_issues
mcp__linear__update_issue
mcp__playwright__browser_navigate
mcp__playwright__browser_screenshot
mcp__context7__resolve_library_id
mcp__context7__get_library_docs
```
### Phase 7: Security & Best Practices
#### 7.1 Security Considerations (2025 Update)
**Known Security Issues** (April 2025):
- **Prompt Injection**: MCP tools can be exploited via prompt injection attacks
- **Tool Permissions**: Combining tools can enable unintended file exfiltration
- **Lookalike Tools**: Malicious tools can silently replace trusted ones
- **Credential Exposure**: API keys and credentials must be protected
**Security Best Practices**:
1. **Validate Tool Inputs**
```python
@mcp.tool()
def read_file(filepath: str) -> str:
"""Read a file - with security validation"""
# Validate filepath to prevent path traversal
import os
filepath = os.path.normpath(filepath)
# Ensure within allowed directory
allowed_dir = "/home/user/documents"
if not filepath.startswith(allowed_dir):
raise ValueError("Access denied: Path outside allowed directory")
with open(filepath, 'r') as f:
return f.read()
```
2. **Implement Authentication**
```python
from fastmcp import FastMCP
import os
mcp = FastMCP("Secure Server", version="1.0.0")
@mcp.middleware
async def authenticate(request, call_next):
api_key = request.headers.get("X-API-Key")
expected_key = os.getenv("MCP_API_KEY")
if api_key != expected_key:
raise PermissionError("Invalid API key")
return await call_next(request)
```
3. **Rate Limiting**
```python
from collections import defaultdict
import time
call_counts = defaultdict(list)
@mcp.middleware
async def rate_limit(request, call_next):
client_id = request.client_id
now = time.time()
# Clean old entries
call_counts[client_id] = [t for t in call_counts[client_id] if now - t < 60]
# Check rate limit (10 calls per minute)
if len(call_counts[client_id]) >= 10:
raise Exception("Rate limit exceeded")
call_counts[client_id].append(now)
return await call_next(request)
```
#### 7.2 Error Handling Best Practices
```python
from fastmcp import FastMCP
from typing import Optional
import logging
mcp = FastMCP("Robust Server", version="1.0.0")
logger = logging.getLogger(__name__)
@mcp.tool()
def safe_api_call(endpoint: str, params: Optional[dict] = None) -> dict:
"""Make an API call with comprehensive error handling"""
try:
# Validate inputs
if not endpoint.startswith("https://"):
raise ValueError("Only HTTPS endpoints allowed")
# Make API call
response = requests.get(endpoint, params=params, timeout=5)
response.raise_for_sta