A Python utility package for building Model Context Protocol (MCP) servers.
- mcp-utils
mcp-utils provides utilities and helpers for building MCP-compliant servers in Python, with a focus on synchronous implementations using Flask. This package is designed for developers who want to implement MCP servers in their existing Python applications without the complexity of asynchronous code.
- Basic utilities for MCP server implementation
- Server-Sent Events (SSE) support
- Simple decorators for MCP endpoints
- Synchronous implementation
- HTTP protocol support
- Redis response queue
- Comprehensive Pydantic models for MCP schema
- Built-in validation and documentation
pip install mcp-utils- Python 3.10+
- Pydantic 2
- Flask (for web server)
- Gunicorn (for production deployment)
- Redis (for response queue)
Here's a simple example of creating an MCP server:
from mcp_utils.core import MCPServer
from mcp_utils.schema import GetPromptResult, Message, TextContent, CallToolResult
# Create a basic MCP server
mcp = MCPServer("example", "1.0")
@mcp.prompt()
def get_weather_prompt(city: str) -> GetPromptResult:
    return GetPromptResult(
        description="Weather prompt",
        messages=[
            Message(
                role="user",
                content=TextContent(
                    text=f"What is the weather like in {city}?",
                ),
            )
        ],
    )
@mcp.tool()
def get_weather(city: str) -> str:
    return "sunny"For production use, you can use a simple Flask app with the mcp server and support Streamable HTTP from version 2025-06-18.
from flask import Flask, Response, url_for, request
# Create Flask app and MCP server with Redis queue
app = Flask(__name__)
mcp = MCPServer(
    "example",
    "1.0",
)
@app.route("/mcp", methods=["POST"])
def mcp_route():
    response = mcp.handle_message(request.get_json())
    return jsonify(response.model_dump(exclude_none=True))
if __name__ == "__main__":
    app.run(debug=True)For production use, you can integrate the MCP server with Flask, Redis, and SQLAlchemy for better message handling and database transaction management:
from flask import Flask, request
from sqlalchemy.orm import Session
from sqlalchemy import create_engine
# Create engine for PostgreSQL database
engine = create_engine("postgresql://user:pass@localhost/dbname")
# Create Flask app and MCP server with Redis queue
app = Flask(__name__)
mcp = MCPServer(
    "example",
    "1.0",
)
@app.route("/mcp", methods=["POST"])
def mcp_route():
    with Session(engine) as session:
        try:
            response = mcp.handle_message(request.get_json())
            session.commit()
        except:
            session.rollback()
            raise
        else:
            return jsonify(response.model_dump(exclude_none=True))
if __name__ == "__main__":
    app.run(debug=True)For a more comprehensive example including logging setup and session management, check out the example Flask application in the repository.
Gunicorn is a better approach to running even locally. To run the app with gunicorn
from gunicorn.app.base import BaseApplication
class FlaskApplication(BaseApplication):
    def __init__(self, app, options=None):
        self.options = options or {}
        self.application = app
        super().__init__()
    def load_config(self):
        config = {
            key: value
            for key, value in self.options.items()
            if key in self.cfg.settings
        }
        for key, value in config.items():
            self.cfg.set(key.lower(), value)
    def load(self):
        return self.application
if __name__ == "__main__":
    handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter("[%(asctime)s] [%(levelname)s] %(name)s: %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    options = {
        "bind": "0.0.0.0:9000",
        "workers": 1,
        "worker_class": "gevent",
        "loglevel": "debug",
    }
    FlaskApplication(app, options).run()- Edit MCP settings and add to configuration
{
  "mcpServers": {
    "server-name": {
      "url": "http://localhost:9000/mcp"
    }
  }
}As of this writing, Claude Desktop does not support MCP through SSE and only supports stdio. To connect Claude Desktop with an MCP server, you'll need to use mcp-proxy.
Configuration example for Claude Desktop:
{
  "mcpServers": {
    "weather": {
      "command": "/Users/yourname/.local/bin/mcp-proxy",
      "args": ["http://127.0.0.1:9000/sse"]
    }
  }
}To install MCP Proxy for Claude Desktop automatically via Smithery:
npx -y @smithery/cli install mcp-proxy --client claudeThe stable version of the package is available on the PyPI repository. You can install it using the following command:
# Option 1: With uv (recommended)
uv tool install mcp-proxy
# Option 2: With pipx (alternative)
pipx install mcp-proxyOnce installed, you can run the server using the mcp-proxy command.
Contributions are welcome! Please feel free to submit a Pull Request.
- MCP Python SDK - The official async Python SDK for MCP
- mcp-proxy - A proxy tool to connect Claude Desktop with MCP servers
MIT License
The MCP Inspector is a useful tool for testing and debugging MCP servers. It provides a web interface to inspect and test MCP server endpoints.
Install MCP Inspector using npm:
npm install -g @modelcontextprotocol/inspector- Start your MCP server (e.g., the Flask example above)
- Run MCP Inspector:
git clone [email protected]:modelcontextprotocol/inspector.git
cd inspector
npm run build
npm start- Open your browser and navigate to http://127.0.0.1:6274/
- Enter your MCP server URL (e.g., http://localhost:9000/sse)
- Use the inspector to:
- Change transport type to SSE
- Test server connections
- Monitor SSE events
- Send test messages
- Debug responses
 
This tool is particularly useful during development to ensure your MCP server implementation is working correctly and complies with the protocol specification.