MCP

Aksshay88/MCP

3.2

If you are the rightful owner of MCP and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This documentation provides a comprehensive guide to implementing a Model Context Protocol (MCP) server for calculator operations using both STDIO and SSE/HTTP transport mechanisms.

Tools
4
Resources
0
Prompts
0

MCP Calculator - Technical Documentation

A comprehensive implementation of the Model Context Protocol (MCP) demonstrating both STDIO (local process communication) and SSE/HTTP (network communication) transport mechanisms for AI assistant integration.

Overview

This repository contains two parallel implementations of a calculator MCP server that exposes arithmetic operations as tools for AI assistants like Claude. The implementations showcase different transport protocols while maintaining identical functionality.

Architecture

Transport Protocols

STDIO (Standard Input/Output)
  • Location: STDIO/fastmcp_calculator.py
  • Protocol: Local process communication via stdin/stdout
  • Use Case: Direct integration with local AI clients (Claude Desktop, IDEs)
  • Connection: IPC through standard streams
  • Lifecycle: Process-based, spawned by host application
SSE (Server-Sent Events) over HTTP
  • Location: SSE/fastapi-mcp_calculator.py
  • Protocol: HTTP-based with SSE for real-time updates
  • Use Case: Network-accessible MCP server, remote integrations
  • Connection: HTTP endpoints at http://localhost:8002
  • Lifecycle: Long-running web server process

Technical Implementation

STDIO Implementation

# STDIO/fastmcp_calculator.py
from fastmcp import FastMCP
mcp = FastMCP(name="Calculator")

Key Characteristics:

  • Uses FastMCP library for simplified MCP protocol implementation
  • Runs in blocking mode with mcp.run() - listens on stdin/stdout
  • Communication is synchronous and bidirectional through pipes
  • No network stack required
  • Automatic serialization/deserialization of JSON-RPC messages
  • Process is spawned and managed by the MCP host (e.g., Claude Desktop)

Message Flow:

Host Application (Claude Desktop)
    ↓ spawn process
Calculator MCP Server
    ↓ JSON-RPC via stdin
[Tool Request: add(5, 3)]
    ↓ stdout
[Tool Response: {"result": 8}]

SSE/HTTP Implementation

# SSE/fastapi-mcp_calculator.py
from fastapi import FastAPI
from fastapi_mcp import FastApiMCP

app = FastAPI(title="Calculator API")
mcp = FastApiMCP(app, name="Calculator MCP")
mcp.mount_http()

Key Characteristics:

  • Built on FastAPI for robust HTTP server capabilities
  • FastApiMCP wraps FastAPI endpoints as MCP tools
  • Exposes both standard REST API and MCP-compatible endpoints
  • Supports CORS for cross-origin requests
  • Server-Sent Events for streaming responses
  • Runs with Uvicorn ASGI server on port 8002
  • Supports concurrent connections from multiple clients

Message Flow:

HTTP Client/MCP Host
    ↓ HTTP POST
http://localhost:8002/multiply
    ↓ JSON payload
{"a": 5, "b": 3}
    ↓ HTTP Response
{"result": 15}

MCP Endpoint Structure:

POST /mcp/v1/tools/list    - List available tools
POST /mcp/v1/tools/call    - Execute a tool
GET  /mcp/v1/sse           - SSE endpoint for streaming

Tool Implementations

Both implementations expose identical calculator operations:

1. Addition (add)

  • Function: add_numbers(x: float, y: float) -> float
  • Description: Adds two numbers
  • Tags: math, arithmetic (STDIO only)
  • Returns: Sum of x and y

2. Multiplication (multiply)

  • Function: multiply(a: float, b: float) -> float
  • Description: Multiplies two numbers
  • Returns: Product of a and b

3. Subtraction (subtract)

  • Function: subtract(a: float, b: float) -> float
  • Description: Subtracts b from a
  • Returns: Difference (a - b)

4. Division (divide)

  • Function: divide(a: float, b: float) -> float
  • Description: Divides a by b
  • Error Handling:
    • STDIO: Raises ValueError for division by zero
    • SSE: Returns {"error": "Division by zero is not allowed."}
  • Returns: Quotient (a / b)

Protocol Comparison

FeatureSTDIOSSE/HTTP
Transportstdin/stdout pipesHTTP/1.1 + SSE
NetworkLocal onlyNetwork accessible
ConcurrencySingle clientMultiple clients
SecurityProcess isolationNetwork authentication required
Latency~1-5ms~10-50ms (network overhead)
DiscoveryProcess spawnHTTP service discovery
State ManagementProcess memoryServer memory + sessions
Error HandlingPython exceptionsHTTP status codes + JSON errors
DebuggingProcess logs, stderrHTTP logs, request tracing

Setup and Installation

Prerequisites

Python 3.8+
pip package manager

STDIO Setup

cd STDIO
python -m venv meraenv
source meraenv/bin/activate  # On Windows: meraenv\Scripts\activate
pip install fastmcp
python fastmcp_calculator.py

SSE/HTTP Setup

cd SSE
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install fastapi fastapi-mcp uvicorn
python fastapi-mcp_calculator.py

Integration Examples

Claude Desktop Configuration (STDIO)

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "calculator": {
      "command": "python",
      "args": ["/absolute/path/to/STDIO/fastmcp_calculator.py"],
      "env": {}
    }
  }
}

HTTP Client Integration (SSE)

import requests

# Direct API call
response = requests.post(
    "http://localhost:8002/add",
    json={"a": 10, "b": 20}
)
print(response.json())  # {"result": 30}

# MCP protocol call
response = requests.post(
    "http://localhost:8002/mcp/v1/tools/call",
    json={
        "tool": "add",
        "arguments": {"a": 10, "b": 20}
    }
)

TypeScript/JavaScript Client

// SSE connection for streaming
const eventSource = new EventSource('http://localhost:8002/mcp/v1/sse');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

// Tool invocation
const response = await fetch('http://localhost:8002/mcp/v1/tools/call', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    tool: 'multiply',
    arguments: { a: 7, b: 6 }
  })
});

Protocol Deep Dive

MCP Message Structure

Tool List Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {}
}

Tool List Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "add",
        "description": "Add two numbers.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "x": {"type": "number"},
            "y": {"type": "number"}
          },
          "required": ["x", "y"]
        }
      }
    ]
  }
}

Tool Call Request:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "add",
    "arguments": {
      "x": 5,
      "y": 3
    }
  }
}

Tool Call Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "8"
      }
    ]
  }
}

Performance Considerations

STDIO

  • Pros: Minimal overhead, no serialization beyond JSON-RPC, direct memory access
  • Cons: Single client limitation, process spawning overhead (~50-100ms)
  • Best For: Desktop applications, local AI assistants, development environments

SSE/HTTP

  • Pros: Scalable, multiple concurrent clients, RESTful interface, service discovery
  • Cons: Network latency, HTTP overhead, requires port management
  • Best For: Production deployments, cloud services, distributed systems, microservices

Security Considerations

STDIO

  • Runs with same permissions as host process
  • No network exposure
  • Trust boundary at process execution
  • Recommend: Validate host process identity

SSE/HTTP

  • Exposed on network interface
  • Requires authentication/authorization layer (not implemented in example)
  • Vulnerable to network attacks without TLS
  • Recommend: Add JWT authentication, implement HTTPS, use rate limiting

Debugging and Troubleshooting

STDIO Debug Mode

# Enable stderr logging
python fastmcp_calculator.py 2> debug.log

# Monitor JSON-RPC messages
strace -e read,write -s 1000 python fastmcp_calculator.py

HTTP Debug Mode

# Enable FastAPI debug mode
uvicorn.run(app, host="localhost", port=8002, log_level="debug")

# Test with curl
curl -X POST http://localhost:8002/add \
  -H "Content-Type: application/json" \
  -d '{"a": 5, "b": 3}'

Common Issues

STDIO:

  • Process not spawning: Check Python path in config
  • No response: Verify stdin/stdout not blocked by other output
  • Encoding errors: Ensure UTF-8 encoding on both sides

HTTP:

  • Port in use: Change port or kill existing process
  • Connection refused: Verify server is running with lsof -i :8002
  • CORS errors: Add CORS middleware for browser clients

Extending the Implementation

Adding New Tools (STDIO)

@mcp.tool(
    name="power",
    description="Raise a number to a power",
    tags={"math", "advanced"}
)
def power(base: float, exponent: float) -> float:
    """Calculate base^exponent"""
    return base ** exponent

Adding New Endpoints (HTTP)

@app.post("/power")
def power_numbers(base: float, exponent: float):
    """Raise base to the power of exponent"""
    result = base ** exponent
    return {"result": result}

Testing

Unit Tests

# test_calculator.py
def test_add():
    assert add_numbers(5, 3) == 8

def test_divide_by_zero():
    with pytest.raises(ValueError):
        divide(10, 0)

Integration Tests

# STDIO
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python fastmcp_calculator.py

# HTTP
pytest tests/test_http_endpoints.py

Dependencies

STDIO

  • fastmcp>=0.1.0 - FastMCP framework for simplified MCP implementation

SSE/HTTP

  • fastapi>=0.100.0 - Modern Python web framework
  • fastapi-mcp>=0.1.0 - FastAPI-MCP integration bridge
  • uvicorn>=0.23.0 - ASGI server for FastAPI
  • python-multipart>=0.0.6 - Form data parsing
  • sse-starlette>=1.6.0 - Server-Sent Events support (implicit)

License

This project is released into the public domain under The Unlicense. See LICENSE file for details.

Future Enhancements

  • Add WebSocket transport option for bidirectional streaming
  • Implement authentication/authorization for HTTP version
  • Add request/response validation with Pydantic models
  • Create Docker containers for both implementations
  • Add OpenTelemetry instrumentation for observability
  • Implement tool result caching
  • Add rate limiting and quota management
  • Support for batch tool invocations
  • Add health check and metrics endpoints

References


Repository Structure:

MCP/
├── LICENSE              # Public domain license
├── README.md           # This file
├── STDIO/              # Local process communication
│   ├── fastmcp_calculator.py
│   └── meraenv/        # Virtual environment
└── SSE/                # HTTP/SSE network communication
    └── fastapi-mcp_calculator.py

For questions, issues, or contributions, please refer to the repository documentation or create an issue.