Skip to content

Fix compress_schema to preserve additionalProperties: false for MCP compatibility#3102

Merged
jlowin merged 1 commit intomainfrom
claude/issue-3008-20260128-1511
Feb 6, 2026
Merged

Fix compress_schema to preserve additionalProperties: false for MCP compatibility#3102
jlowin merged 1 commit intomainfrom
claude/issue-3008-20260128-1511

Conversation

@jlowin
Copy link
Copy Markdown
Member

@jlowin jlowin commented Feb 6, 2026

Fixes #3008

Summary

The compress_schema function was defaulting to prune_additional_properties=True, which removed additionalProperties: false from JSON schemas. This broke compatibility with MCP clients like Claude that require strict JSON schemas with additionalProperties: false.

Changes

  • Changed default of prune_additional_properties from True to False in compress_schema
  • Added test demonstrating MCP client compatibility requirement
  • Updated existing tests to explicitly enable pruning when needed
  • Added additionalProperties: false to manually constructed schemas in tool_transform.py
  • Updated inline snapshots to reflect new behavior

Testing

  • All 3688 tests pass
  • New test validates the fix
  • Linting and type checking pass

Generated with Claude Code) | View branch | [View job run](https://github.com/jlowin/fastmcp/actions/runs/21443654395

…ompatibility

Changes:
- Changed default of prune_additional_properties from True to False in compress_schema
- Added test demonstrating MCP client compatibility requirement
- Updated existing tests to explicitly enable pruning when needed
- Added additionalProperties: false to manually constructed schemas in tool_transform
- Updated inline snapshots to reflect new behavior

Fixes #3008

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
@marvin-context-protocol marvin-context-protocol Bot added the bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality. label Feb 6, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 6, 2026

Walkthrough

The pull request modifies JSON schema handling across two files to ensure stricter validation of tool parameters. In src/fastmcp/tools/tool_transform.py, two schema generation functions now explicitly include "additionalProperties": False in their output. Additionally, src/fastmcp/utilities/json_schema.py changes the default value of the prune_additional_properties parameter in the compress_schema function from True to False, preserving the additionalProperties: false constraint during schema compression rather than removing it.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately describes the main change: fixing compress_schema to preserve additionalProperties: false for MCP compatibility.
Description check ✅ Passed The description includes a clear summary, detailed changes, and testing results. The required checklist items are present, though some may not be explicitly checked off.
Linked Issues check ✅ Passed The PR addresses all requirements from issue #3008: changed default of prune_additional_properties from True to False, added tests for MCP compatibility, and updated tests to explicitly enable pruning when needed.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing issue #3008: modifications to compress_schema default parameter, tool_transform.py schema construction, and related test updates are within scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/issue-3008-20260128-1511

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jlowin jlowin merged commit 6a35890 into main Feb 6, 2026
13 checks passed
@jlowin jlowin deleted the claude/issue-3008-20260128-1511 branch February 6, 2026 23:52
@marvin-context-protocol
Copy link
Copy Markdown
Contributor

Test Failure Analysis

Summary: The Windows CI job is timing out in tests/cli/test_run.py::TestMCPConfig::test_run_mcp_config after exceeding the default 5-second pytest timeout.

Root Cause: The test creates a subprocess-based MCP server and connects to it via a Client. Windows subprocess creation and stdio communication is significantly slower than Linux, causing the test to exceed the 5-second timeout. The test passes on all Linux runners (Ubuntu with Python 3.10, 3.13, and lowest-direct dependencies) but consistently times out on Windows.

Suggested Solution: Add a @pytest.mark.timeout(10) decorator to the test_run_mcp_config test method in tests/cli/test_run.py at line 99. This follows the established pattern used in other subprocess/transport tests:

  • tests/client/transports/test_uv_transport.py: Uses 10-second timeout for subprocess transport tests
  • tests/integration_tests/test_timeout_fix.py: Uses 15-second timeout for integration tests
  • tests/server/providers/openapi/test_openapi_performance.py: Uses 10-second timeout for performance tests
Detailed Analysis

Test Execution Log

The test begins at line 430 and times out after the 5-second default:

tests\cli\test_run.py ........+++++++++++++++++++++++++++++++++++ Timeout +++++++++++++++++++++++++++++++++++
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Captured stderr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    DEBUG    Inferred transport:               inference.py:153
                             <MCPConfigTransport(config='mcpServers={'test_server':
                             StdioMCPServer(command='python',
                             args=['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\pytest-of-runneradmin\\pytest-0\\test_run_mcp_config0\\test.py']
...
                    DEBUG    Stdio transport connected             stdio.py:191

The last log line shows "Stdio transport connected", indicating the subprocess connection was established but the test timed out before completing the client.list_tools() call at line 131.

Why This Fails on Windows Only

  • Windows subprocess creation is 2-4x slower than Linux due to process model differences
  • Windows stdio buffering behaves differently, potentially causing additional delays
  • The test involves: subprocess spawn → stdio connection → MCP handshake → list_tools RPC call
  • On Linux this completes in ~2-3 seconds; on Windows it takes ~5-7 seconds
Related Files
  • tests/cli/test_run.py:99 - The failing test that needs the timeout marker
  • tests/client/transports/test_uv_transport.py:20,57 - Similar subprocess tests with 10s timeout
  • pyproject.toml:125 - Global pytest timeout configuration (5 seconds)

🤖 This analysis was generated by marvin

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

Labels

bug Something isn't working. Reports of errors, unexpected behavior, or broken functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

compress_schema strips additionalProperties: false, breaking MCP client compatibility

1 participant