Skip to content

feat: make the FastMCP access log opt-in - #243

Merged
lesnik512 merged 3 commits into
mainfrom
feat/240-fastmcp-access-log-opt-in
Sep 20, 2026
Merged

lesnik512 merged 3 commits into
mainfrom
feat/240-fastmcp-access-log-opt-in

Conversation

@lesnik512

@lesnik512 lesnik512 commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Closes #240.

FastMCP installed FastMcpLoggingMiddleware by default, so every MCP message produced a log line.
Litestar's equivalent is off by default and #180 made FastAPI's off by default, leaving FastMCP the
only framework logging every message without being asked.

Breaking, deliberately. This removes log output from services that never configured it, and
removes the logging_turn_off_middleware field outright. That is why it is a separate PR from #180:
it needs its own release-note line.

The change

Two lines of production code:

-    logging_turn_off_middleware: bool = False
+    fastmcp_logging_middleware_enabled: bool = False

-        if self.bootstrap_config.logging_turn_off_middleware:
+        if not self.bootstrap_config.fastmcp_logging_middleware_enabled:

All three frameworks now read the same way:

framework field
Litestar litestar_logging_middleware_enabled
FastAPI fastapi_logging_middleware_enabled
FastMCP fastmcp_logging_middleware_enabled

No compatibility shim

FastMcpConfig is frozen, so FastMcpConfig(logging_turn_off_middleware=True) now raises
TypeError at construction. A test pins that, so the break stays deliberate rather than becoming an
accident someone quietly re-adds a field to fix.

AGENTS.md says "a public rename ships a silent alias", worked as
OpentelemetryConfig = OpenTelemetryConfig. That mechanism cannot express a dataclass field, and a
silent alias was never available here anyway: the default flipped from on to off, so a shim would
have had to be a tri-state bool | None distinguishing "never set" from "set to False", plus a
warning, plus a rule for setting both fields. An earlier revision of this PR did exactly that and it
cost more than the break it avoided.

The break is also the better outcome for users. The behaviour change is that log output disappears; a
TypeError makes every service that configured this setting re-decide, where a shim would let them
upgrade past the change without noticing that the default flipped for everyone else in their
codebase.

Tests

Reverting the production file turns four red: not mounted by default, mounted when enabled, the
removed field raising TypeError, and the default/enabled paths warning nothing (the repo sets no
filterwarnings, so a stray warning would otherwise fail no test).

322 tests, ruff, ty, mkdocs build --strict, lychee: all clean.

Docs

docs/integrations/fastmcp.md gains a Logging section with the new default, what gets logged, and
the removal. docs/introduction/configuration.md gains a ### Structlog FastMCP section, which the
issue did not ask for but the other three frameworks already have.

@lesnik512
lesnik512 merged commit 5e96b5c into main Sep 20, 2026
13 checks passed
@lesnik512
lesnik512 deleted the feat/240-fastmcp-access-log-opt-in branch September 20, 2026 13:49
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.

Make the FastMCP access log opt-in, matching Litestar and FastAPI

1 participant