Skip to content

Upgrade to mcp 2.0 (MCP protocol revision 2026-07-28) #1776

Description

@Kayaba-Attribution

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:

  1. 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.

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions