novem.comments.MCP() targets the mcp v1 API. mcp 2.0.0 (published 2026-07-28) is a breaking release and the extra is pinned to <2 in #264 as a stopgap. This issue tracks the actual migration.
Verified breaking changes
Established by installing mcp==1.28.1 and mcp==2.0.0 side by side on Python 3.10 and comparing the surfaces novem actually uses:
|
v1.28.1 |
v2.0.0 |
| Server module |
mcp.server.fastmcp |
mcp.server.mcpserver (old path removed) |
| Server class |
FastMCP |
MCPServer |
Tool schema attr |
t.inputSchema |
t.input_schema |
call_tool() returns |
tuple(list[Content], dict) |
CallToolResult (not subscriptable) |
| Image content attr |
item.mimeType |
item.mime_type |
What is not broken, so the migration surface is small: MCPServer(name) and .run(transport='stdio') keep compatible signatures, @server.tool() is unchanged, arbitrary attribute assignment (server.ctx = ...) still works, Image(data=, format=) still works, and v2 installs cleanly on Python 3.10.
Sites to change
novem/comments.py:666 — from mcp.server.fastmcp import FastMCP
novem/comments.py:887 — from mcp.server.fastmcp import Image
novem/comments.py:808 — t.inputSchema raises AttributeError on v2
novem/comments.py:669-670 — bare except ImportError swallows ModuleNotFoundError, producing the misleading "install the mcp extra" message when mcp is installed
examples/mcp_mention_responder.py:110,173 — result[0] raises TypeError: 'CallToolResult' object is not subscriptable
examples/mcp_mention_responder.py:180 — item.mimeType is missing on v2
MCP() docstring references FastMCP (cosmetic)
Proposed approach
Support both majors rather than moving the pin to >=2. novem is a published library and third-party scripts may already be pinned to either major, so the extra should stay open at mcp>=1.0.0.
_check_mcp_deps() tries mcp.server.mcpserver first, falls back to mcp.server.fastmcp, and only reports "install the extra" when mcp itself is genuinely absent — distinguish a missing package from a moved symbol.
api_tools() reads getattr(t, "input_schema", None) or t.inputSchema.
Image import uses the same two-path fallback.
- Update the example to normalize
CallToolResult vs. tuple, and mime_type vs. mimeType.
- Keep
MCP()'s public signature and return contract unchanged.
Add CI coverage
This rotted silently because nothing exercises it: uv sync does not install optional extras and no test imports mcp. The lockfile bump in #263 would have gone green.
Add a job that installs the mcp extra and smoke-tests MCP(...).api_tools() against both majors — asserting the six tool names resolve is enough to catch every break listed above.
novem.comments.MCP()targets the mcp v1 API. mcp 2.0.0 (published 2026-07-28) is a breaking release and the extra is pinned to<2in #264 as a stopgap. This issue tracks the actual migration.Verified breaking changes
Established by installing
mcp==1.28.1andmcp==2.0.0side by side on Python 3.10 and comparing the surfaces novem actually uses:mcp.server.fastmcpmcp.server.mcpserver(old path removed)FastMCPMCPServerToolschema attrt.inputSchemat.input_schemacall_tool()returnstuple(list[Content], dict)CallToolResult(not subscriptable)item.mimeTypeitem.mime_typeWhat is not broken, so the migration surface is small:
MCPServer(name)and.run(transport='stdio')keep compatible signatures,@server.tool()is unchanged, arbitrary attribute assignment (server.ctx = ...) still works,Image(data=, format=)still works, and v2 installs cleanly on Python 3.10.Sites to change
novem/comments.py:666—from mcp.server.fastmcp import FastMCPnovem/comments.py:887—from mcp.server.fastmcp import Imagenovem/comments.py:808—t.inputSchemaraisesAttributeErroron v2novem/comments.py:669-670— bareexcept ImportErrorswallowsModuleNotFoundError, producing the misleading "install the mcp extra" message when mcp is installedexamples/mcp_mention_responder.py:110,173—result[0]raisesTypeError: 'CallToolResult' object is not subscriptableexamples/mcp_mention_responder.py:180—item.mimeTypeis missing on v2MCP()docstring referencesFastMCP(cosmetic)Proposed approach
Support both majors rather than moving the pin to
>=2. novem is a published library and third-party scripts may already be pinned to either major, so the extra should stay open atmcp>=1.0.0._check_mcp_deps()triesmcp.server.mcpserverfirst, falls back tomcp.server.fastmcp, and only reports "install the extra" whenmcpitself is genuinely absent — distinguish a missing package from a moved symbol.api_tools()readsgetattr(t, "input_schema", None) or t.inputSchema.Imageimport uses the same two-path fallback.CallToolResultvs. tuple, andmime_typevs.mimeType.MCP()'s public signature and return contract unchanged.Add CI coverage
This rotted silently because nothing exercises it:
uv syncdoes not install optional extras and no test importsmcp. The lockfile bump in #263 would have gone green.Add a job that installs the
mcpextra and smoke-testsMCP(...).api_tools()against both majors — asserting the six tool names resolve is enough to catch every break listed above.