v0.3.0 - works on mcp 1.x and 2.x
0.2.1 pinned mcp<2 to stop fresh installs dying at import. That was a holding action — it left you stranded on a superseded major. This ports the server properly.
Both majors, no pin
mcp 2.0 renamed FastMCP to MCPServer and moved it to mcp.server.mcpserver. Everything realhands uses is otherwise identical across the two: the .tool() decorator, .run() defaulting to stdio, Image(data=, format=), and a tool returning [str, Image] producing TextContent + ImageContent. So rather than move the pin, it imports either:
try: from mcp.server.mcpserver import MCPServer as _Server, Image # mcp >= 2.0
except: from mcp.server.fastmcp import FastMCP as _Server, Image # mcp 1.xThe dependency is back to an unbounded mcp>=1.2. Verified against mcp 1.29.1 and 2.1.0 — the server imports and registers computer with an identical 9-parameter schema on both.
CI now proves this instead of assuming it
The smoke test is its own job running on windows-latest — the platform this package targets, where pyautogui and pywin32 can actually load — across a matrix of both mcp majors. It imports realhands.server and asserts the tool still exposes action, steps, screenshot, coordinate and monitor. Silently losing the batching parameters would be a worse regression than a hard import error, and only a contract check catches that. Publishing depends on it passing.
Also
GitHub Actions moved off Node 20, which the runners deprecated: checkout v4→v7.0.1, setup-python v5→v7.0.0, upload-artifact v4→v7.0.1, download-artifact v4→v8.0.1 — all repinned to full commit SHAs, since the publish job holds id-token: write.
Upgrade: uvx realhands@latest picks this up on your next client restart. On a pinned install, pip install --upgrade realhands.