fastapi-mcp-router 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. fastapi_mcp_router-0.1.0/.codannaignore +70 -0
  2. fastapi_mcp_router-0.1.0/.github/workflows/release.yml +61 -0
  3. fastapi_mcp_router-0.1.0/.gitignore +49 -0
  4. fastapi_mcp_router-0.1.0/CHANGELOG.md +35 -0
  5. fastapi_mcp_router-0.1.0/CLAUDE.md +81 -0
  6. fastapi_mcp_router-0.1.0/LICENSE +21 -0
  7. fastapi_mcp_router-0.1.0/PKG-INFO +104 -0
  8. fastapi_mcp_router-0.1.0/README.md +67 -0
  9. fastapi_mcp_router-0.1.0/docs/guide.md +685 -0
  10. fastapi_mcp_router-0.1.0/docs/quickstart.md +136 -0
  11. fastapi_mcp_router-0.1.0/docs/reference.md +814 -0
  12. fastapi_mcp_router-0.1.0/examples/README.md +102 -0
  13. fastapi_mcp_router-0.1.0/examples/__init__.py +0 -0
  14. fastapi_mcp_router-0.1.0/examples/server.py +97 -0
  15. fastapi_mcp_router-0.1.0/fastapi_mcp_router/__init__.py +44 -0
  16. fastapi_mcp_router-0.1.0/fastapi_mcp_router/exceptions.py +146 -0
  17. fastapi_mcp_router-0.1.0/fastapi_mcp_router/prompts.py +337 -0
  18. fastapi_mcp_router-0.1.0/fastapi_mcp_router/protocol.py +135 -0
  19. fastapi_mcp_router-0.1.0/fastapi_mcp_router/registry.py +871 -0
  20. fastapi_mcp_router-0.1.0/fastapi_mcp_router/resources.py +782 -0
  21. fastapi_mcp_router-0.1.0/fastapi_mcp_router/router.py +2191 -0
  22. fastapi_mcp_router-0.1.0/fastapi_mcp_router/session.py +956 -0
  23. fastapi_mcp_router-0.1.0/fastapi_mcp_router/telemetry.py +60 -0
  24. fastapi_mcp_router-0.1.0/fastapi_mcp_router/types.py +389 -0
  25. fastapi_mcp_router-0.1.0/pyproject.toml +108 -0
  26. fastapi_mcp_router-0.1.0/tests/__init__.py +1 -0
  27. fastapi_mcp_router-0.1.0/tests/conftest.py +168 -0
  28. fastapi_mcp_router-0.1.0/tests/test_annotations.py +189 -0
  29. fastapi_mcp_router-0.1.0/tests/test_background_tasks_injection.py +310 -0
  30. fastapi_mcp_router-0.1.0/tests/test_backwards_compat.py +333 -0
  31. fastapi_mcp_router-0.1.0/tests/test_completions.py +289 -0
  32. fastapi_mcp_router-0.1.0/tests/test_elicitation.py +538 -0
  33. fastapi_mcp_router-0.1.0/tests/test_exceptions.py +483 -0
  34. fastapi_mcp_router-0.1.0/tests/test_handle_tools_list.py +174 -0
  35. fastapi_mcp_router-0.1.0/tests/test_logging_protocol.py +261 -0
  36. fastapi_mcp_router-0.1.0/tests/test_mcp_router_class.py +308 -0
  37. fastapi_mcp_router-0.1.0/tests/test_output_schemas.py +254 -0
  38. fastapi_mcp_router-0.1.0/tests/test_prm.py +188 -0
  39. fastapi_mcp_router-0.1.0/tests/test_progress.py +582 -0
  40. fastapi_mcp_router-0.1.0/tests/test_prompts.py +559 -0
  41. fastapi_mcp_router-0.1.0/tests/test_protocol.py +423 -0
  42. fastapi_mcp_router-0.1.0/tests/test_redis_session.py +466 -0
  43. fastapi_mcp_router-0.1.0/tests/test_registry.py +1106 -0
  44. fastapi_mcp_router-0.1.0/tests/test_registry_generator.py +210 -0
  45. fastapi_mcp_router-0.1.0/tests/test_request_injection.py +409 -0
  46. fastapi_mcp_router-0.1.0/tests/test_resources.py +554 -0
  47. fastapi_mcp_router-0.1.0/tests/test_roots.py +224 -0
  48. fastapi_mcp_router-0.1.0/tests/test_router_integration.py +1345 -0
  49. fastapi_mcp_router-0.1.0/tests/test_sampling.py +490 -0
  50. fastapi_mcp_router-0.1.0/tests/test_security.py +445 -0
  51. fastapi_mcp_router-0.1.0/tests/test_session.py +478 -0
  52. fastapi_mcp_router-0.1.0/tests/test_session_management.py +795 -0
  53. fastapi_mcp_router-0.1.0/tests/test_session_store.py +353 -0
  54. fastapi_mcp_router-0.1.0/tests/test_sse_events.py +734 -0
  55. fastapi_mcp_router-0.1.0/tests/test_sse_streaming.py +660 -0
  56. fastapi_mcp_router-0.1.0/tests/test_streamable_http.py +875 -0
  57. fastapi_mcp_router-0.1.0/tests/test_streaming_tools.py +458 -0
  58. fastapi_mcp_router-0.1.0/tests/test_subscriptions.py +390 -0
  59. fastapi_mcp_router-0.1.0/tests/test_telemetry.py +588 -0
  60. fastapi_mcp_router-0.1.0/tests/test_types.py +225 -0
@@ -0,0 +1,70 @@
1
+ # Codanna ignore patterns (gitignore syntax)
2
+ # https://git-scm.com/docs/gitignore
3
+ #
4
+ # This file tells codanna which files to exclude from indexing.
5
+ # Each line specifies a pattern. Patterns follow the same rules as .gitignore.
6
+
7
+ # Build artifacts
8
+ target/
9
+ build/
10
+ dist/
11
+ *.o
12
+ *.so
13
+ *.dylib
14
+ *.exe
15
+ *.dll
16
+
17
+ # Test files (uncomment to exclude tests from indexing)
18
+ # tests/
19
+ # *_test.rs
20
+ # *.test.js
21
+ # *.spec.ts
22
+ # test_*.py
23
+
24
+ # Temporary files
25
+ *.tmp
26
+ *.temp
27
+ *.bak
28
+ *.swp
29
+ *.swo
30
+ *~
31
+ .DS_Store
32
+
33
+ # Codanna's own directory
34
+ .codanna/
35
+
36
+ # Dependency directories
37
+ node_modules/
38
+ vendor/
39
+ .venv/
40
+ venv/
41
+ __pycache__/
42
+ *.egg-info/
43
+ .cargo/
44
+
45
+ # IDE and editor directories
46
+ .idea/
47
+ .vscode/
48
+ *.iml
49
+ .project
50
+ .classpath
51
+ .settings/
52
+
53
+ # Documentation (uncomment if you don't want to index docs)
54
+ # docs/
55
+ # *.md
56
+
57
+ # Generated files
58
+ *.generated.*
59
+ *.auto.*
60
+ *_pb2.py
61
+ *.pb.go
62
+
63
+ # Version control
64
+ .git/
65
+ .svn/
66
+ .hg/
67
+
68
+ # Example of including specific files from ignored directories:
69
+ # !target/doc/
70
+ # !vendor/specific-file.rs
@@ -0,0 +1,61 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ release:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ contents: write
11
+ id-token: write
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: astral-sh/setup-uv@v5
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: '3.13'
21
+
22
+ - name: Install dependencies
23
+ run: uv sync --extra dev
24
+
25
+ - name: Run tests
26
+ run: uv run pytest
27
+
28
+ - name: Build package
29
+ run: uv run python -m build
30
+
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@release/v1
33
+
34
+ - name: Create git tag
35
+ run: |
36
+ git config --global user.name "github-actions[bot]"
37
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
38
+
39
+ VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
40
+
41
+ if git tag -l "v${VERSION}" | grep -q "v${VERSION}"; then
42
+ echo "Tag v${VERSION} already exists, skipping"
43
+ else
44
+ git tag -a "v${VERSION}" -m "Release v${VERSION}"
45
+ git push --tags
46
+ fi
47
+
48
+ echo "RELEASE_VERSION=${VERSION}" >> "$GITHUB_ENV"
49
+
50
+ - name: Create GitHub Release
51
+ env:
52
+ GH_TOKEN: ${{ github.token }}
53
+ run: |
54
+ if gh release view "v${RELEASE_VERSION}" &>/dev/null; then
55
+ echo "Release v${RELEASE_VERSION} already exists, skipping"
56
+ else
57
+ gh release create "v${RELEASE_VERSION}" \
58
+ --title "v${RELEASE_VERSION}" \
59
+ --generate-notes \
60
+ dist/*
61
+ fi
@@ -0,0 +1,49 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+
15
+ # Testing & coverage
16
+ .coverage
17
+ coverage/
18
+ reports/
19
+ .pytest_cache/
20
+ htmlcov/
21
+
22
+ # Linting
23
+ .ruff_cache/
24
+
25
+ # IDE
26
+ .idea/
27
+ .vscode/
28
+ *.swp
29
+ *.swo
30
+
31
+ # OS
32
+ .DS_Store
33
+ Thumbs.db
34
+
35
+ # Claude Code
36
+ .claude/
37
+
38
+ # Conduct workflow artifacts
39
+ conduct/
40
+
41
+ # Code intelligence
42
+ .codanna/
43
+ .fastembed_*
44
+
45
+ # Generated docs
46
+ ARCHITECTURE.md
47
+
48
+ # uv lock (library — consumers pin their own deps)
49
+ uv.lock
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-03-01
9
+
10
+ Initial release.
11
+
12
+ ### Added
13
+
14
+ - `MCPRouter` — `APIRouter` subclass with `@mcp.tool()`, `@mcp.resource()`, `@mcp.prompt()` decorators
15
+ - `create_mcp_router()` factory for external registry composition
16
+ - Full MCP 2025-06-18 protocol coverage (17 methods)
17
+ - Streamable HTTP transport (JSON and SSE responses via `Accept` header)
18
+ - Legacy SSE compatibility via `legacy_sse=True`
19
+ - `MCPToolRegistry` with auto-generated JSON schemas from function signatures
20
+ - FastAPI `Depends()`, `Request`, and `BackgroundTasks` injection in tool handlers
21
+ - `ToolFilter` callback for per-connection tool filtering
22
+ - `ResourceRegistry` with decorator and provider patterns
23
+ - `FileResourceProvider` with path traversal protection and 10 MB size limit
24
+ - `PromptRegistry` with auto-generated argument metadata
25
+ - Streaming tools via `AsyncGenerator` return type
26
+ - `ProgressCallback` injection for long-running tools
27
+ - `SessionStore` ABC with `InMemorySessionStore` and `RedisSessionStore`
28
+ - `SamplingManager` and `RootsManager` for server-to-client requests
29
+ - Resource subscriptions with per-session URI change tracking
30
+ - `auth_validator` callback for API key and Bearer token authentication
31
+ - `create_prm_router()` for OAuth 2.1 Protected Resource Metadata (RFC 9728)
32
+ - `MCPError` (protocol-level) and `ToolError` (LLM-visible) error separation
33
+ - Optional OpenTelemetry spans and counters via `fastapi-mcp-router[otel]`
34
+ - Stateless mode for AWS Lambda deployment via Mangum
35
+ - Documentation: quick start, narrative guide, API reference
@@ -0,0 +1,81 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project
6
+
7
+ fastapi-mcp-router is a lightweight FastAPI integration for the Model Context Protocol (MCP). It exposes MCP tools, resources, and prompts through FastAPI endpoints using decorator-based registration and JSON-RPC 2.0 transport. Supports stateless HTTP (Lambda-compatible) and Streamable HTTP with SSE streaming.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Run all tests (includes coverage, enforces 80% minimum)
13
+ uv run pytest
14
+
15
+ # Run a single test
16
+ uv run pytest tests/test_registry.py::test_register_tool_default_name -v
17
+
18
+ # Run tests by marker
19
+ uv run pytest -m unit
20
+ uv run pytest -m integration
21
+
22
+ # Run tests without coverage (faster iteration)
23
+ uv run pytest --no-cov
24
+
25
+ # Build package
26
+ uv run python -m build
27
+ ```
28
+
29
+ No separate lint or format commands are configured. No Makefile exists. The venv is managed by `uv` — use `uv run` to execute commands.
30
+
31
+ ## Architecture
32
+
33
+ The package has 10 modules across 5,909 LOC with this dependency flow:
34
+
35
+ ```
36
+ router.py → registry.py → exceptions.py
37
+ ↓ ↓
38
+ protocol.py types.py
39
+
40
+ telemetry.py (leaf, zero internal imports)
41
+
42
+ session.py, resources.py, prompts.py
43
+ ```
44
+
45
+ **router.py** — `create_mcp_router()` factory and `MCPRouter` class. Handles 17 MCP methods. Streamable HTTP POST returns `JSONResponse` or `StreamingResponse` based on `Accept` header. `legacy_sse=True` registers GET endpoint for backward compatibility. OTel instrumentation via `telemetry.py`.
46
+
47
+ **registry.py** — `MCPToolRegistry` stores tool definitions registered via `@registry.tool()` decorator. Auto-generates JSON schemas from function signatures using Pydantic `TypeAdapter`. Filters out FastAPI `Depends()`, `Request`, and `BackgroundTasks` parameters from schemas.
48
+
49
+ **telemetry.py** — Leaf module with zero internal imports. Wraps optional `opentelemetry-api` behind try/except ImportError. Exports `get_tracer()` and `get_meter()`.
50
+
51
+ **protocol.py** — Pure functions for formatting JSON-RPC 2.0 responses and errors.
52
+
53
+ **types.py** — Pydantic models: `TextContent`, `ToolResponse`, `ServerInfo`, `ServerIcon`, `McpSessionData`.
54
+
55
+ **exceptions.py** — `MCPError` (protocol-level, JSON-RPC error codes -32700 to -32603) vs `ToolError` (business logic, returns `isError: true` so LLM can recover).
56
+
57
+ **session.py** — `SessionStore` ABC, `InMemorySessionStore`, `RedisSessionStore`, `SamplingManager`, `RootsManager`.
58
+
59
+ **resources.py** — `ResourceRegistry`, `ResourceProvider` ABC, `FileResourceProvider`.
60
+
61
+ **prompts.py** — `PromptRegistry` with auto-generated argument metadata.
62
+
63
+ ## Key Patterns
64
+
65
+ - Streamable HTTP: POST with `Accept: text/event-stream` returns `StreamingResponse`; without returns `JSONResponse`.
66
+ - `legacy_sse=True` registers SSE GET endpoint alongside Streamable HTTP POST. Default is `False`.
67
+ - All JSON-RPC responses use HTTP 200. Errors are at the protocol level, not HTTP status codes.
68
+ - Tool handlers can be sync or async. Registry detects and handles both.
69
+ - `ToolFilter` callback enables per-connection tool filtering (e.g., OAuth vs API key scopes).
70
+ - Auth validation uses `auth_validator` callback passed to `create_mcp_router()`.
71
+ - Protocol versions supported: `2025-06-18` (primary), `2025-03-26` (fallback).
72
+ - Public API is defined in `__init__.py` via `__all__` (17 exports).
73
+ - OTel tracing is optional: `enable_telemetry=True` (default) emits spans when `opentelemetry-api` is installed. Install via `pip install fastapi-mcp-router[otel]`.
74
+
75
+ ## Testing
76
+
77
+ - 544 tests across 33 files using pytest + pytest-asyncio.
78
+ - Integration tests use `httpx.AsyncClient` with FastAPI `TestClient`.
79
+ - Tests use `@pytest.mark.unit` and `@pytest.mark.integration` markers.
80
+ - Async test functions use explicit `@pytest.mark.asyncio` decorator (`asyncio_mode = "auto"` is NOT configured).
81
+ - Key test files: `test_streamable_http.py` (Streamable HTTP transport), `test_telemetry.py` (OTel), `test_sse_streaming.py` (legacy SSE).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andre Bremer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-mcp-router
3
+ Version: 0.1.0
4
+ Summary: Lightweight FastAPI integration for Model Context Protocol (MCP)
5
+ Project-URL: Homepage, https://github.com/rcrsr/fastapi-mcp-router
6
+ Project-URL: Repository, https://github.com/rcrsr/fastapi-mcp-router
7
+ Project-URL: Issues, https://github.com/rcrsr/fastapi-mcp-router/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: ai,fastapi,llm,mcp,model-context-protocol
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Framework :: FastAPI
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: fastapi>=0.134.0
24
+ Requires-Dist: pydantic>=2.12.5
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.4.0; extra == 'dev'
27
+ Requires-Dist: httpx>=0.28.1; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
30
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
31
+ Requires-Dist: ruff>=0.15.4; extra == 'dev'
32
+ Requires-Dist: twine>=6.2.0; extra == 'dev'
33
+ Requires-Dist: ty>=0.0.19; extra == 'dev'
34
+ Provides-Extra: otel
35
+ Requires-Dist: opentelemetry-api>=1.0; extra == 'otel'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # fastapi-mcp-router
39
+
40
+ Add MCP to your existing FastAPI app. Register tools, resources, and prompts with decorators. Use `Depends()`, `Request`, and `BackgroundTasks` the same way you already do.
41
+
42
+ ## Why fastapi-mcp-router
43
+
44
+ - **It's just an `APIRouter`.** Mount it like any other router. No separate framework, no new server process.
45
+ - **Your DI still works.** `Depends()`, `Request`, `BackgroundTasks` — same patterns, same middleware.
46
+ - **2 dependencies.** FastAPI and Pydantic. Nothing else.
47
+ - **No lock-in.** Tools are regular async functions. Call them from tests, CLI scripts, or other endpoints without MCP.
48
+ - **Lambda-ready.** Stateless mode + Mangum. No adapter layer.
49
+
50
+ **Use FastMCP instead** if you need STDIO transport, OpenAPI spec imports, or managed hosting.
51
+
52
+ ## Install
53
+
54
+ ```bash
55
+ pip install fastapi-mcp-router
56
+ ```
57
+
58
+ ## Quick Start
59
+
60
+ ```python
61
+ from fastapi import FastAPI
62
+ from fastapi_mcp_router import MCPRouter
63
+
64
+ app = FastAPI()
65
+ mcp = MCPRouter()
66
+
67
+ @mcp.tool()
68
+ async def write_message(payload: str) -> dict:
69
+ """Write coordination message."""
70
+ return {"success": True, "message_id": "msg-123"}
71
+
72
+ @mcp.resource("project://{project_id}/config")
73
+ async def project_config(project_id: str) -> dict:
74
+ return {"project_id": project_id, "env": "production"}
75
+
76
+ @mcp.prompt()
77
+ async def review_code(file_path: str, language: str = "python") -> list[dict]:
78
+ return [{"role": "user", "content": f"Review {file_path} ({language})"}]
79
+
80
+ app.include_router(mcp, prefix="/mcp")
81
+ ```
82
+
83
+ That's it. Your FastAPI app now speaks MCP over Streamable HTTP.
84
+
85
+ ## What You Get
86
+
87
+ - **Full MCP 2025-06-18 spec** — tools, resources, prompts, sampling, logging, completions, elicitation
88
+ - **Streamable HTTP** — JSON or SSE response based on `Accept` header
89
+ - **Streaming tools** — return `AsyncGenerator` for incremental results
90
+ - **Session management** — in-memory and Redis stores for stateful connections
91
+ - **Progress reporting** — inject `ProgressCallback` into tool signatures
92
+ - **Auth** — `auth_validator` callback + OAuth 2.1 PRM (RFC 9728)
93
+ - **OpenTelemetry** — opt-in spans and counters via `pip install fastapi-mcp-router[otel]`
94
+ - **Lambda-ready** — stateless mode works with Mangum, no adapter overhead
95
+
96
+ ## Documentation
97
+
98
+ - [Quick Start](docs/quickstart.md) — installation, first tool, stateful mode, auth, Lambda
99
+ - [Guide](docs/guide.md) — resources, prompts, streaming, sessions, telemetry
100
+ - [API Reference](docs/reference.md) — all exports, types, and configuration options
101
+
102
+ ## License
103
+
104
+ MIT
@@ -0,0 +1,67 @@
1
+ # fastapi-mcp-router
2
+
3
+ Add MCP to your existing FastAPI app. Register tools, resources, and prompts with decorators. Use `Depends()`, `Request`, and `BackgroundTasks` the same way you already do.
4
+
5
+ ## Why fastapi-mcp-router
6
+
7
+ - **It's just an `APIRouter`.** Mount it like any other router. No separate framework, no new server process.
8
+ - **Your DI still works.** `Depends()`, `Request`, `BackgroundTasks` — same patterns, same middleware.
9
+ - **2 dependencies.** FastAPI and Pydantic. Nothing else.
10
+ - **No lock-in.** Tools are regular async functions. Call them from tests, CLI scripts, or other endpoints without MCP.
11
+ - **Lambda-ready.** Stateless mode + Mangum. No adapter layer.
12
+
13
+ **Use FastMCP instead** if you need STDIO transport, OpenAPI spec imports, or managed hosting.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pip install fastapi-mcp-router
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```python
24
+ from fastapi import FastAPI
25
+ from fastapi_mcp_router import MCPRouter
26
+
27
+ app = FastAPI()
28
+ mcp = MCPRouter()
29
+
30
+ @mcp.tool()
31
+ async def write_message(payload: str) -> dict:
32
+ """Write coordination message."""
33
+ return {"success": True, "message_id": "msg-123"}
34
+
35
+ @mcp.resource("project://{project_id}/config")
36
+ async def project_config(project_id: str) -> dict:
37
+ return {"project_id": project_id, "env": "production"}
38
+
39
+ @mcp.prompt()
40
+ async def review_code(file_path: str, language: str = "python") -> list[dict]:
41
+ return [{"role": "user", "content": f"Review {file_path} ({language})"}]
42
+
43
+ app.include_router(mcp, prefix="/mcp")
44
+ ```
45
+
46
+ That's it. Your FastAPI app now speaks MCP over Streamable HTTP.
47
+
48
+ ## What You Get
49
+
50
+ - **Full MCP 2025-06-18 spec** — tools, resources, prompts, sampling, logging, completions, elicitation
51
+ - **Streamable HTTP** — JSON or SSE response based on `Accept` header
52
+ - **Streaming tools** — return `AsyncGenerator` for incremental results
53
+ - **Session management** — in-memory and Redis stores for stateful connections
54
+ - **Progress reporting** — inject `ProgressCallback` into tool signatures
55
+ - **Auth** — `auth_validator` callback + OAuth 2.1 PRM (RFC 9728)
56
+ - **OpenTelemetry** — opt-in spans and counters via `pip install fastapi-mcp-router[otel]`
57
+ - **Lambda-ready** — stateless mode works with Mangum, no adapter overhead
58
+
59
+ ## Documentation
60
+
61
+ - [Quick Start](docs/quickstart.md) — installation, first tool, stateful mode, auth, Lambda
62
+ - [Guide](docs/guide.md) — resources, prompts, streaming, sessions, telemetry
63
+ - [API Reference](docs/reference.md) — all exports, types, and configuration options
64
+
65
+ ## License
66
+
67
+ MIT