Skip to main content
Glama
kshitijkumrawat20

FastAPI MCP Streamable HTTP Starter

README.md
# FastAPI MCP Streamable HTTP Starter ๐Ÿš€

[![MCP Spec](https://img.shields.io/badge/MCP_Spec-2025--11--25-00d2ff.svg)](https://modelcontextprotocol.io)
[![Python](https://img.shields.io/badge/Python-3.11+-3776ab.svg)](https://python.org)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.110+-009688.svg)](https://fastapi.tiangolo.com)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

A minimal, production-ready starter template for building **Model Context Protocol (MCP)** servers in Python with **FastAPI** over **Streamable HTTP**.

Implements the official MCP Specification version `2025-11-25`, handling standard JSON-RPC 2.0 requests:
- `initialize` (protocol handshake and capability negotiation)
- `tools/list` (dynamic tool discovery)
- `tools/call` (tool execution)

---

## โšก Quickstart

### 1. Clone the repository
```bash
git clone https://github.com/kshitijkumrawat20/fastapi-mcp-streamable-http-starter.git
cd fastapi-mcp-streamable-http-starter
```

### 2. Install dependencies
Using `uv`:
```bash
uv pip install -r requirements.txt
```
Or standard `pip`:
```bash
pip install -r requirements.txt
```

### 3. Run the MCP server
```bash
uvicorn main:app --host 127.0.0.1 --port 8000 --reload
```

---

## ๐Ÿงช Testing with cURL

### 1. Protocol Handshake (`initialize`)
```bash
curl -X POST http://127.0.0.1:8000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-11-25",
      "capabilities": {},
      "clientInfo": {"name": "curl-client", "version": "1.0.0"}
    }
  }'
```

### 2. Discover Tools (`tools/list`)
```bash
curl -X POST http://127.0.0.1:8000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list"
  }'
```

### 3. Execute a Tool (`tools/call`)
```bash
curl -X POST http://127.0.0.1:8000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "echo",
      "arguments": {
        "message": "Hello from MCP Streamable HTTP!"
      }
    }
  }'
```

---

## ๐Ÿ›  Adding Custom Tools

Subclass `MCPTool` and register it in `mcp_server.py`:

```python
from mcp_server import MCPTool

class WeatherTool(MCPTool):
    @property
    def name(self) -> str:
        return "get_weather"

    @property
    def description(self) -> str:
        return "Returns current weather for a city."

    @property
    def input_schema(self) -> dict:
        return {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name"}
            },
            "required": ["city"]
        }

    async def execute(self, arguments: dict) -> dict:
        city = arguments["city"]
        return {"city": city, "temperature": "72ยฐF", "condition": "Sunny"}

# Register in ToolRegistry:
server.registry.register(WeatherTool())
```

---

## ๐Ÿ“„ License
MIT License. Feel free to use this template for your hackathons and production MCP servers!