Conversation
- Add --disable-dns-rebinding-protection, --allowed-hosts, --allowed-origins CLI flags - Move transport security from module-level init to main() (after argparse) - Apply transport security only for SSE and streamable-http transports (not stdio) - Env vars (POSTGRES_MCP_*) override CLI flags when both are set - Add comprehensive test suite: 10 scenarios × 2 transports = 20 tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align with the shorter MCP_* naming convention used in the original PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename MCP_DNS_REBINDING_PROTECTION to MCP_ENABLE_DNS_REBINDING_PROTECTION - Add monkeypatch fixture to clear MCP_* env vars in tests - Remove coupling to FastMCP upstream defaults in test_default_defers_to_fastmcp - Update README with CLI flags documentation table Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use MCP_ENABLE_DNS_REBINDING_PROTECTION env var name (matching upstream) - Add monkeypatch env cleanup in tests to prevent flakiness - Remove coupling to FastMCP upstream defaults in tests - Update README with CLI flags + env vars documentation table Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hancements feat: add CLI flags and tests for transport security
|
+1 — would love to see this land. We hit the same DNS-rebinding 421 wiring postgres-mcp 0.3.0 (rebuilt from main HEAD Two CLI flags you've added ( Issue #145 reports the same gotcha for a docker compose deployment. Common pattern: any non-localhost host binding triggers this. While waiting for #144 to land, we vendored a minimal hotfix in our fork as a stopgap (drops |
jssmith
left a comment
There was a problem hiding this comment.
Review: Transport security configuration with DNS rebinding protection
Verdict: Approve with comments.
Assessment
Exposes MCP's built-in TransportSecuritySettings (DNS rebinding protection, allowed hosts/origins) via CLI flags and env vars. Applies only to sse and streamable-http transports, not stdio.
Strengths
- Env vars take precedence over CLI flags — sensible for Docker deployments where env vars are the primary config method.
- Test suite is comprehensive — 11 tests covering CLI flag, env var, env-overrides-CLI, default behavior, and arg ordering (database URL after flags). Parametrized across both
sseandstreamable-http. - The
_preserve_mcp_statefixture restoresmcp.settings.transport_securityandsys.argvafter each test — good test hygiene. - README table clearly documents flags, env vars, defaults, and includes a Docker example.
Comments
-
from mcp.server.transport_security import TransportSecuritySettings— this import depends on themcppackage version supportingtransport_security. Themcp < 2constraint from PR #197 should be fine, but verify this module exists in mcp 1.29.0. If it was added later, this could break on older 1.x versions. -
The
**{...} if hosts else {}dict-spread pattern is used to conditionally passallowed_hosts/allowed_originstoTransportSecuritySettings. This works but is slightly hard to read. Consider building a kwargs dict explicitly. -
protection_off = dns_env.lower() in ("false", "0", "no")— good handling of boolean env var parsing. The CLI flag--disable-dns-rebinding-protectionisstore_true, so the logic correctly prefers the env var when set.
This review was created by an AI agent (OpenHands) on behalf of @jssmith.
jssmith
left a comment
There was a problem hiding this comment.
Review — concise
Verdict: Approve with comments. Well-structured security feature with comprehensive tests.
Strengths
- DNS rebinding protection for SSE and streamable-http transports. Correctly skips
stdio. - CLI flags + env vars with env taking precedence. Standard pattern.
TransportSecuritySettingsapplied only when overrides are present — defaults defer to FastMCP.- Tests are excellent: 10 test cases covering CLI flags, env vars, env-overrides-CLI, env-true-overrides-CLI-disable, default behavior, and positional arg after flags. Parametrized for both
sseandstreamable-http. _preserve_mcp_statefixture cleanly restores state between tests.- README documentation includes a table and JSON config example.
Issues to address
1. TransportSecuritySettings construction with conditional kwargs (non-blocking)
The **{...} if hosts else {} pattern is functional but hard to read. Consider building a dict first, then unpacking:
settings_kwargs = {"enable_dns_rebinding_protection": not protection_off}
if hosts:
settings_kwargs["allowed_hosts"] = [h.strip() for h in hosts.split(",") if h.strip()]
if origins:
settings_kwargs["allowed_origins"] = [o.strip() for o in origins.split(",") if o.strip()]
mcp.settings.transport_security = TransportSecuritySettings(**settings_kwargs)2. Env var naming inconsistency (non-blocking)
MCP_ENABLE_DNS_REBINDING_PROTECTION is a positive flag (set to false to disable), while the CLI flag is --disable-dns-rebinding-protection (negative flag, set to enable). This inversion could confuse users. The README documents it clearly, but consider aligning the naming.
3. No test for stdio transport (non-blocking)
The tests verify SSE and streamable-http but don't verify that stdio skips transport security setup. A test asserting mcp.settings.transport_security is unchanged for stdio would be useful.
This review was created by an AI agent (OpenHands) on behalf of @jssmith.
|
@jssmith feedback addressed, I hope this lands and can help others :D. |
No description provided.