GitShow/modelcontextprotocol/typescript-sdk
modelcontextprotocol

typescript-sdk

The official TypeScript SDK for Model Context Protocol servers and clients

by modelcontextprotocol
Star on GitHubForkWebsitenpm

TypeScript

12.8k stars1.9k forks166 contributorsActive · 12h agoSince 2024v1.29.0

Meet the team

See all 166 on GitHub →
jspahrsummers
jspahrsummers368 contributions
ihrpr
ihrpr299 contributions
felixweinberger
felixweinberger127 contributions
ochafik
ochafik77 contributions
KKonstantinov
KKonstantinov74 contributions
bhosmer-ant
bhosmer-ant57 contributions
jerome3o-anthropic
jerome3o-anthropic39 contributions
mattzcarey
mattzcarey37 contributions

Languages

View on GitHub →
TypeScript97.2%
JavaScript2.7%
Shell0.1%

Commit activity

Last 12 weeks · 85 commits

Full graph →

Community health

5 of 6 standards met

Community profile →
87
✓README✓License✓Contributing✓Code of Conduct○Issue Template✓PR Template

Recent PRs & issues

Active · Last activity 12h ago
See all on GitHub →
morluto
alpha.3: CfWorkerJsonSchemaValidator and AjvJsonSchemaValidator declared in types but missing from runtime index.mjs exportOpenIssue

Bug In , and are declared in the type declarations () and listed in the type statement, but are missing from the runtime export. This causes a runtime when importing them from the package root. Package version Reproduction Results in: The same happens with . Evidence Type declarations () — both are present Runtime () — both are absent Subpath exports work correctly The exports field includes subpath entries that DO export them at runtime: So the classes exist and are exported via subpaths — the main bundle just forgot to re-export them. Workaround Import from the subpath export instead of the package root: Expected behavior Either: 1. Re-export and from (matching the type declarations), or 2. Remove them from the export list if the intent is to only expose them via subpath exports. Option 1 is preferable since the type declarations already promise these exports from the root, and consumers importing from will expect them to be available at runtime.

morluto · 1m ago
carissalicatovich
OAuth token exchange crashes on gzip-compressed token response (JSON.parse on undecompressed bytes)OpenIssue

Summary When completing the OAuth flow against a server whose /oauth/token-request endpoint returns a gzip-compressed token response, mcp-remote crashes while parsing that response. The raw compressed bytes appear to be passed to JSON.parse without being decompressed first. Environment mcp-remote: 0.1.37 and 0.1.38 (both fail) Node: v26.2.0 OS: Windows 11 Enterprise 23H2 (build 22631.7219) Auth server: Snowflake MCP endpoint; /oauth/token-request returns gzip-encoded responses (not on every call) Error Authorization error during finishAuth SyntaxError: Unexpected token '\u001f', "\u001f \b\u0000\u0000\u0000\u0000\u0000\u0000\u0003"... is not valid JSON at JSON.parse () at parseJSONFromBytes (node:internal/deps/undici/undici:4292:19) at successSteps (node:internal/deps/undici/undici:6907:27) at readAllBytes (node:internal/deps/undici/undici:5754:13) The leading bytes 1F 8B 08 00 00 00 00 00 03 are the gzip magic header, confirming the body being parsed is still gzip-compressed. Diagnosis A plain curl to the endpoint returns uncompressed JSON (7B 0A ...), so the server only gzips when the client advertises gzip support. Node's own fetch() decompresses correctly: a direct fetch() with Accept-Encoding: gzip, reading arrayBuffer(), returns decompressed JSON (is gzip: false). This points to the token-exchange code path reading the raw response body without gzip decompression, rather than a Node bug. Expected The token response should be decompressed (or fetch() allowed to handle Content-Encoding) before JSON.parse, so gzip-encoded token responses parse successfully. Actual Raw gzip bytes are passed to JSON.parse, throwing SyntaxError and aborting the OAuth flow, so the connection never completes against this endpoint.

carissalicatovich · 2m ago
christopher-h-johnson
[v2] feedback: Client sends legacy `initialize` to non-conforming "MCP" endpoint — no dual-era probeOpenIssue

