Repository navigation
Description
Summary
gimp_mcp_server.py cannot be imported on any mcp release that a fresh resolve currently produces, so the MCP server process dies before it can serve a single tool.
To be clear which "MCP server" this is about: the in-GIMP socket plugin (Tools > MCP > Start MCP Server, port 9877) is unaffected and works fine. This is the client-side process that an MCP host launches via uv run --directory . gimp_mcp_server.py.
Reproduce
Both documented uv paths fail, for two unrelated reasons.
Path A - committed lock, default interpreter
uv selects the newest available interpreter (3.14 here). The committed uv.lock pins pydantic-core 2.33.2, which publishes no cp314 wheel, so uv falls back to a Rust build that PyO3 refuses:
$ uv sync
x Failed to build `pydantic-core==2.33.2`
|-> The build backend returned an error
`-> Call to `maturin.build_wheel` failed (exit status: 1)
error: failed to run custom build command for `pyo3-ffi v0.24.1`
error: the configured Python interpreter version (3.14) is newer than
uv sync -p 3.13 still succeeds, which is the workaround people settled on in #13.
Path B - refresh the lock
Following the guidance in #13 ("try uv sync --upgrade or delete uv.lock and re-sync"):
$ uv lock --upgrade # resolves mcp 1.29.1, fastmcp 3.4.7
$ uv run -p 3.13 python -c "import gimp_mcp_server"
File "gimp_mcp_server.py", line 88, in <module>
mcp = FastMCP("GimpMCP", description="GIMP integration through MCP - ...")
TypeError: FastMCP.__init__() got an unexpected keyword argument 'description'
This is the same 3.13 interpreter that worked in Path A, so it is not a Python-version problem.
Root cause
FastMCP.__init__ used to end with **settings: Any, which silently absorbed unknown keywords. description= was therefore never actually applied - it was a no-op from the start. That catch-all was removed in mcp 1.13.0, which turns the same call into a hard TypeError.
Measured directly, calling FastMCP('x', description='d') and FastMCP('x', instructions='i') on each release:
| mcp | description= |
instructions= |
|---|---|---|
| 1.10.1 (current lock) | accepted, ignored | works |
| 1.11.0, 1.12.0 | accepted, ignored | works |
| 1.13.0 - 1.29.1 | TypeError | works |
| 2.x | n/a | module is gone |
On mcp 2.x it fails even earlier, and the SDK's own message spells out the remedy:
ModuleNotFoundError: No module named 'mcp.server.fastmcp'. Thi
7C3A
s is mcp 2.x, where
FastMCP was renamed to MCPServer ... or pin 'mcp<2' to keep running v1 code.
Suggested fix
- use
instructions=, the supported field for this text, which works unchanged from 1.10.1 through 1.29.1 - bound the dependency as
mcp>=1.28.1,<2; the floor also clears CVE-2025-66416, CVE-2026-52869 and CVE-2026-59950, and the ceiling keeps v1 API code off the 2.x rename - drop
fastmcpfromdependencies- nothing imports it, the code usesmcp.server.fastmcpwhich ships insidemcp - refresh
uv.locksopydantic-coreis new enough to have 3.14 wheels
I have this working locally and will open a PR shortly.
Environment
- GIMP 3.2.4 on macOS (Apple silicon)
- verified
uv sync+import gimp_mcp_serveron Python 3.11, 3.12, 3.13 and 3.14 after the fix
Activity