Claude Tools

Custom MCP Servers: Extend Claude with External APIs and Tools

Supercharge Claude AI by building custom MCP servers to connect it with real-time APIs like weather or CRMs. This step-by-step guide delivers code examples for seamless integration.

A

Andrew Snyder

AI & Automation Editor

December 9, 20255 min read
Share:
Custom MCP Servers: Extend Claude with External APIs and Tools

Unlock Claude's Power with Custom MCP Servers

Model Context Protocol (MCP) servers are game-changers for extending Claude's capabilities beyond its native training data. By creating your own MCP server, you enable Claude to fetch real-time data from external sources—think weather updates, stock prices, or proprietary CRM data—directly within conversations or agents. This Claude-specific tool bridges the gap between static models and dynamic, real-world applications.

In this guide, we'll walk through 10 actionable steps to build, deploy, and integrate your custom MCP server. Whether you're a developer crafting AI agents or a business user automating workflows, these steps provide practical examples tailored to Claude's ecosystem.

Why Custom MCP Servers Matter for Claude Users

  • Real-Time Data Access: Claude can't natively query live APIs, but MCP servers act as intermediaries.
  • Claude Agent Enhancement: Power autonomous agents with tools for tasks like research or customer support.
  • Enterprise Security: Keep sensitive data on your servers, exposing only what's needed via Claude Code or API.
  • Scalability: Integrate with n8n, Zapier, or custom SDKs for workflows.
  • Cost Efficiency: Avoid bloated prompts; fetch data on-demand.

Compared to generic tool-calling in GPT or Gemini, MCP is optimized for Anthropic's models (Opus, Sonnet, Haiku), ensuring low-latency responses and precise context handling.

Prerequisites

Before diving in:

  • Python 3.10+ (for server implementation)
  • Familiarity with Claude API or Claude Code CLI
  • API keys for testing (e.g., OpenWeatherMap)
  • Docker (optional, for deployment)
  • Node.js (if using Claude Code for local dev)

Install dependencies:

pip install flask requests anthropic

Step 1: Understand the MCP Protocol Basics

MCP defines a simple HTTP/JSON protocol for Claude to interact with your server:

  • Endpoint: /mcp/tool/{tool_name} (POST for execution)
  • Request Schema:
    {
      "params": {"city": "London"},
      "context": "Previous conversation snippet"
    }
    
  • Response Schema:
    {
      "result": "Sunny, 22°C",
      "context_update": "Weather data fetched"
    }
    

Claude Code or agents discover tools via /mcp/discover, returning a tool manifest.

Step 2: Set Up Your MCP Server Skeleton

Create a Flask app as your MCP server base.

# mcp_server.py
from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/mcp/discover', methods=['GET'])
def discover_tools():
    return jsonify({
        "tools": [
            {"name": "get_weather", "description": "Fetch current weather", "params": ["city"]},
            {"name": "query_crm", "description": "Search CRM contacts", "params": ["query"]}
        ]
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

Run it: python mcp_server.py. Test with curl http://localhost:8000/mcp/discover.

Step 3: Implement Your First Tool – Weather API

Integrate OpenWeatherMap for real-time data.

import requests

@app.route('/mcp/tool/get_weather', methods=['POST'])
def get_weather():
    data = request.json
    city = data['params']['city']
    api_key = 'YOUR_OPENWEATHER_KEY'  # Secure this!
    url = f'https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric'
    response = requests.get(url)
    weather = response.json()
    return jsonify({
        'result': f"{weather['weather'][0]['description'].title()}, {weather['main']['temp']}°C",
        'context_update': f'Weather for {city} retrieved.'
    })

Pro Tip: Use environment variables for API keys: os.getenv('OPENWEATHER_KEY').

Step 4: Secure Your MCP Server

  • Authentication: Add API keys to requests.
    @app.before_request
    

def auth(): if request.headers.get('X-MCP-Key') != os.getenv('MCP_SECRET'): return jsonify({'error': 'Unauthorized'}), 401

- **CORS**: For browser-based Claude integrations.
```python
from flask_cors import CORS
CORS(app)
  • Rate Limiting: Use flask-limiter to prevent abuse.

Step 5: Integrate with Claude API

Use Anthropic's SDK to call your MCP server from Claude prompts.

import anthropic

client = anthropic.Anthropic(api_key='your_claude_key')
message = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Get weather",
        "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}}
    }],
    messages=[{"role": "user", "content": "What's the weather in NYC?"}],
    tool_choice="auto"
)
# Claude will output tool_use; execute via your MCP server

Parse tool_use blocks and POST to http://localhost:8000/mcp/tool/get_weather.

Step 6: Build a CRM Integration Example

Connect to a mock/internal CRM (e.g., HubSpot API).

@app.route('/mcp/tool/query_crm', methods=['POST'])
def query_crm():
    data = request.json
    query = data['params']['query']
    # Simulate CRM query
    contacts = [
        {'name': 'John Doe', 'email': 'john@company.com'}  # Replace with real API call
    ]
    matches = [c for c in contacts if query.lower() in c['name'].lower()]
    return jsonify({
        'result': f"Found {len(matches)} contacts: {', '.join([c['name'] for c in matches])}",
        'context_update': 'CRM search complete.'
    })

For real CRMs: Swap with hubspot-python or similar.

Step 7: Deploy with Docker

Containerize for production.

# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "mcp_server.py"]

Build and run: docker build -t mcp-server . && docker run -p 8000:8000 -e MCP_SECRET=yourkey mcp-server.

Step 8: Connect via Claude Code CLI

For local dev, use Claude Code:

claude-code --mcp-server http://localhost:8000

This auto-discovers tools and injects them into your coding sessions.

Step 9: Advanced: Multi-Tool Agents

Chain tools in Claude agents.

  • Define agent loop: Claude decides tools sequentially.
  • Example Prompt:
    You are a sales agent. Use get_weather for location insights, then query_crm for leads.
    
  • Handle state with context_update for multi-turn memory.

Step 10: Monitor, Scale, and Optimize

  • Logging: Add logging module for requests.
  • Scaling: Deploy to AWS Lambda or Vercel with serverless Flask.
  • Metrics: Track tool calls with Prometheus.
  • Claude-Specific Tweaks: Optimize for Haiku (low latency) vs. Opus (complex reasoning).

Real-World Use Cases

  1. Marketing: Weather-triggered campaigns via Claude agents.
  2. Engineering: GitHub API tools for code reviews in Claude Code.
  3. HR: Internal directory searches.
  4. Sales: Real-time pricing from CRMs.
  5. Legal: Document retrieval from secure vaults.

Best Practices and Troubleshooting

  • Prompt Engineering: Always describe tools precisely in Claude prompts.
  • Error Handling: Return structured errors in MCP responses.
  • Common Issues:
    • Tool not discovered? Check /mcp/discover.
    • Latency? Use async Flask with asyncio.
    • Security? Never expose raw API keys to Claude.

Conclusion

Custom MCP servers transform Claude from a conversational AI into a powerhouse agent platform. Start with the weather example, scale to your CRM, and integrate into workflows with n8n or Slack. Experiment with Opus for advanced reasoning—your agents will thank you.

. Share your MCP builds in the comments!

The #1 Newsletter in AI

Stay ahead of the AI curve

The most important updates, news, and content — delivered in one weekly newsletter.

No spam. Unsubscribe anytime. Privacy policy

MCP Servers
Claude Agents
Custom Tools
Claude AI
API Extensions
ai-agents
A

About Andrew Snyder

AI & Automation Editor

Andrew covers practical AI automation, workflow design, and the tools teams use to streamline everyday operations.

Comments (0)