Skip to content

chore(deps): bump fastmcp to >=3.2.0,<4 and move black to dev extra#134

Merged
dsonyy merged 4 commits into
golf-mcp:mainfrom
dsonyy:chore/fastmcp-3-security
May 7, 2026
Merged

chore(deps): bump fastmcp to >=3.2.0,<4 and move black to dev extra#134
dsonyy merged 4 commits into
golf-mcp:mainfrom
dsonyy:chore/fastmcp-3-security

Conversation

@dsonyy

@dsonyy dsonyy commented May 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Bumps fastmcp from >=2.14.0,<2.15.0 to >=3.2.0,<4.0.0 to pick up upstream OAuth proxy and OpenAPI security patches.
  • Moves black out of runtime dependencies into a new [project.optional-dependencies].dev extra (and matching Poetry dev group). Black is build-time only and no longer ships in production installs.
  • Lazy-imports black inside golf.core.builder so the production import path no longer requires it. If golf build is run without black installed, a warning is printed and generated code is written unformatted.
  • Updates CI to install .[dev] so test and lint jobs still get black, pytest, ruff, mypy. (Previously the workflow installed .[telemetry], which is not a defined extra.)

Advisories closed

Advisory CVE GitHub severity Client-listed severity Patched in
GHSA-rww4-4w9c-7733 CVE-2026-27124 High High fastmcp 3.2.0
GHSA-vv7q-7jx5-f767 CVE-2026-32871 High Medium fastmcp 3.2.0
GHSA-5h2m-4q8j-pqpj CVE-2025-69196 Medium High fastmcp 2.14.2 / 3.2.0
GHSA-m8x7-r2rg-vh5g CVE-2025-64340 Medium (not flagged) fastmcp 3.2.0
(psf/black) CVE-2026-32274 resolved by removing black from production install

The two High fastmcp advisories require 3.2.0 — no 2.x backport. Severity column uses GitHub Security Advisory data; the client classified 69196 and 32871 differently. Coverage is identical regardless of classification.

Why black is moved, not just version-bumped

Black is a code formatter. It is invoked exclusively from golf.core.builder during golf build to format generated server.py. The generated server.py does not import golf.core.builder, so production runtimes have no need for black. Keeping it as a runtime dep was forcing it into production images and tripping security scanners on CVE-2026-32274.

After this PR:

  • pip install golf-mcp → black not installed. Sec scanner finds nothing.
  • pip install golf-mcp[dev] → black 26.3.1 installed for golf build and tests.

Compatibility

  • All 284 existing tests pass against fastmcp 3.2.4 with [dev] installed.
  • Production import path verified: python -c "from golf.core import builder" succeeds with black absent.
  • fastmcp imports used by golf-mcp (FastMCP, JWTVerifier, StaticTokenVerifier, OAuthProvider, RemoteAuthProvider, AuthProvider, middleware, dependencies, context) are stable across fastmcp 2.x → 3.x — no code changes required for the bump.

Behavioral change to flag

Users who previously ran pip install golf-mcp and then golf build will now see a warning instead of a black-formatted output, because black is no longer pulled in by default. They need pip install golf-mcp[dev] (or to install black themselves) to restore formatting. Generated code is functionally identical — only formatting differs.

Test plan

  • pytest tests/ with [dev] — 284 passed, 1 skipped
  • python -c "from golf.core import builder" without [dev] — succeeds
  • CI: lint pass, test pass with .[dev]
  • Cut new release; downstream golf-mcp-enterprise PR (golf-mcp/golf-enterprise#22) depends on this

Note on access

Authored from a fork because the contributor only has READ permission on golf-mcp/golf. Happy to re-push to a branch on this repo if write access is granted.

dsonyy added 4 commits May 6, 2026 13:35
Resolves multiple security advisories that are only patched in fastmcp 3.2.0:
- GHSA-rww4-4w9c-7733 / CVE-2026-27124 (High): OAuth proxy confused-deputy
- GHSA-vv7q-7jx5-f767 / CVE-2026-32871 (High): OpenAPI provider SSRF / path traversal
- GHSA-5h2m-4q8j-pqpj / CVE-2025-69196: OAuth token reuse across MCP servers
- GHSA-m8x7-r2rg-vh5g / CVE-2025-64340: Command injection via server name

Also moves black from runtime dependencies to the new `dev` extra, so it is
no longer pulled into production container images. Resolves CVE-2026-32274
(arbitrary file write via unsanitized cache filename in black 25.9.0) for
downstream services that scan production images.

All 284 existing tests pass against fastmcp 3.2.4.
Initial commit moved black to a dev extra to resolve CVE-2026-32274
(arbitrary file write via unsanitized cache filename in black 25.9.0).
That broke CI: black is imported at module import time in
src/golf/core/builder.py and is genuinely used at runtime to format
generated server.py output. Tests assert on black-formatted output
(double-quoted strings, etc.) so removing it changes generated code
behavior, not just dev tooling.

CVE-2026-32274 is patched in black 26.3.1. Pinning black>=26.3.1 closes
the finding while keeping black available at runtime so generated code
formatting is unchanged.

All 284 existing tests pass against fastmcp 3.2.4 and black 26.3.1.
Black is build-time only — it formats generated server.py inside
golf.core.builder during `golf build`. The generated server.py itself
does not import golf.core.builder at runtime, so production installs
have no need for black. Keeping black as a runtime dep was forcing the
package into production container images and tripping security scanners
on CVE-2026-32274 even after the version bump.

Changes:
- Move black from [project].dependencies and [tool.poetry].dependencies
  into the new [project.optional-dependencies].dev extra (and the
  existing [tool.poetry.group.dev.dependencies] block).
- Lazy-import black inside builder.py format calls. Production import
  path no longer touches black. If `golf build` is run without black
  installed, a yellow warning is printed and generated code is written
  unformatted.
- Update CI workflow to install `.[dev]` so test/lint jobs still get
  black + pytest + ruff + mypy. (Previously installed `.[telemetry]`,
  which is not a defined extra in this repo.)

Result for downstream consumers:
- `pip install golf-mcp` → no black, no CVE-2026-32274 finding.
- `pip install golf-mcp[dev]` → black 26.3.1, full tooling for
  developers running `golf build` and the test suite.

All 284 existing tests pass against fastmcp 3.2.4 + black 26.3.1
when installed with [dev]. Builder is importable without black.
…tMCP() ctor kwarg

fastmcp 3.x removed the stateless_http kwarg from FastMCP() (see
fastmcp/server/server.py: _REMOVED_KWARGS). The kwarg now lives on
run_http_async() / http_app(). The builder still emitted

    mcp = FastMCP("name", auth=auth_provider, stateless_http=True)

into generated dist/server.py, so any server with stateless_http: true in
golf.json crashes on import:

    TypeError: FastMCP() no longer accepts `stateless_http`. Pass
    `stateless_http` to `run_http_async()` or `http_app()`, or set
    FASTMCP_STATELESS_HTTP.

Drop the ctor emission. Append `, stateless_http=True` to the streamable-http
mcp.run() call sites instead. stdio and sse transports are unaffected.
@dsonyy dsonyy force-pushed the chore/fastmcp-3-security branch from fd56e37 to 35286d2 Compare May 7, 2026 10:50
@dsonyy dsonyy merged commit b1223f7 into golf-mcp:main May 7, 2026
2 checks passed
@dsonyy dsonyy deleted the chore/fastmcp-3-security branch May 7, 2026 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant