Skip to content

Conversation

@ccreighton-apptio
Copy link
Contributor

Adds definitions for params? on all Requests that avoid overwriting extended interfaces, while still allowing base models to be extended with custom functionality, implementing SEP-1319 in the process, and fixing allowance for arbitrary params in 7 models.

Motivation and Context

In #1284, it's suggested to use _meta on tools/list & other requests, but this isn't currently possible.

The cleanest approach, IMO, to solving that issue involves implementing SEP-1319.

While doing so, I believe it would make sense to "bite the bullet" on a breaking change to what I believe is unintentional behavior present in the 7 models which were not affected by _meta erasure.

This PR represents what I believe is the preferred approach over #1520 which does not include the breaking changes to 7 models. If 1520 is merged, this PR will be updated to reflect a continued desire to address the bug that allows usage of arbitrary params in models that don't override them.

Please note that the introduction of non-arbitrary params to any of these 7 models would also be a breaking change in the future unless support for arbitrary params is retained at that time. In the event someone has already made "unofficial" use of the support for arbitrary params, even defining a non-arbitrary param while retaining support for other arbitrary params would also be a potentially breaking change. As a result, I believe it is best to address this issue sooner than later.

How Has This Been Tested?

Defined a sample ListToolsRequest to ensure that both _meta and cursor were supported params:

const listToolsRequest: ListToolsRequest = {
  id: 'foo',
  jsonrpc: "2.0",
  method: "tools/list",
  params: {
    cursor: 'next',
    badKey: 'typescript error here - invalid key',
    _meta: {
      any: 'no typescript error here',
      thing: {
        complex: 'object'
      }
    }
  }
}

Defined a sample PingRequest to ensure that arbitrary params are no longer allowed:

const pingRequest: PingRequest = {
  id: "foo",
  jsonrpc: "2.0",
  method: "ping",
  params: {
    _meta: {
      "anything": ["in", "here"]
    },
    badKey: 'typescript error here - invalid key - this is a "breaking" change',
  },
}

Breaking Changes

Yes, if people have used the spec-supported ability to send arbitrary params for the models which do not override it:

  • previously, [key: string]: unknown; was part of the params definition for any type which didn't override the definition from Request or Notification. If support for arbitrary params was used, this will no longer be allowed.

This is breaking for the following types:

  • PingRequest
  • ListRootsRequest
  • InitializedNotification
  • ResourceListChangedNotification
  • PromptListChangedNotification
  • ToolListChangedNotification
  • RootsListChangedNotification

Please see further discussion here, and follow-up here.

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

@ccreighton-apptio
Copy link
Contributor Author

ccreighton-apptio commented Oct 21, 2025

Note that the failed workflow appears to be an issue with the modelcontextprotocol account, and not with this PR. I have opened a PR in my account to demonstrate that the workflows are passing: ccreighton-apptio#3

The job was not started because your account is locked due to a billing issue.

E: rebased since GHA workflows seem to be happier now

@ccreighton-apptio ccreighton-apptio force-pushed the fix/arbitrary-params-and-meta-erasure branch from 7437471 to 48b7231 Compare October 22, 2025 16:24
@dsp-ant dsp-ant merged commit 266e9a8 into modelcontextprotocol:main Nov 4, 2025
2 checks passed
@dsp-ant
Copy link
Member

dsp-ant commented Nov 4, 2025

Thank you

@ksinder
Copy link

ksinder commented Nov 5, 2025

@ccreighton-apptio @dsp-ant I think this change is causing build failures in the TS SDK now because they don't have complementary type compatibility tests. Mind helping me figure out the right path forward for a (somewhat) unrelated PR of mine: https://github.com/modelcontextprotocol/typescript-sdk/pull/816/files?

@ccreighton-apptio
Copy link
Contributor Author

ccreighton-apptio commented Nov 5, 2025

@ksinder looks like there's a couple things going on - the first is that the removal of arbitrary params is causing some failures, but after that, it looks like I made a mistake while initially combining and later separating ParameterizedRequestParams into individual types:

  • arguments?: { [key: string]: string }; was used by GetPromptRequest
  • arguments?: { [key: string]: unknown }; was used by CallToolRequest, but unknown ended up swapped to string

I've opened #1770 to fix the arguments type change.

Poking at the arbitrary params change, some of that is just removing .passthrough() in a couple places, and a couple others for fixing unknown vs. any mismatches. Beyond those, there are now 18 new types. I've opened modelcontextprotocol/typescript-sdk#1084 with the passthrough fixes and unknown/any issues, but have not added types+tests for the new models.

E: I've stolen your list of Params models to exclude from testing under the assumption that'll be an acceptable path forward 😅 , assuming so, in typescript-sdk#1084 reverting the fetch:spec-types change is the only pending item. I won't be able to handle arbitrary params fixes across all SDKs though - I'm sure there are others where this will also be breaking 🙂

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

Labels

draft SEP proposal with a sponsor.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing _meta in schema.json for CallToolRequest

4 participants