Inventory and gap analysis of the 0.2.0 codebase against the full Gitea API and the official gitea-mcp toolset, the B1..B11 + security chunk plan, ADRs 0001-0006 for the full-access rebuild, SDK/OAuth research notes, and the instance swagger pinned for tool generation. The audit-logging doc moves to docs/audit-logging.md.
1.5 KiB
ADR 0002: official MCP SDK, low-level server
Status: accepted (2026-10-14)
Context
The mission asks for the official MCP Python SDK (FastMCP). In mcp 2.x
(current stable 2.3.0) FastMCP was renamed MCPServer. Its add_tool() always
derives the input schema from a Python function signature and cannot accept a
raw JSON schema. We register 538 tools whose schemas come from the Gitea OpenAPI
spec. The SDK's low-level mcp.server.Server takes raw Tool(input_schema=...)
objects and offers the same streamable_http_app(auth=..., token_verifier=..., auth_server_provider=..., custom_starlette_routes=...) wiring as MCPServer.
Details: docs/research/sdk-oauth-gitea.md section 2.
Decision
- Depend on
mcp>=2.3,<3. - Build one low-level
Serverfrom the generated catalog with a singleon_list_toolsand a singleon_call_tooldispatcher. - Serve it over
stdio_server()and overserver.streamable_http_app(...)run by uvicorn. The FastAPI app, the hand-rolled JSON-RPC protocol and the[server]extra are removed;mcpalready brings Starlette and uvicorn. - Validate arguments ourselves with
jsonschema(v2 does not). - Tool failures are returned as
CallToolResult(is_error=True)so the model can read them; only protocol problems raiseMCPError.
Consequences
Same package, same transports and auth stack as MCPServer, without private
API hacks. The core no longer needs a web-free boundary test: both transports
come from the SDK.