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, 2025 min read
Share:

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.

Word count: ~1450. 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)