Skip to content

Conversation

@KKonstantinov
Copy link
Contributor

@KKonstantinov KKonstantinov commented Dec 10, 2025

Proof of Concept: v2 monorepo, package split

Motivation and Context

v1 of the sdk shipped both client and server in the same package, introducing extra dependencies to users who have a single concern (client or server only). Client and server packages are now split, depending on a shared core package.

Additionally, v1 exported all files as the public API of the SDK, limiting the SDK ability to iterate internally while keeping backwards compatibility. Barrel files are now introduced as the single entrypoint to the SDK and defining the public API of the SDK.

How Has This Been Tested?

Unit, integration tests

Breaking Changes

v2

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 10, 2025

Open in StackBlitz

pnpm add https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/sdk-client@1279
pnpm add https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/sdk-server@1279

commit: b532047

@KKonstantinov KKonstantinov added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Dec 10, 2025
@KKonstantinov KKonstantinov self-assigned this Dec 10, 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.

Is there a way we can break this PR up somehow so that this is more reviewable? E.g. with using git mv to preserve history and provenance of files? As it is it'll be quite hard to verify correctness of the split.

@KKonstantinov
Copy link
Contributor Author

KKonstantinov commented Dec 12, 2025

EDITs:

  • Provenance / history retained (except 3-4 files, will review them and bring it to them as well)
  • Dropped Node v18
  • Dropped CommonJS (ESM only)
  • Removed tsgo - that's running TS v7 - switched to tsc for our current typescript version
  • Bumped the ts version
  • Added eslint import rules to tidy up imports
  • cleaned-up package.json files - client-sdk and server-sdk ship with the minimum required dependencies (as opposed to v1, which shipped server deps if you were only interested in the client and vice versa
  • introduce catalogs for reusing dep versions
  • bundling tool change - tsdown as per @mattzcarey
  • ... might be more, will add as quite tired after this one :)

TODOs still:

  • *.md - readme updates
  • test(18) check - no code change, repository config -> needs to be removed as required check from branch rulesets, and replaced with test(20)

@KKonstantinov KKonstantinov added this to the v2 milestone Dec 12, 2025
@KKonstantinov KKonstantinov linked an issue Dec 12, 2025 that may be closed by this pull request
23 tasks
@KKonstantinov KKonstantinov changed the title [v2] Proof of Concept: monorepo, package split [v2] Мonorepo, sdk-client, sdk-server, sdk-core package split Dec 14, 2025
@modelcontextprotocol modelcontextprotocol deleted a comment from sonarqubecloud bot Dec 16, 2025
@KKonstantinov KKonstantinov linked an issue Dec 16, 2025 that may be closed by this pull request
@KKonstantinov KKonstantinov linked an issue Dec 16, 2025 that may be closed by this pull request
@mattzcarey
Copy link
Contributor

I would push against removing tsgo from the check script. As we move to a monorepo it will be much much faster than tsc.

export default defineConfig({
// 1. Entry Points
// Directly matches package.json include/exclude globs
entry: ['src/**/*.ts', '!src/**/*.test.ts', '!src/__mocks__/**', '!src/examples/**'],
Copy link
Contributor

Choose a reason for hiding this comment

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

this should just be the root index.ts

"node": ">=20",
"pnpm": ">=10.24.0"
},
"packageManager": "[email protected]",
Copy link
Contributor

Choose a reason for hiding this comment

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

I dont hate this move. I like that we wont have to use turborepo or nx, at least initially. But it should be noted this will be a big dev ex change

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, we would need to update the README and the contribution guidelines

@@ -0,0 +1,3 @@
import { defineWorkspace } from 'vitest/config';

export default defineWorkspace(['packages/**/vitest.config.js']);
Copy link
Contributor

Choose a reason for hiding this comment

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

I did not know this was a thing lol. why do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Basically different configs if we need to - https://v2.vitest.dev/guide/workspace

export default defineConfig({
// 1. Entry Points
// Directly matches package.json include/exclude globs
entry: ['src/**/*.ts', '!src/**/*.test.ts', '!src/__mocks__/**', '!src/examples/**'],
Copy link
Contributor

Choose a reason for hiding this comment

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

this should just be the index.ts also. Note there are other options: this config can also live in the package.json for each package or can be defined at root and imported here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tks, will update

Comment on lines +18 to +19
export * from './validation/ajv-provider.js';
export * from './validation/cfworker-provider.js';
Copy link
Contributor

Choose a reason for hiding this comment

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

these have to be exported in the package.json. otherwise they will both get included on import.

Copy link
Contributor

Choose a reason for hiding this comment

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

really we should use shims for this in the package.json and not have separate modules. similarly to this. mswjs/msw#2640

"rootDir": "./src"
},
"include": ["./"],
"exclude": ["dist", "node_modules", "test"]
Copy link
Contributor

Choose a reason for hiding this comment

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

we should not need seperate build tsconfigs. that is the beauty of tsdown.

Copy link
Contributor Author

@KKonstantinov KKonstantinov Dec 17, 2025

Choose a reason for hiding this comment

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

Yes, this is leftover from before I added tsdown, will remove, tks

Comment on lines +9 to +10
"@modelcontextprotocol/sdk-client": ["node_modules/@modelcontextprotocol/sdk-client/src/index.ts"],
"@modelcontextprotocol/sdk-server": ["node_modules/@modelcontextprotocol/sdk-server/src/index.ts"],
Copy link
Contributor

Choose a reason for hiding this comment

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

are these used? that would make for a weird dependency structure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its a leftover thing, tks, will clean up

Copy link
Contributor

Choose a reason for hiding this comment

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

its weird that these examples live in packages. maybe put examples on the top level?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think going forward, it'd be good to treat examples as real end-user scenarios, them being in a package and importing our real packages simulates that quite well - let's discuss

Copy link
Contributor

Choose a reason for hiding this comment

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

also feels pretty weird that this is a package. imo these tests should live in either client or server depending on what they are testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

you could have some test helpers but they would live in common.

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, this one felt weird to me as well and haven't spent a lot of time thinking about it.

Let's think how we want it and refactor in a separate PR.

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

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESM only (if feasible) Publish separate client and server packages SDK V2

3 participants