Skip to content

Conversation

@vincent0426
Copy link

Added $ref resolution for requestedSchema.properties before SDK validation. When incoming requests contain $ref references in their schema properties, they are automatically resolved before reaching the SDK's validation layer.

Before the fix

Error executing tool book_table: [
  {
    "code": "invalid_union",
    "unionErrors": [
      {
        "issues": [
          {
            "code": "invalid_literal",
            "expected": "boolean",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "type"
            ],
            "message": "Invalid literal value, expected \"boolean\""
          },
          {
            "code": "invalid_type",
            "expected": "boolean",
            "received": "string",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "default"
            ],
            "message": "Expected boolean, received string"
          }
        ],
        "name": "ZodError"
      },
      {
        "issues": [
          {
            "code": "invalid_literal",
            "expected": "string",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "type"
            ],
            "message": "Invalid literal value, expected \"string\""
          }
        ],
        "name": "ZodError"
      },
      {
        "issues": [
          {
            "expected": "'number' | 'integer'",
            "received": "undefined",
            "code": "invalid_type",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "type"
            ],
            "message": "Required"
          }
        ],
        "name": "ZodError"
      },
      {
        "issues": [
          {
            "code": "invalid_literal",
            "expected": "string",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "type"
            ],
            "message": "Invalid literal value, expected \"string\""
          },
          {
            "code": "invalid_type",
            "expected": "array",
            "received": "undefined",
            "path": [
              "params",
              "requestedSchema",
              "properties",
              "fruit",
              "enum"
            ],
            "message": "Required"
          }
        ],
        "name": "ZodError"
      }
    ],
    "path": [
      "params",
      "requestedSchema",
      "properties",
      "fruit"
    ],
    "message": "Invalid input"
  }
]

After
Screenshot 2025-11-01 at 9 10 42 PM

Motivation and Context

While playing around with python enum elicitation requests, when MCP servers send elicitation requests (or any requests) with $ref references in requestedSchema.properties (e.g., { $ref: "#/properties/nameDef" }), the SDK attempts to validate these schemas before our handlers can process them. Unresolved $ref references can cause validation failures.

This change intercepts incoming messages at the transport level (before validation) and resolves all $ref references in requestedSchema.properties, ensuring the SDK receives fully resolved schemas that validate correctly.

How Has This Been Tested?

Added a new unit test:

  • Creates a mock request with $ref in requestedSchema.properties
  • Verifies the ref is resolved to actual schema values before reaching the protocol handler
  • Confirms the resolved schema contains the expected values

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

@olaservo olaservo mentioned this pull request Nov 4, 2025
@cliffhall cliffhall added the duplicate This issue or pull request already exists label Nov 4, 2025
@cliffhall
Copy link
Member

Hi @vincent0426 thanks for this, but we just merged a change #889 last week that addresses this specific issue.

@cliffhall cliffhall closed this Nov 4, 2025
@vincent0426
Copy link
Author

Hi @cliffhall, thanks for the response, but I think they address different issues. This PR fixes request handling (e.g., schemas sent by elicitation), while #889 addresses tool rendering. I’m still seeing the error on the latest version which fails before the handler, during validation against ElicitRequestSchema.

client.setRequestHandler(ElicitRequestSchema, async (request) => {

Screenshot 2025-11-04 at 7 47 50 AM

@cliffhall cliffhall reopened this Nov 4, 2025
Copy link
Member

@cliffhall cliffhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hoping we can avoid adding even more logic to useConnection by extracting the bulk of the change to schemaUtils.ts

@vincent0426 vincent0426 force-pushed the fix/resolve-ref-pre-validation branch from 37b99b3 to b000fc2 Compare November 4, 2025 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants