Context
mcp SDK v2.0.0 shipped 2026-07-27/28 alongside the 2026-07-28 protocol spec. It removed mcp.server.fastmcp (FastMCP renamed to MCPServer at mcp.server), so our unpinned mcp>=1.0 extra pulled v2 and broke CI (all 5 tests/test_mcp_identity.py cases failed at import).
Already done (PR #25): pinned mcp>=1.0,<2 — matching upstream's own guidance — and switched the test guard to pytest.importorskip("mcp.server.fastmcp"). This issue tracks the eventual port to mcp 2.x.
Minimum port
src/cfg/mcp/server.py is 30 flat tools, each a thin @mcp.tool() wrapper around _call(action, payload) -> dict envelope. No resources, sessions, OAuth, or env-var config. The mechanical port is small:
from mcp.server.fastmcp import FastMCP → from mcp.server import MCPServer
FastMCP("cfgit") → MCPServer("cfgit")
Must verify during the port (v2 breaking changes that could bite us):
Features actually worth adopting (for our surface)
- OpenTelemetry tracing (on by default) — free per-tool spans across our 30 tools; see which
cfg_* calls are slow/failing in an agent session with zero instrumentation. Highest-value, lowest-effort win.
- Stateless protocol — our tools are already stateless (no
Mcp-Session-Id, no session state), so this is a natural fit and more robust for the "spawn cfg-mcp per agent turn" pattern.
Bigger, optional redesign (separate decision)
- Resources + RFC 6570 URI templates — move read-only tools (
cfg_show, cfg_log, cfg_status, cfg_diff) to resources like cfg://{env}/{collection}/{id}@{ref} so agents can browse records. More idiomatic, but a real rework, not a drop-in.
- Request cancellation — let an agent abort a slow
cfg_impact --llm narration.
- Enterprise auth (SEP-990 identity assertion) — could eventually feed a verified caller identity into cfgit's existing
author/attribution system. Design question, not a quick adopt.
Not relevant to us
Resolver dependency injection, client-side subscriptions, extension APIs — for complex/multi-round-trip servers; our flat wrappers don't need them.
Refs
Context
mcpSDK v2.0.0 shipped 2026-07-27/28 alongside the2026-07-28protocol spec. It removedmcp.server.fastmcp(FastMCP renamed toMCPServeratmcp.server), so our unpinnedmcp>=1.0extra pulled v2 and broke CI (all 5tests/test_mcp_identity.pycases failed at import).Already done (PR #25): pinned
mcp>=1.0,<2— matching upstream's own guidance — and switched the test guard topytest.importorskip("mcp.server.fastmcp"). This issue tracks the eventual port to mcp 2.x.Minimum port
src/cfg/mcp/server.pyis 30 flat tools, each a thin@mcp.tool()wrapper around_call(action, payload) -> dict envelope. No resources, sessions, OAuth, or env-var config. The mechanical port is small:from mcp.server.fastmcp import FastMCP→from mcp.server import MCPServerFastMCP("cfgit")→MCPServer("cfgit")Must verify during the port (v2 breaking changes that could bite us):
mcp-typessplit into a standalone package (any types we import).mcp>=2,<3and unpin the test guard once ported.Features actually worth adopting (for our surface)
cfg_*calls are slow/failing in an agent session with zero instrumentation. Highest-value, lowest-effort win.Mcp-Session-Id, no session state), so this is a natural fit and more robust for the "spawn cfg-mcp per agent turn" pattern.Bigger, optional redesign (separate decision)
cfg_show,cfg_log,cfg_status,cfg_diff) to resources likecfg://{env}/{collection}/{id}@{ref}so agents can browse records. More idiomatic, but a real rework, not a drop-in.cfg_impact --llmnarration.author/attribution system. Design question, not a quick adopt.Not relevant to us
Resolver dependency injection, client-side subscriptions, extension APIs — for complex/multi-round-trip servers; our flat wrappers don't need them.
Refs