What happened? We used the v2 beta client () to connect to Shopify's Global Catalog endpoint, which advertises in its UCP service card at . On , the SDK unconditionally sends an request with . Shopify's server doesn't implement the MCP protocol lifecycle at any version — it only accepts raw JSON-RPC POSTs. It rejects with a domain-specific error: The SDK retries this 3 times (treating it as a transport failure) and never reaches . Wire capture of the first request the SDK sends: Key observations: in the compiled bundle is , not No header (required by the 2026-07-28 spec) No inline metadata — the client operates in legacy mode only The server returns a well-formed JSON-RPC error (code ) but the SDK treats it as retryable rather than surfacing it as a clear failure Shopify's non-conformance: Their endpoint doesn't implement , doesn't use headers, doesn't use envelopes — it accepts only bare POSTs with a proprietary payload. It's JSON-RPC with MCP framing but no MCP lifecycle. What did you expect? Per the 2026-07-28 versioning spec, a dual-era client should: 1. Attempt a modern stateless request first (with inline and header) 2. Stay modern if the server responds with success or a recognized modern error 3. Fall back to only if the server returns a 4xx without a recognized modern JSON-RPC error We expected the v2 SDK (which claims 2026-07-28 support in its release notes) to implement this probe-first flow on the client side. With that, a modern-only server (or even a non-conforming one like Shopify) would receive a as the first request rather than . Additionally: When the SDK receives a well-formed JSON-RPC error in response to (even with a non-standard code like ), we expected it to surface a clear error rather than retrying — the server is telling the client "I don't understand this request," not "transient failure." Our workaround:** We bypassed the SDK and send raw POSTs with JSON-RPC directly, matching Shopify's format. Code to reproduce SDK version Area Client

christopher-h-johnson · 2m ago

Recent fixes

View closed PRs →
microadam
[v2] AWS Lambda + API Gateway ExampleClosedIssue

Attempting to build a fresh MCP server, v2 is obviously the future, so trying to get it running using that. Is there a simple example that could be shown on how to get this running with streaming on AWS with API gateway and lambda? I had it working without any streaming, but trying to use and then everything just stops working. A simple working example would be very handy. Many thanks Code example: NOTE: mcpHandler is omitted here. Its just the basic response of from the server package In terms of API Gateway and the lambda config, the "responseTransferMode" is set to "STREAM" on ApiGateway and the lambda is being invoked via its streaming method

microadam · 23m ago
KKonstantinov
codemod iterations 5MergedPR

Teach the v1→v2 codemod to catch two classes of test-code breakage that the handler migration leaves behind, and fix the batch-test harness so it can exercise monorepo targets that are their own pnpm workspace. Both codemod additions are advisory diagnostics — they flag and explain, they never rewrite. Motivation and Context The codemod already migrates handler implementations to v2 — reshaping reads to the nested / context, and switching handler registration to the method-string key. But a migration is only load-bearing if the project's tests still pass afterward, and two batch tests surfaced cases where the sources migrate cleanly yet the tests break at runtime because the codemod can't safely reach the test doubles: v1 mock contexts (mcp-servers batch test).* A test hands a hand-built context to a bare call. The codemod reshapes reads inside handler definitions it can anchor on (registerTool, setRequestHandler, fallback handlers, annotated params), but a free-standing object literal passed to an invocation is never reached, so it keeps the flat v1 shape. The migrated handler then reads / against it and throws . In the mcp-servers fork this was 11 failures from 1 root cause. Stale registration-schema assertions. In v2 handlers register by the method string, not by the / constant. Tests that assert against a mock's recorded first argument () or look a handler up by schema () silently go stale — the same constant is still importable and still valid for , so nothing errors at compile time; the assertion just never matches. Neither can be auto-rewritten safely: an untyped object literal that merely shares a key name might not be a context mock, and a schema constant used in a registration-shaped expression might be a legitimate /validation use. So the codemod's job here is to diagnose precisely — point at the node, name the v2 shape, and let the author apply it. Separately, the batch-test harness couldn't run monorepo targets that carry their own (catalog:/workspace: deps — e.g. mastra). The install path unconditionally passed , which discards the clone's workspace file; pnpm then can't resolve the catalog/workspace links () and the repo is skipped — so those targets never produced codemod signal. What this PR adds: — v1 mock-context detection. Flags object literals in a call-argument or variable-initializer position that look like a v1 handler-context mock: either one distinctive v1 key (, , , , , , ) or ≥2 context-like keys together. Emits an advisory diagnostic with a concrete reshape hint per key (, , …), a worked example (), and a note that stays top-level. Skips literals already in v2 shape (containing / / ). Never rewrites. — stale registration-schema flagging. In a file that performs handler registration, flags a method-mapped schema constant used as a value (a call argument, or an /// operand) and advises comparing against the method string instead (). Only fires in files that still reference the schema — a fully converted source drops the import, so this targets the registration tests that survive. Never rewrites. Batch-test harness — own-workspace clones. now detects a clone with its own and keeps it, scoping the install to the target packages via (installing only what the checks need — e.g. 2 of mastra's 161 projects — instead of the whole tree). The single-package clone path (, so pnpm doesn't walk up into the SDK's own workspace) is unchanged. The command is computed once and reused for the post-codemod reinstall. Generated version pin bump. regenerated from → , so the codemod's dependency rewrite now targets the beta line. How Has This Been Tested? Unit tests, (7 new cases): inline call-argument mock, variable-bound mock with the -stays-top-level note, the / progress-notification shape, two-generic-keys-without-a-distinctive-key, and three negatives — already-v2 shape, a non-context config literal, and a lone generic key. Each positive asserts advisory-only and the exact reshape hint; the literal is asserted left untouched. Unit tests, (4 new cases): schema as a assertion arg, schema as a registration-lookup helper arg, and two negatives — schema used as alongside a real registration, and a schema referenced in a file with no handler registration. Unit tests, (4 new cases): non-pnpm managers, pnpm single-package clone (), pnpm own-workspace clone (no , per target package), and own-workspace clone whose only target is the root (whole-workspace install, no ). Full codemod suite green: 19 files, 615 tests passing. The diagnostics were derived from real batch-test runs (mcp-servers fork for the mock-context gap; the memory/subscribe server for the registration-schema gap); the harness fix was validated by getting mastra (own pnpm workspace) to install and run its checks instead of being skipped. Breaking Changes None to any public API. The change is additive to the codemod and the batch-test harness. The two new codemod outputs are advisory diagnostics only — no existing migration output changes; the codemod now surfaces more actionable guidance about test code it was previously silent on. Types of changes [x] Bug fix (non-breaking change which fixes an issue) — codemod was silent on v1 mock contexts and stale registration-schema assertions that break migrated tests at runtime [x] New feature (non-breaking change which adds functionality) — two new advisory diagnostics + batch-test support for own-workspace monorepo targets [ ] Breaking change (fix or feature that would cause existing functionality to change) [ ] Documentation update Checklist [ ] I have read the MCP Documentation [x] My code follows the repository's style guidelines [x] New and existing tests pass locally [x] I have added appropriate error handling [ ] I have added or updated documentation as needed Additional context Advisory, not rewritten — by design. Both new detections sit on top of ambiguity the AST can't resolve: an untyped literal sharing a key name might not be a context mock, and a schema constant is still a valid argument. Rewriting either risks corrupting correct code, so the codemod flags with a precise, node-anchored message instead. This mirrors the existing diagnostics for fallback handlers and annotated params. Detection precision. The mock-context check requires either a distinctive v1 key or ≥2 context-like keys, and bails on anything already in the v2 nested shape, to avoid firing on ordinary config/option objects. The registration-schema check only runs in files that actually call / and only flags value positions (call arg / equality operand), leaving property-access bases like alone. Batch-test scoping. For own-workspace targets the install is filtered to (package + its dependencies) so a large monorepo installs only the projects under test rather than the entire workspace — the difference between a runnable target and a multi-minute/timeout install. Note for reviewers following this branch: an earlier iteration explored a CommonJS-interop transform (dynamic- rewriting for CJS targets). That is not* part of this change — #2405 shipped native builds for the v2 packages, so CJS projects consume v2 directly and the interop transform was dropped. The net diff here is the two diagnostics, the harness fix, and the version-pin bump.

KKonstantinov · 12h ago
mattzcarey
feat(packaging): ship CommonJS builds alongside ESM for v2 packagesMergedPR

Summary Restores CommonJS output for the v2 packages, so works again alongside . The v2 monorepo shipped ESM-only; this brings back the dual CJS/ESM build v1 had, now driven entirely by tsdown. All nine publishable packages are covered: , , , , , and the four adapters. What changed tsdown configs (9) — → plus . tsdown emits the second bundle and its interop shims; normalizes every package onto the same convention: ESM: / CJS: / This also fixes a pre-existing inconsistency: was emitting / (it builds with ) while every other package emitted . They now all match. exports (9) — each subpath gains a condition beside , following the conventional ordering ( first, first within each branch, last): This covers every export: / , , , and (the runtime conditions stay outer, / nest inside); //. A field is added for bare- fallback. 's export is renormalized off . 's stays ESM; only its library entry goes dual. Changeset** — patch bump for all nine packages. Verification — clean (exit 0), 18 dual-format builds, no warnings. Every CJS bundle -loads without error (no ESM-only dependency getting d), and resolves through the new condition by name. The existing types check stays clean. All exports / / / paths resolve to emitted files; each subpath is balanced across / / / . Public import paths are unchanged — this is additive.

mattzcarey · 13h ago
Structured data for AI agents

Repository: modelcontextprotocol/typescript-sdk. Description: The official TypeScript SDK for Model Context Protocol servers and clients Stars: 12771, Forks: 1950. Primary language: TypeScript. Languages: TypeScript (97.2%), JavaScript (2.7%), Shell (0.1%). Homepage: https://ts.sdk.modelcontextprotocol.io/v2 Latest release: v1.29.0 (3mo ago). Open PRs: 100, open issues: 337. Last activity: 12h ago. Community health: 87%. Top contributors: jspahrsummers, ihrpr, felixweinberger, ochafik, KKonstantinov, bhosmer-ant, jerome3o-anthropic, mattzcarey, cliffhall, allenzhou101 and others.

·@ofershap

Replace github.com with gitshow.dev