This repo is a teaching starter for Model Context Protocol (MCP) using FastAPI and the Streamable HTTP transport (HTTP POST/GET with optional SSE).
It is designed to support the 20‑week plan where students:
- learn REST/HTTP fundamentals,
- learn MCP primitives (tools/resources/prompts),
- compare stdio vs Streamable HTTP (HTTP/SSE),
- and test servers using curl and Python (no Postman required).
- Python 3.10+ (3.11 recommended)
cd mcp-fastapi-starter
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install -r requirements.txt# You may need python -m here
uvicorn app.main:app --reload --port 8000You should now have:
- REST health endpoint:
http://127.0.0.1:8000/health - MCP endpoint:
http://127.0.0.1:8000/mcp/(note the trailing slash)
curl -s http://127.0.0.1:8000/health | python -m json.toolOr with plain curl output:
curl -i http://127.0.0.1:8000/healthImportant: For Streamable HTTP, clients must send Accept: application/json, text/event-stream.
The server may return a Mcp-Session-Id response header. If it does, include it on later requests.
curl -i \
-X POST http://127.0.0.1:8000/mcp/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"initialize",
"params":{
"protocolVersion":"2025-11-25",
"capabilities":{},
"clientInfo":{"name":"curl","version":"1.0"}
}
}'Copy the Mcp-Session-Id header value if returned.
curl -i \
-X POST http://127.0.0.1:8000/mcp/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: <PASTE_SESSION_ID>" \
-d '{
"jsonrpc":"2.0",
"method":"notifications/initialized",
"params":{}
}'curl -s \
-X POST http://127.0.0.1:8000/mcp/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: <PASTE_SESSION_ID>" \
-d '{
"jsonrpc":"2.0",
"id":2,
"method":"tools/list",
"params":{}
}' | python -m json.toolcurl -s \
-X POST http://127.0.0.1:8000/mcp/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: <PASTE_SESSION_ID>" \
-d '{
"jsonrpc":"2.0",
"id":3,
"method":"tools/call",
"params":{
"name":"add",
"arguments":{"a":2,"b":3}
}
}' | python -m json.toolcurl -s \
-X POST http://127.0.0.1:8000/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "Mcp-Session-Id: <PASTE_SESSION_ID>" \
-d '{
"jsonrpc":"2.0",
"id":4,
"method":"resources/read",
"params":{"uri":"status://summary"}
}' | python -m json.toolpython clients/http_client_manual.pyIt will:
- initialize
- capture
Mcp-Session-Idif provided - list tools
- call
echo
mcp-fastapi-starter/
app/
main.py
mcp_server.py
clients/
http_client_manual.py
requirements.txt