--- 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
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($"Tool: {tool.Name}"); Console.WriteLine($"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(); 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 { 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____" 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_status() return { "success": True, "data": response.json() } except requests.Timeout: logger.error(f"Timeout calling {endpoint}") return { "success": False, "error": "Request timeout", "error_type": "timeout" } except requests.HTTPError as e: logger.error(f"HTTP error calling {endpoint}: {e}") return { "success": False, "error": str(e), "error_type": "http_error", "status_code": e.response.status_code } except Exception as e: logger.exception(f"Unexpected error calling {endpoint}") return { "success": False, "error": "Internal server error", "error_type": "internal_error" } ``` #### 7.3 Testing MCP Servers **Integration Testing (Python)**: ```python import pytest from mcp.server import McpServer from mcp.client import McpClient @pytest.mark.asyncio async def test_mcp_server_integration(): # Start test server server = McpServer() server.register_tool(WeatherForecastTool(MockWeatherService())) await server.start(port=5000) try: # Create client client = McpClient("http://localhost:5000") # Test tool discovery tools = await client.discover_tools() assert "weatherForecast" in [t.name for t in tools] # Test tool execution response = await client.execute_tool("weatherForecast", { "location": "Seattle", "days": 3 }) # Verify response assert response.status_code == 200 assert "Seattle" in response.content[0].text finally: await server.stop() ``` ### Phase 8: Advanced MCP Patterns #### 8.1 Chain of Tools Workflow ```python class ChainWorkflow: def __init__(self, tools_chain): self.tools_chain = tools_chain async def execute(self, mcp_client, initial_input): current_result = initial_input all_results = {"input": initial_input} for tool_name in self.tools_chain: response = await mcp_client.execute_tool(tool_name, current_result) all_results[tool_name] = response.result current_result = response.result return { "final_result": current_result, "all_results": all_results } # Usage data_pipeline = ChainWorkflow([ "dataFetch", "dataCleaner", "dataAnalyzer", "dataVisualizer" ]) result = await data_pipeline.execute( mcp_client, {"source": "sales_database", "table": "transactions"} ) ``` #### 8.2 Parallel Tool Execution ```typescript async function executeParallelTools(mcpClient: Client, tools: ToolCall[]) { const promises = tools.map(tool => mcpClient.callTool({ name: tool.name, arguments: tool.arguments }) ); const results = await Promise.all(promises); return results; } // Usage const toolCalls = [ { name: "get_weather", arguments: { location: "Seattle" } }, { name: "get_weather", arguments: { location: "Portland" } }, { name: "get_weather", arguments: { location: "Vancouver" } } ]; const weatherData = await executeParallelTools(mcpClient, toolCalls); ``` #### 8.3 Context-Aware Tool Selection ```python from typing import List, Dict import openai class ContextAwareToolSelector: def __init__(self, mcp_client, llm_client): self.mcp_client = mcp_client self.llm_client = llm_client async def select_tools(self, user_query: str, available_tools: List[Dict]) -> List[str]: """Use LLM to intelligently select which tools to use""" tool_descriptions = "\n".join([ f"- {tool['name']}: {tool['description']}" for tool in available_tools ]) prompt = f""" User query: {user_query} Available tools: {tool_descriptions} Select the most relevant tools to answer this query. Return a JSON array of tool names. """ response = await self.llm_client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) selected_tools = json.loads(response.choices[0].message.content) return selected_tools["tools"] ``` ## MCP Ecosystem (2025) ### Major Platform Adoptions **OpenAI** (March 2025): - MCP integrated into ChatGPT Desktop - MCP support in Agents SDK - MCP compatibility in Responses API **Google** (April 2025): - MCP support in Gemini models - Data Commons MCP Server (public datasets) - MCP integration in Google DeepMind infrastructure **Microsoft** (2025): - MCP in Copilot Studio (GA) - Semantic Kernel integration - Azure OpenAI compatibility **Anthropic**: - Native MCP support in Claude Code - Reference MCP server implementations - MCP specification maintenance ### Official MCP Servers Repository: https://github.com/modelcontextprotocol **Enterprise Integrations**: - Google Drive, Slack, GitHub, GitLab - Postgres, MySQL, MongoDB - AWS, Azure, GCP - Stripe, Salesforce **Development Tools**: - Puppeteer, Playwright - Docker, Kubernetes - Git, GitHub Actions ### MCP SDK Support (2025) **Official SDKs**: - Python: `pip install modelcontextprotocol` - TypeScript: `npm install @modelcontextprotocol/sdk` - C#: NuGet package - Java: Maven/Gradle - Rust: Cargo package - Swift: Swift Package Manager ## Documentation Research Workflow ### Using Context7 for MCP Research When researching MCP servers and integration patterns: ```bash # 1. Resolve library ID /ctx7 model context protocol # 2. Get comprehensive documentation # Context7 returns documentation with: # - Trust Score (7-10 for quality sources) # - Code Snippets (100-5000+) # - Implementation examples # - Best practices # 3. Evaluate quality # - Trust Score 9-10: Official documentation # - Trust Score 7-9: Well-maintained projects # - Code Snippets 500+: Comprehensive coverage ``` **Best Context7 Sources for MCP** (by Trust Score): 1. `/microsoft/mcp-for-beginners` (Trust: 9.9, Snippets: 30,945) 2. `/modelcontextprotocol/python-sdk` (Trust: 7.8, Snippets: 119) 3. `/modelcontextprotocol/typescript-sdk` (Trust: 7.8, Snippets: 55) 4. `/modelcontextprotocol/csharp-sdk` (Trust: 7.8, Snippets: 59) ## Common MCP Integration Patterns ### Pattern 1: Simple Tool Integration **Use Case**: Add a single MCP tool to Claude Code ```json // claude_desktop_config.json { "mcpServers": { "weather": { "command": "python", "args": ["weather_server.py"] } } } ``` ```python # weather_server.py from fastmcp import FastMCP from fastmcp.transports.stdio import serve_stdio import asyncio mcp = FastMCP("Weather", version="1.0.0") @mcp.tool() def get_weather(location: str) -> str: return f"Weather in {location}: Sunny, 72°F" asyncio.run(serve_stdio(mcp)) ``` ### Pattern 2: Multi-Server Integration **Use Case**: Combine multiple MCP servers for complex workflows ```json { "mcpServers": { "linear": { "command": "npx", "args": ["-y", "@linear/mcp-server"], "env": { "LINEAR_API_KEY": "..." } }, "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "..." } }, "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp-server"] } } } ``` ### Pattern 3: Custom Resource Server **Use Case**: Expose internal documentation or data ```python from fastmcp import FastMCP from fastmcp.transports.stdio import serve_stdio import asyncio import os mcp = FastMCP("Internal Docs", version="1.0.0") @mcp.resource("docs://{path}") def get_documentation(path: str) -> str: """Get internal documentation by path""" docs_dir = "/company/docs" filepath = os.path.join(docs_dir, path) if not os.path.exists(filepath): return f"Documentation not found: {path}" with open(filepath, 'r') as f: return f.read() @mcp.tool() def search_docs(query: str) -> list: """Search internal documentation""" # Implementation would use search index return [ {"title": "Getting Started", "path": "onboarding/getting-started.md"}, {"title": "API Reference", "path": "api/reference.md"} ] asyncio.run(serve_stdio(mcp)) ``` ## Troubleshooting MCP Integration ### Issue 1: MCP Server Not Connecting **Symptoms**: Tools not appearing in Claude Code **Solutions**: 1. Check configuration file location 2. Verify command and args are correct 3. Test server independently: `python server.py` 4. Check logs in Claude Code 5. Ensure environment variables are set ### Issue 2: Tool Execution Failures **Symptoms**: Tool calls return errors **Solutions**: 1. Validate tool parameter schemas 2. Add error handling in tool implementation 3. Check server logs for exceptions 4. Test with simple inputs first 5. Verify authentication/API keys ### Issue 3: Performance Issues **Symptoms**: Slow tool responses **Solutions**: 1. Add caching for repeated calls 2. Implement connection pooling 3. Use async/await properly 4. Add timeout handling 5. Consider HTTP transport for remote servers ## Best Practices Summary 1. **Start Simple**: Begin with a single tool, expand gradually 2. **Use Official SDKs**: Leverage maintained libraries (Python, TypeScript, C#, Java) 3. **Implement Security**: Validate inputs, authenticate, rate limit 4. **Handle Errors Gracefully**: Return structured error responses 5. **Document Thoroughly**: Provide clear tool descriptions and parameter schemas 6. **Test Extensively**: Write integration tests for all tools 7. **Monitor Performance**: Track response times and error rates 8. **Version Your Servers**: Use semantic versioning for changes 9. **Leverage Context7**: Research documentation before implementation 10. **Follow MCP Specification**: Adhere to official protocol standards ## Quick Reference ### MCP Server Checklist - [ ] Server name and version defined - [ ] Tools have clear descriptions - [ ] Parameter schemas are complete - [ ] Error handling implemented - [ ] Authentication/authorization configured - [ ] Logging enabled - [ ] Tests written - [ ] Documentation created - [ ] Security validated - [ ] Performance tested ### Essential Commands ```bash # Install MCP SDKs pip install modelcontextprotocol npm install @modelcontextprotocol/sdk # Test server independently python server.py # Verify Claude Code config cat ~/Library/Application\ Support/Claude/claude_desktop_config.json # Research with Context7 /ctx7 [library-name] ``` ### Resources **Official Documentation**: - MCP Specification: https://modelcontextprotocol.io/specification - MCP GitHub: https://github.com/modelcontextprotocol - MCP Servers: https://github.com/modelcontextprotocol (servers directory) **SDKs**: - Python SDK: https://github.com/modelcontextprotocol/python-sdk - TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk - C# SDK: https://github.com/modelcontextprotocol/csharp-sdk - Java SDK: https://github.com/modelcontextprotocol/java-sdk **Learning Resources**: - Microsoft MCP for Beginners: https://github.com/microsoft/mcp-for-beginners - Anthropic MCP Announcement: https://www.anthropic.com/news/model-context-protocol --- **Skill Version**: 1.0.0 **Last Updated**: 2025-10-18 **Context7 Research**: Microsoft MCP for Beginners (Trust: 9.9)