Skip to content

fix(schemas): widen ServerCapabilities capability fields from Dict[str, bool] to Dict[str, Any] to match MCP SDK permissive approach#3185

Merged
crivetimihai merged 2 commits intomainfrom
fix/server-capabilities-tools-type-too-strict
Feb 26, 2026
Merged

fix(schemas): widen ServerCapabilities capability fields from Dict[str, bool] to Dict[str, Any] to match MCP SDK permissive approach#3185
crivetimihai merged 2 commits intomainfrom
fix/server-capabilities-tools-type-too-strict

Conversation

@crivetimihai
Copy link
Copy Markdown
Member

Note: This PR was re-created from #3075 due to repository maintenance. Your code and branch are intact. @omorros please verify everything looks good.

🔗 Related Issue Closes #3063 --- ## 📝 Summary

The MCP SDK's ToolsCapability uses extra: "allow", so MCP servers can return arbitrary extra fields in their
capabilities response. Our ServerCapabilities model typed prompts, resources, and tools as Dict[str, bool], which
rejects non-boolean values during PydanticGateway.model_validate() when plugins are enabled. Widened these three fields to
Dict[str, Any] to match the SDK's permissive approach.


🏷️ Type of Change

  • Bug fix

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes (optional)

Single file change (mcpgateway/common/models.py). Existing tests continue to pass since boolean values are valid Any. No
new tests needed as the fix is purely relaxing a type constraint.

@crivetimihai crivetimihai added this to the Release 1.0.0-GA milestone Feb 24, 2026
@crivetimihai crivetimihai added bug Something isn't working mcp-protocol Alignment with MCP protocol or specification MUST P1: Non-negotiable, critical requirements without which the product is non-functional or unsafe labels Feb 24, 2026
@omorros
Copy link
Copy Markdown
Contributor

omorros commented Feb 24, 2026

Hi @crivetimihai thanks for reopening this! I've verified the code, everything looks good, intact and matching my original changes. Ready for review whenever you get the chance. Thanks!

@kevalmahajan kevalmahajan force-pushed the fix/server-capabilities-tools-type-too-strict branch from 75cd2f0 to 0a58981 Compare February 25, 2026 13:00
@kevalmahajan kevalmahajan added the wxo wxo integration label Feb 25, 2026
@kevalmahajan kevalmahajan self-requested a review February 25, 2026 13:08
kevalmahajan
kevalmahajan previously approved these changes Feb 25, 2026
@crivetimihai crivetimihai self-assigned this Feb 26, 2026
omorros and others added 2 commits February 26, 2026 18:09
…r, bool] to Dict[str, Any] to match MCP SDK permissive approach

Closes #3063

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
…d tests

Apply the same Dict[str, bool] -> Dict[str, Any] widening to
ClientCapabilities.roots for consistency: the MCP SDK's
RootsCapability also uses extra="allow", so non-boolean values
must be accepted.

Add test_server_capabilities_non_boolean_values to both
test_models.py and test_schemas.py to verify the type widening
actually accepts strings, ints, and nested dicts.

Closes #3063

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai
Copy link
Copy Markdown
Member Author

Review

Reviewed and rebased onto main (clean, no conflicts).

Original change (correct): Widens ServerCapabilities.prompts, .resources, .tools from Dict[str, bool] to Dict[str, Any] to match the MCP SDK's extra="allow" on ToolsCapability, PromptsCapability, and ResourcesCapability. All downstream consumers (gateway_service, notification_service, session_registry) use defensive .get() with bool() wrapping — no code assumes top-level dict values are booleans.

Review fix committed:

Checks:

  • No security concerns — type relaxation on internal Pydantic model, no new input paths.
  • No performance impact.
  • 99% coverage on models.py (1 uncovered line is unrelated AnyUrl.__eq__).
  • 1055 tests passed across model, schema, main endpoint, session registry, notification, and gateway service suites. Zero failures.

LGTM ✅

@crivetimihai crivetimihai merged commit 98f283e into main Feb 26, 2026
31 checks passed
@crivetimihai crivetimihai deleted the fix/server-capabilities-tools-type-too-strict branch February 26, 2026 18:48
MohanLaksh pushed a commit that referenced this pull request Mar 12, 2026
…r, bool] to Dict[str, Any] to match MCP SDK permissive approach (#3185)

* fix(schemas): widen ServerCapabilities capability fields from Dict[str, bool] to Dict[str, Any] to match MCP SDK permissive approach

Closes #3063

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>

* fix(schemas): widen ClientCapabilities.roots to Dict[str, Any] and add tests

Apply the same Dict[str, bool] -> Dict[str, Any] widening to
ClientCapabilities.roots for consistency: the MCP SDK's
RootsCapability also uses extra="allow", so non-boolean values
must be accepted.

Add test_server_capabilities_non_boolean_values to both
test_models.py and test_schemas.py to verify the type widening
actually accepts strings, ints, and nested dicts.

Closes #3063

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>

---------

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Co-authored-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working mcp-protocol Alignment with MCP protocol or specification MUST P1: Non-negotiable, critical requirements without which the product is non-functional or unsafe wxo wxo integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][API]: ServerCapabilities.tools type too strict — rejects MCP servers with extra capability fields

3 participants