Skip to content

Conversation

@KKonstantinov
Copy link
Contributor

@KKonstantinov KKonstantinov commented Dec 7, 2025

Typescript SDK has for a long time contained types which are allowing more than the actual specification. This has been masked by the spec test (spec.types.ts) having a RemovePassthrough helper to make types pass typechecks. This has unfortunately lead to actual implementation in the SDK to have wrong types, as well as SDK users to have the ability to use out-of-spec attributes in various JSONRPC methods - knowingly or unknowingly. Further, in many occasions it has broken types for SDK end users.

TL; DR:

Motivation and Context

Passthrough and loose objects not allowed by the spec were largely removed in another PR, but a few still remain.

How Has This Been Tested?

Unit tests, type checking.

Breaking Changes

None. Bringing SDK back to full spec compliance.

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

@KKonstantinov KKonstantinov requested a review from a team as a code owner December 7, 2025 12:37
@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 7, 2025

Open in StackBlitz

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/sdk@1242

commit: 36536f9

Copy link
Contributor

@felixweinberger felixweinberger left a comment

Choose a reason for hiding this comment

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

Looking at this change to Request and Notification, I'm not convinced 0 passthrough is actually the right objective for all types. I don't think the spec's types are all that strict.

Some types are intended to be flexible per the spec, these ones being specific examples. See the spec's schema.ts which literally has a comment "Allow unofficial extensions of Request.params without impacting `RequestParams")

In practice we're introducing new Generic types just to be able to keep the flexibility which seems odd? Runtime behavior hasn't really changed, we just introduced a new type to hide the flexibility elsewhere?

…ub.com:KKonstantinov/typescript-sdk into feature/passthrough-looseobject-removal-part-2
@KKonstantinov KKonstantinov changed the title Passthrough removal part 2: Achieve 0 passthrough types. Passthrough removal part 2: Remove loose types not allowed by spec. Dec 8, 2025
@KKonstantinov KKonstantinov changed the title Passthrough removal part 2: Remove loose types not allowed by spec. SPEC COMPLIANCE: Remove loose/passthrough types not allowed/defined by MCP spec. Dec 8, 2025
@KKonstantinov KKonstantinov changed the title SPEC COMPLIANCE: Remove loose/passthrough types not allowed/defined by MCP spec. SPEC COMPLIANCE: Remove loose/passthrough types not allowed/defined by MCP spec + Task types Dec 8, 2025
Copy link
Contributor

@felixweinberger felixweinberger left a comment

Choose a reason for hiding this comment

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

Thanks @KKonstantinov for reworking this AND syncing our schema.ts to the latest version! Some small follow-ups but I think we can do that in a fast-follow PR if easier.

  1. Let's use the npm run fetch:spec-types to update the spec as that will be what the nightly build does anyway. To align with the 2025-11-25 spec this makes sense, let's make sure we stay synced with the protocol.
  2. The timeout increase - was that necessary for this PR or just bypassing some flakiness?
  3. Let's remove the console.log from the test.

* Last updated from commit: 7dcdd69262bd488ddec071bf4eefedabf1742023
*
* DO NOT EDIT THIS FILE MANUALLY. Changes will be overwritten by automated updates.
* To update this file, run: npm run fetch:spec-types
Copy link
Contributor

Choose a reason for hiding this comment

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

did you run this? not sure we should be removing this docstring

Copy link
Contributor

Choose a reason for hiding this comment

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

In the interim it's fine to do this I think, but we'll want to restore the nightly logic as a fast follow. Ran it locally and there are some small diffs in comments and the 2026-DRAFT version which I think should be the one this points to longer term

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I didn't run it, but got the stable spec from 2025-25-11 version to test against. Now it's restored via #1274

/* eslint-disable @typescript-eslint/no-unsafe-function-type */

// Removes index signatures added by ZodObject.passthrough().
type RemovePassthrough<T> = T extends object
Copy link
Contributor

Choose a reason for hiding this comment

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

🥳

}
}

console.log(missingTests);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'm guessing this was accidentally included during debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

// Verify we received the notification that was sent while disconnected
expect(allText).toContain('Missed while disconnected');
}, 10000);
}, 15000);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This increase in timeouts seems unrelated to this change right? Just to reduce flakiness?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes for some reason 10s was still not enough to remove flakiness, I've not looked into why in this PR.

export const RequestSchema = z.object({
method: z.string(),
params: BaseRequestParamsSchema.optional()
params: BaseRequestParamsSchema.loose().optional()
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

});

const NotificationsParamsSchema = z.looseObject({
const NotificationsParamsSchema = z.object({
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@felixweinberger felixweinberger merged commit a606fb1 into modelcontextprotocol:main Dec 9, 2025
6 checks passed
felixweinberger added a commit that referenced this pull request Dec 9, 2025
- Restore spec.types.ts docstring header via npm run fetch:spec-types
- Remove debugging console.log from spec.types.test.ts
- Revert unrelated timeout increase in streamableHttp.test.ts
@felixweinberger felixweinberger mentioned this pull request Dec 9, 2025
9 tasks
felixweinberger added a commit that referenced this pull request Dec 9, 2025
- Restore spec.types.ts docstring header via npm run fetch:spec-types
- Remove debugging console.log from spec.types.test.ts
- Revert unrelated timeout increase in streamableHttp.test.ts
felixweinberger added a commit that referenced this pull request Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants