mcp 2.0.0 was released on 2026-07-28, implementing MCP protocol revision 2026-07-28. Serena currently pins mcp==1.28.1, and the upgrade cannot be a plain version bump: the SDK renamed mcp.server.fastmcp to mcp.server.mcpserver, renamed FastMCP to MCPServer, and removed some symbols Serena imports. On mcp==2.0.0 the current code fails at import:
src/serena/tools/tools_base.py:11: in <module>
from mcp.server.fastmcp import Context
E ModuleNotFoundError: No module named 'mcp.server.fastmcp'
Opening this first rather than sending a PR straight away, since CONTRIBUTING.md asks for an issue when a change affects behaviour, and two user-visible behaviours do change. I have a working branch ready and will link it below.
What the upgrade requires
Mechanical:
- Import path renames in
src/serena/mcp.py, src/serena/tools/tools_base.py, test/serena/test_mcp.py.
ToolAnnotations fields are now snake_case (readOnlyHint -> read_only_hint, destructiveHint -> destructive_hint).
Context lost its ServerSessionT type parameter (3 -> 2); ServerSessionT no longer exists. The base Tool.run() also no longer accepts an optional context.
Behaviour-affecting, and the reason for this issue:
-
FASTMCP_* environment variables no longer configure the server. SerenaMCPFactory.create_mcp_server() currently does Settings.model_config = SettingsConfigDict(env_prefix="FASTMCP_") to stop .env files in user projects from overriding MCP settings. In mcp 2.0 Settings is no longer a pydantic-settings BaseSettings; it is a plain pydantic BaseModel populated from the MCPServer constructor, so it reads neither the environment nor .env files.
Worth flagging explicitly: that assignment does not raise on 2.0, it simply stops doing anything, so the tests stay green either way. The .env problem the override existed to solve is now handled by the SDK itself, so my branch deletes the override (which also drops the need for pydantic-settings, previously transitive via mcp 1.x). But losing FASTMCP_* support is a real change for anyone relying on it, and whether you want it reintroduced explicitly is your call, not something I wanted to decide in a migration PR.
-
create_mcp_server() no longer accepts host/port. The SDK moved them from the MCPServer constructor to the transport-specific run() call. My branch drops them from the factory signature and has cli.py pass them to server.run() for non-stdio transports. Only one in-repo caller exists, but the factory is plausibly used externally, so an alternative is keeping the parameters on the factory and storing them until run().
There is a related trap I hit that is worth recording: from mcp.server.mcpserver import server must bind the submodule, not the package, or the existing server.configure_logging override in mcp.py silently stops taking effect (the SDK reads that name from mcp/server/mcpserver/server.py's own namespace). Both of Serena's SDK monkey-patches fail invisibly under a naive port.
Status of the branch
ty check and ruff clean, test/serena/test_mcp.py 64/64, and test/serena 746 passed / 14 failed, where all 14 failures are Go/Rust/C#/PowerShell language-server tests failing on this machine for want of those toolchains (RuntimeError: Go is not installed) and are unrelated to the upgrade.
Happy to adjust either behavioural decision above, or to split the change, whichever you prefer.
mcp2.0.0 was released on 2026-07-28, implementing MCP protocol revision2026-07-28. Serena currently pinsmcp==1.28.1, and the upgrade cannot be a plain version bump: the SDK renamedmcp.server.fastmcptomcp.server.mcpserver, renamedFastMCPtoMCPServer, and removed some symbols Serena imports. Onmcp==2.0.0the current code fails at import:Opening this first rather than sending a PR straight away, since CONTRIBUTING.md asks for an issue when a change affects behaviour, and two user-visible behaviours do change. I have a working branch ready and will link it below.
What the upgrade requires
Mechanical:
src/serena/mcp.py,src/serena/tools/tools_base.py,test/serena/test_mcp.py.ToolAnnotationsfields are now snake_case (readOnlyHint->read_only_hint,destructiveHint->destructive_hint).Contextlost itsServerSessionTtype parameter (3 -> 2);ServerSessionTno longer exists. The baseTool.run()also no longer accepts an optional context.Behaviour-affecting, and the reason for this issue:
FASTMCP_*environment variables no longer configure the server.SerenaMCPFactory.create_mcp_server()currently doesSettings.model_config = SettingsConfigDict(env_prefix="FASTMCP_")to stop.envfiles in user projects from overriding MCP settings. Inmcp2.0Settingsis no longer a pydantic-settingsBaseSettings; it is a plain pydanticBaseModelpopulated from theMCPServerconstructor, so it reads neither the environment nor.envfiles.Worth flagging explicitly: that assignment does not raise on 2.0, it simply stops doing anything, so the tests stay green either way. The
.envproblem the override existed to solve is now handled by the SDK itself, so my branch deletes the override (which also drops the need for pydantic-settings, previously transitive via mcp 1.x). But losingFASTMCP_*support is a real change for anyone relying on it, and whether you want it reintroduced explicitly is your call, not something I wanted to decide in a migration PR.create_mcp_server()no longer acceptshost/port. The SDK moved them from theMCPServerconstructor to the transport-specificrun()call. My branch drops them from the factory signature and hascli.pypass them toserver.run()for non-stdio transports. Only one in-repo caller exists, but the factory is plausibly used externally, so an alternative is keeping the parameters on the factory and storing them untilrun().There is a related trap I hit that is worth recording:
from mcp.server.mcpserver import servermust bind the submodule, not the package, or the existingserver.configure_loggingoverride inmcp.pysilently stops taking effect (the SDK reads that name frommcp/server/mcpserver/server.py's own namespace). Both of Serena's SDK monkey-patches fail invisibly under a naive port.Status of the branch
ty checkandruffclean,test/serena/test_mcp.py64/64, andtest/serena746 passed / 14 failed, where all 14 failures are Go/Rust/C#/PowerShell language-server tests failing on this machine for want of those toolchains (RuntimeError: Go is not installed) and are unrelated to the upgrade.Happy to adjust either behavioural decision above, or to split the change, whichever you prefer.