Skip to content

fix(templates): port python-mcp-proxy to mcp 2 and bump fastmcp to v4 - #917

Open
l2ysho wants to merge 1 commit into
masterfrom
fix/mcp-2-and-fastmcp-4
Open

fix(templates): port python-mcp-proxy to mcp 2 and bump fastmcp to v4#917
l2ysho wants to merge 1 commit into
masterfrom
fix/mcp-2-and-fastmcp-4

Conversation

@l2ysho

@l2ysho l2ysho commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Note

TL;DR
fastmcp 4 #911 could not be closed alone. All required stuff updated in this PR.

Why #911 is red

#911 bumps fastmcp to >=4.0.2 but leaves mcp >= 1.25.0, < 2.0.0 next to it. Every Python lint and type-check leg dies in ~8s, before linting starts:

× No solution found when resolving dependencies for split
╰─▶ Because fastmcp-slim[client]>=4.0.2 depends on mcp>=2.0.0,<3.0.0 and
    fastmcp>=4.0.2 depends on fastmcp-slim[client]==4.0.2 ... your project's
    requirements are unsatisfiable.

renovate/artifacts on that PR fails for the same reason — Renovate could not regenerate uv.lock.

Why Renovate cannot finish it

Widening mcp to >= 2.0.0, < 3.0.0 resolves, but ty check then reports 34 diagnostics, all in templates/python-mcp-proxy/my_actor/mcp_gateway.py. mcp 2 is a breaking rewrite of the low-level server API the proxy is built on:

Was (mcp 1) Is (mcp 2)
app.request_handlers[types.XRequest] = fn Server(..., on_x=fn) — constructor kwargs
handler takes a Request, returns types.ServerResult(result) handler takes (ctx, params), returns the result type directly
types.ServerResult(...) callable wrapper plain union — not callable
response.serverInfo response.server_info
CallToolResult(isError=True) CallToolResult(is_error=True)
req.params.progressToken params.progress_token

And one break the type checker never saw, because the import is resolved at runtime:

ImportError: cannot import name 'streamablehttp_client' from 'mcp.client.streamable_http'

mcp 2 renamed it to streamable_http_client, dropped the per-call HTTP kwargs in favour of a pre-built client, and yields two streams instead of three.

What this PR does

Pinspyproject.toml, templates/python-mcp-empty/requirements.txt, templates/python-mcp-proxy/requirements.txt:

  • fastmcp>= 4.0.2, < 5.0.0
  • mcp>= 2.0.0, < 3.0.0

Porttemplates/python-mcp-proxy/my_actor/:

  • mcp_gateway.py rewritten against the on_* constructor API. Handlers are collected per advertised capability and passed to Server(...) in one go. Whitelist filtering, tool-call charging and the unauthorized-tool error path are unchanged.
  • server.pystreamable_http_client, with headers/timeout/auth moved into a create_mcp_http_client(...) passed as http_client=.
  • models.py, server.pyhttpxhttpx2. mcp 2 runs on httpx2 and the auth field is handed straight to it, so the template would otherwise ship two HTTP stacks. httpx stays in the root env; python-beautifulsoup and python-start still use it.

Behavior changes worth a reviewer's eye

Two handlers are dropped, because mcp 2 emits a runtime MCPDeprecationWarning at Server(...) construction for each:

  • logging/setLevel forwarding — "The logging capability is deprecated as of 2026-07-28 (SEP-2577)."
  • client-to-server progress forwarding — "Client-to-server progress is deprecated as of 2026-07-28; progress is server-to-client only."

resources/subscribe and resources/unsubscribe are kept, so the proxy still works in front of a 2025-era remote. Only the client-side calls are deprecated, not the handler slots, so they cost one # ty: ignore[deprecated] each and no runtime warning.

Say the word if you would rather keep logging and progress and accept the startup warnings.

Verification

Local, against the real packages (fastmcp 4.0.2, mcp 2.1.1):

  • uv run poe lint — clean. uv run poe type-checkAll checks passed! (was 34 diagnostics).
  • Gateway end to end, in-memory: upstream server → create_gateway → client. Tool list filtered to the whitelist, allowed call proxied, unauthorized call returns is_error=True with the right message, charging fired once with the configured count ('search_papers', 2), prompts proxied, upstream name/version forwarded.
  • HTTP branch end to end, over a real socket: a FastMCP streamable-http server on one port, ProxyServer(server_type=HTTP) on another. Through the proxy: initialize reports the upstream's upstream-http 9.9.9, list_tools['echo'], call_toolecho: hello.
  • python-mcp-empty under fastmcp 4: server builds, list_tools['add'], add(2,3) returns the expected structured content, http_app(transport='streamable-http') still constructs.
  • Both templates' requirements.txt resolve on their own (arxiv-mcp-server included).

Follow-ups, not in this PR

  • SessionTrackingMiddleware / create_starlette_app still call session_manager.handle_request, which mcp 2 keeps. No change needed, but the newer asgi_app is the forward path.
  • python-mcp-proxy/README.md:128 points at src/mcp_gateway.py; the file lives in my_actor/. Pre-existing.
  • mcp 2 offers on_subscriptions_listen as the replacement for resource subscriptions. Wiring the proxy through it is a design change, not a port.

Close #911 once this is green.

🤖 Generated with Claude Code

fastmcp 4 requires mcp >= 2.0.0, so the two pins have to move together.
mcp 2 replaces the low-level Server handler dicts with constructor-based
on_* handlers, renames camelCase result fields, and drops
streamablehttp_client, so python-mcp-proxy needs a port to go with the bump.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added this to the 148th sprint - Tooling team milestone Sep 4, 2026
@github-actions github-actions Bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Sep 4, 2026
@l2ysho l2ysho added t-builders Issues owned by the Builders team. and removed t-tooling Issues with this label are in the ownership of the tooling team. labels Sep 4, 2026
@l2ysho
l2ysho marked this pull request as ready for review September 4, 2026 20:16
@l2ysho
l2ysho requested a review from DaveHanns as a code owner September 4, 2026 20:16
@l2ysho
l2ysho requested a review from vdusek September 4, 2026 20:21
@l2ysho

l2ysho commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@vdusek can you pls take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-builders Issues owned by the Builders team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants