mcp-simple-server
Minimal MCP server with streamable HTTP transport
Documentation
MCP Simple Server
A minimal, reference implementation of a Model Context Protocol server with streamable HTTP transport. Built with FastMCP following the official Anthropic MCP specification 2025-06-18. Perfect starting point for building remote MCP servers.
๐ฏ Purpose
This project serves as a simple, well-documented reference for developers who want to:
- Build their first MCP server
- Deploy MCP servers to cloud platforms (Railway, Heroku, Render)
- Understand the MCP protocol implementation
- Create a foundation for more sophisticated MCP solutions
Features
- โ Two Math Tools: `add` and `multiply` functions
- โ Streamable HTTP Transport: Modern MCP protocol with SSE support
- โ Session Management: Proper MCP initialization flow
- โ Remote Deployment: Railway, Heroku, Render deployment configs
- โ Automated Testing: Complete protocol validation and debugging tools
- โ Claude Desktop Integration: Ready for AI assistant integration
- โ Reference Implementation: Well-documented code for learning
Quick Start
Local Development
git clone https://github.com/oleksandrsirenko/mcp-simple-server.git
cd mcp-simple-server
uv sync
source .venv/bin/activate
python main.pyServer starts at: `http://localhost:8000/mcp/`
Test the Server
python test_server.pyExpected output:
๐งช Starting MCP Server Tests
โ
Initialize successful - Server: Simple Server
โ
Initialized notification sent
โ
Found 2 tools: add, multiply
โ
Add tool returned correct result
โ
Multiply tool returned correct result
๐ All tests passed!Available Tools
`add(a, b)`
Adds two numbers together.
Example:
{"name": "add", "arguments": {"a": 25, "b": 17}}
โ Returns: 42`multiply(a, b)`
Multiplies two numbers together.
Example:
{"name": "multiply", "arguments": {"a": 8, "b": 6}}
โ Returns: 48Manual Testing with curl
Local Testing (Development)
For testing your local development server running on `localhost:8000`:
1. Initialize Session
curl -X POST http://localhost:8000/mcp/ \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"clientInfo":{"name":"test-client","version":"1.0.0"}}}'2. Send Initialized Notification
curl -X POST http://localhost:8000/mcp/ \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'3. List Tools
curl -X POST http://localhost:8000/mcp/ \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'4. Call Add Tool
curl -X POST http://localhost:8000/mcp/ \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"add","arguments":{"a":25,"b":17}}}'Remote Testing (Production)
For testing your deployed server, replace `localhost:8000` with your deployment URL:
# Example with Railway deployment
curl -X POST https://your-app.railway.app/mcp/ \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"clientInfo":{"name":"test-client","version":"1.0.0"}}}'Note: For comprehensive remote testing, use the automated test script:
python test_deployment.py your-app.railway.appDeployment
Railway (Recommended)
1. Push to GitHub:
git add .
git commit -m "ready for deployment"
git push origin main2. Deploy to Railway:
3. Test your deployment:
python test_deployment.py your-app-name.up.railway.app4. Your MCP URL: `https://your-app.railway.app/mcp/`
Heroku
heroku create your-mcp-server
git push heroku mainYour MCP URL: `https://your-mcp-server.herokuapp.com/mcp/`
Render
1. Connect GitHub repository to Render
2. Render auto-detects `render.yaml` and Dockerfile
3. Deploys automatically
Your MCP URL: `https://your-service.onrender.com/mcp/`
Docker
docker build -t mcp-simple-server .
docker run -p 8000:8000 mcp-simple-serverClaude Desktop Integration
Local Server Configuration
{
"mcpServers": {
"simple-server": {
"command": "python",
"args": ["main.py"],
"cwd": "/path/to/mcp-simple-server"
}
}
}Remote Server Configuration (Recommended)
For remote servers deployed to Railway, Heroku, or Render, use the `mcp-remote` package:
{
"mcpServers": {
"simple-server-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://your-app.railway.app/mcp/",
"--allow-http",
"--header",
"Accept: application/json, text/event-stream"
]
}
}
}Key Configuration Notes:
- Use `npx` with the `-y` flag to auto-install `mcp-remote`
- Include the trailing slash in the URL: `/mcp/`
- Add the `--allow-http` flag for HTTP connections
- Include the Accept header for proper SSE support
Alternative: Direct Python Proxy (Advanced)
For advanced users or debugging purposes, you can create a custom Python proxy:
{
"mcpServers": {
"simple-server-proxy": {
"command": "python",
"args": ["claude_mcp_proxy.py"],
"cwd": "/path/to/mcp-simple-server"
}
}
}Note: This requires the `claude_mcp_proxy.py` script from the repository and is mainly for debugging purposes. Use `mcp-remote` for production.
Configuration File Locations:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
Test with Claude
After integration, ask Claude:
- "Can you add 42 and 18 for me?"
- "What's 7 times 9?"
- "What tools do you have available?"
Claude will use your MCP server to perform calculations! ๐
Development
Adding New Tools
@mcp.tool()
def subtract(a: float, b: float) -> float:
"""Subtract two numbers"""
return a - b
@mcp.tool()
def divide(a: float, b: float) -> float:
"""Divide two numbers"""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / bEnvironment Variables
- `HOST`: Server host (default: 127.0.0.1, use 0.0.0.0 for deployment)
- `PORT`: Server port (default: 8000, Railway sets this automatically)
HOST=0.0.0.0 PORT=3000 python main.pyNote: For Railway deployment, FastMCP will automatically bind to `0.0.0.0:$PORT`.
Project Structure
mcp-simple-server/
โโโ main.py # MCP server (~25 lines)
โโโ test_server.py # Local server tests (~300 lines)
โโโ test_deployment.py # Remote deployment tests
โโโ test_host_binding.py # Host binding tests
โโโ test_proxy_script.py # Proxy testing script
โโโ test_streamable_app.py # Streamable HTTP tests
โโโ test_tool_verification.py # Tool verification tests
โโโ debug_railway_server.py # Railway debugging utilities
โโโ debug_fastmcp.py # FastMCP debugging utilities
โโโ claude_mcp_proxy.py # Claude Desktop proxy (optional)
โโโ start.sh # Shell startup script
โโโ pyproject.toml # Project configuration
โโโ README.md # This documentation
โโโ uv.lock # Dependency lock file
โโโ .gitignore # Git ignore patterns
โโโ .python-version # Python version specification
โโโ Dockerfile # Docker deployment
โโโ railway.toml # Railway configuration
โโโ Procfile # Heroku configuration
โโโ render.yaml # Render configurationArchitecture
- FastMCP: High-level MCP implementation from Anthropic
- Streamable HTTP: Modern transport with SSE streaming support
- Session Management: Stateful connections with session IDs
- JSON-RPC 2.0: Standard protocol for message exchange
- Protocol 2025-06-18: Latest MCP specification
- Port 8000: Default FastMCP server port (configurable via PORT env var)
Technical Details
Server Implementation
- Framework: FastMCP (official Anthropic library)
- Transport: Streamable HTTP with Server-Sent Events
- Protocol: MCP 2025-06-18 specification
- Dependencies: `httpx>=0.28.1`, `mcp>=1.9.4`
MCP Protocol Flow
1. Client sends `initialize` request
2. Server responds with capabilities and session ID
3. Client sends `initialized` notification
4. Normal operations begin (tools/list, tools/call, etc.)
Tool Response Format
Tools return simple Python values (float, int, str) which FastMCP automatically wraps in the proper MCP response format.
Troubleshooting
Server Won't Start
# Check if port is in use
lsof -i :8000
# Try different port
PORT=3000 python main.pyMCP Protocol Errors
# Run automated test
python test_server.py
# Check server logs for detailed errorsClaude Desktop Not Connecting
1. Verify JSON configuration syntax - Use a JSON validator
2. Check server URL accessibility - Test with `curl` or browser
3. Restart Claude Desktop after config changes
4. Ensure proper MCP endpoint path - Use `/mcp/` with trailing slash
5. Use `mcp-remote` for remote servers - Don't use `curl` for remote connections
Test Remote Deployment
Test your deployed server with the provided script:
# Test your deployed server (replace with your URL)
python test_deployment.py your-app.railway.app
# Or with full URL
python test_deployment.py https://your-app.railway.appThis will run the complete MCP protocol test suite against your remote server.
Common Issues
- Wrong endpoint: Use `/mcp/` (with trailing slash)
- Missing headers: Include all required MCP headers
- Session management: Must send `initialized` notification after `initialize`
- Remote connections: Use `mcp-remote`, not `curl` for Claude Desktop
- Port binding: Use `0.0.0.0:$PORT` for deployment, not `127.0.0.1`
Dependencies
dependencies = [
"httpx>=0.28.1", # HTTP client for testing
"mcp>=1.9.4", # Official Anthropic MCP library
]The project uses:
- mcp: Official Anthropic MCP Python SDK
- httpx: Modern HTTP client for automated testing
- Python: Requires Python >=3.10
Contributing
1. Fork the repository
2. Make your changes
3. Run tests: `python test_server.py`
4. Test deployment: `python test_deployment.py your-test-url`
5. Ensure all tests pass
6. Submit a pull request
License
MIT License
Resources
Frequently asked questions
What is mcp-simple-server?
mcp-simple-server is Minimal MCP server with streamable HTTP transport
How do I install mcp-simple-server?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is mcp-simple-server open source?
Yes โ it is hosted on GitHub at https://github.com/oleksandrsirenko/mcp-simple-server and has 1 stars.
Related MCP tools
Cognee is the open-source AI memory platform for agents. Give your AI agents persistent long-term memory across sessions with a self-hosted knowledge graph engine.
Automate browser based workflows with AI
Hindsight: Agent Memory That Learns
A privacy-first app that strips AI watermarks from content you own.
Agent framework and applications built upon Qwen>=3.0, featuring Function Calling, MCP, Code Interpreter, RAG, Chrome extension, etc.
The power of Claude Code / GeminiCLI / CodexCLI + [Gemini / OpenAI / OpenRouter / Azure / Grok / Ollama / Custom Model / All Of The Above] working as one.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP