Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com> Co-authored-by: Konstantin Konstantinov <KKonstantinov@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
28 KiB
@modelcontextprotocol/client
2.0.0-alpha.3
Major Changes
- #2128
c8d7401Thanks @felixweinberger! - SEP-2663: remove 2025-11 experimental tasks (TaskManager, experimental.tasks.* accessors). Tasks are now Extensions Track.
Minor Changes
-
#2049
4f226c1Thanks @KKonstantinov! - AddSdkHttpErrorsubclass with typed.status/.statusTextaccessors for HTTP transport failures.StreamableHTTPClientTransportnow throwsSdkHttpError(which extendsSdkError) for non-OK HTTP responses;SSEClientTransportthrowsSdkHttpErrorfor 401-after-reauth (circuit breaker). -
#1974
db83829Thanks @felixweinberger! - Add custom (non-spec) method support: a 3-argsetRequestHandler(method, schemas, handler)/setNotificationHandler(method, schemas, handler)form for vendor-prefixed methods, and arequest(req, resultSchema)overload (also onctx.mcpReq.send) for typed custom-method results. Spec-method calls are unchanged.Response result-schema validation failure now rejects with
SdkError(InvalidResult)instead of a rawZodError. AddsSdkErrorCode.InvalidResult. -
#1653
6bec24aThanks @rechedev9! - AddvalidateClientMetadataUrl()utility for early validation ofclientMetadataUrlExports a
validateClientMetadataUrl()function thatOAuthClientProviderimplementations can call in their constructors to fail fast on invalid URL-based client IDs, instead of discovering the error deep in the auth flow. -
#2354
0fb8406Thanks @KKonstantinov! - Add the v2IdJagTokenExchangeResponsetype to the public API and register its schema as an MCP spec type.IdJagTokenExchangeResponseis now exported from@modelcontextprotocol/clientand@modelcontextprotocol/server,'IdJagTokenExchangeResponse'joins theSpecTypeNameunion, andisSpecType.IdJagTokenExchangeResponse(value)/specTypeSchemas.IdJagTokenExchangeResponsevalidate it by name — matching how the OAuth/OpenID auth schemas are already exposed. The Zod schema itself,IdJagTokenExchangeResponseSchema, is available from@modelcontextprotocol/core. -
#2248
db28156Thanks @felixweinberger! - Restore the 2025-11-25 task wire types that were removed together with the task feature: the task schemas and inferred types, task members of the request/result/notification unions, thetaskrequest-params augmentation, thetaskscapability key, theisTaskAugmentedRequestParamsguard, andRELATED_TASK_META_KEY. The task feature itself remains removed — servers do not advertise thetaskscapability and inboundtasks/*requests receive-32601— but the wire surface stays so SDKs interoperate cleanly with peers on the 2025-11-25 revision. -
#1887
96db044Thanks @felixweinberger! - ExportisSpecTypeandspecTypeSchemasrecords for runtime validation of any MCP spec type by name.isSpecType.ContentBlock(value)is a type predicate;specTypeSchemas.ContentBlockis aStandardSchemaV1Sync<ContentBlock>validator —validate()returns the result synchronously. Guards are standalone functions, soarr.filter(isSpecType.ContentBlock)works. Also export theSpecTypeName,SpecTypes, andStandardSchemaV1Synctypes. -
#1871
9fc9070Thanks @felixweinberger! - Move stdio transports to a./stdiosubpath export. ImportStdioClientTransport,getDefaultEnvironment,DEFAULT_INHERITED_ENV_VARS, andStdioServerParametersfrom@modelcontextprotocol/client/stdio, andStdioServerTransportfrom@modelcontextprotocol/server/stdio. The@modelcontextprotocol/clientroot entry no longer pulls innode:child_process,node:stream, orcross-spawn, fixing bundling for browser and Cloudflare Workers targets; the@modelcontextprotocol/serverroot entry drops itsnode:streamreference. Node.js, Bun, and Deno consumers update the import path; runtime behavior is unchanged.
Patch Changes
-
#1897
434b2f1Thanks @felixweinberger! - Stop bundling@cfworker/json-schemainto the main package barrel. PreviouslyCfWorkerJsonSchemaValidatorwas re-exported from the core internal barrel, so tsdown inlined the@cfworker/json-schemadependency into every consumer's bundle even when it was never used. The named validator classes are now reachable only via the explicit@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}subpaths and the runtime_shimsconditional, so consumers that import only from the root entry point no longer ship the validator dep. -
#2269
e84c3e9Thanks @mattzcarey! - Non-SEP draft spec conformance fixesMcpServernow eagerly installs list/read/call handlers for every primitive capability (tools,resources,prompts) declared inServerOptions.capabilities. Per the draft spec, a server that declares a capability MUST respond to its list method (potentially with an empty result) instead of returning "Method not found". Previously, handlers were only installed lazily on first registration, so a server constructed with e.g.capabilities: { tools: {} }and zero registered tools answeredtools/listwith-32601. Low-levelServerusers remain responsible for registering handlers for declared capabilities (documented onServerOptions.capabilities).- Fixed pagination doc examples on
Client.listTools/listPrompts/listResourcesto loopwhile (cursor !== undefined)instead ofwhile (cursor)— per the draft spec, clients MUST NOT treat an empty-string cursor as the end of results.
-
#1834
42cb6b2Thanks @felixweinberger! - ExportInMemoryTransportfor in-process testing. -
#1898
2a7611dThanks @felixweinberger! - Add top-leveltypesfield (andtypesVersionson client/server for their subpath exports) so consumers on legacymoduleResolution: "node"can resolve type declarations. Theexportsmap remains the source of truth fornodenext/bundlerresolution. ThetypesVersionsmap includes entries for subpaths added by sibling PRs in this series (zod-schemas,stdio); those entries are no-ops until the correspondingdist/*.d.mtsfiles exist. -
#1655
1eb3123Thanks @nielskaspers! - fix(client): append custom Accept headers to spec-required defaults in StreamableHTTPClientTransportCustom Accept headers provided via
requestInit.headersare now appended to the spec-mandated Accept types instead of being overwritten. This ensures the required media types (application/json, text/event-streamfor POST;text/event-streamfor GET SSE) are always present while allowing users to include additional types for proxy/gateway routing. -
#2268
49c0a71Thanks @mattzcarey! - Mark the roots, sampling, and logging runtime APIs as@deprecatedper SEP-2577 (deprecated as of protocol version 2026-07-28; functional for at least twelve months). AnnotatesServer.createMessage/listRoots/sendLoggingMessage,McpServer.sendLoggingMessage,Client.setLoggingLevel/sendRootsListChanged, theServerContext.mcpReq.log/requestSamplinghelpers, and theroots/sampling/loggingcapability schema fields. JSDoc/docs only — no behavior change. -
#2275
1b53a41Thanks @KKonstantinov! - Add a configurablemaxBufferSize(default 10 MB) to the stdio transports. When a single message would push the read buffer past the limit, the transport now emits anonerrorand closes instead of growing the buffer unbounded. Configure vianew StdioClientTransport({ ..., maxBufferSize })ornew StdioServerTransport(stdin, stdout, { maxBufferSize }). The default is exported from@modelcontextprotocol/client/@modelcontextprotocol/serverasSTDIO_DEFAULT_MAX_BUFFER_SIZE. -
#2088
16d13abThanks @mattzcarey! - Bundle automatic JSON Schema validator defaults in@modelcontextprotocol/clientand@modelcontextprotocol/serverruntime shims.Client and server pick the right validator automatically based on the runtime: the Node shim uses AJV, the browser/workerd shim uses
@cfworker/json-schema. Both backends are bundled into the shim chunks that select them, so the default code path needs no extra installs —import { McpServer } from '@modelcontextprotocol/server'does not pullajvor@cfworker/json-schemainto the root entry chunk.The named validator classes remain part of the public surface for consumers who want to customize the built-in backend (pre-register schemas by
$id, register custom AJV formats, switch dialects, change@cfworker/json-schemadraft). They are exposed through explicit subpaths so they do not bloat the root index chunk:import { AjvJsonSchemaValidator } from '@modelcontextprotocol/{client,server}/validators/ajv'import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/{client,server}/validators/cf-worker'
Importing from one of these subpaths means the corresponding peer dep (
ajv+ajv-formats, or@cfworker/json-schema) must be in yourpackage.json. The shim keeps its own vendored copy for the default path, so a project can use the subpath in some files and rely on the default in others.The
jsonSchemaValidatorinterface remains the public extension point for replacing validation entirely with a custom implementation. -
#1976
55b1f06Thanks @felixweinberger! - refactor: subclasses override_wrapHandlerhook instead of redeclaringsetRequestHandler. -
#1895
b256546Thanks @felixweinberger! - Fix runtime crash ontools/listwhen a tool'sinputSchemacomes from zod 4.0–4.1. The SDK requires~standard.jsonSchema(StandardJSONSchemaV1, added in zod 4.2.0); previously a missingjsonSchemacrashed atundefined[io].standardSchemaToJsonSchemanow detects zod 4 schemas lackingjsonSchemaand falls back to the SDK-bundledz.toJSONSchema(), emitting a one-time console warning. zod 3 schemas (which the bundled zod 4 converter cannot introspect) and non-zod schema libraries withoutjsonSchemaget a clear error pointing tofromJsonSchema(). The workspace zod catalog is also bumped to^4.2.0.
2.0.0-alpha.2
Patch Changes
- #1840
424cbaeThanks @KKonstantinov! - tsdown exports resolution fix
2.0.0-alpha.1
Major Changes
- #1783
045c62aThanks @felixweinberger! - RemoveWebSocketClientTransport. WebSocket is not a spec-defined transport; use stdio or Streamable HTTP. TheTransportinterface remains exported for custom implementations. See #142.
Minor Changes
-
#1527
dc896e1Thanks @felixweinberger! - AdddiscoverOAuthServerInfo()function and unified discovery state caching for OAuth- New
discoverOAuthServerInfo(serverUrl)export that performs RFC 9728 protected resource metadata discovery followed by authorization server metadata discovery in a single call. Use this for operations like token refresh and revocation that need the authorization server URL outside ofauth(). - New
OAuthDiscoveryStatetype and optionalOAuthClientProvidermethodssaveDiscoveryState()/discoveryState()allow providers to persist all discovery results (auth server URL, resource metadata URL, resource metadata, auth server metadata) across sessions. This avoids redundant discovery requests and handles browser redirect scenarios where discovery state would otherwise be lost. - New
'discovery'scope forinvalidateCredentials()to clear cached discovery state. - New
OAuthServerInfotype exported for the return value ofdiscoverOAuthServerInfo().
- New
-
#1673
462c3fcThanks @KKonstantinov! - refactor: extract task orchestration from Protocol into TaskManagerBreaking changes:
taskStore,taskMessageQueue,defaultTaskPollInterval, andmaxTaskQueueSizemoved fromProtocolOptionstocapabilities.tasksonClientOptions/ServerOptions
-
#1763
6711ed9Thanks @felixweinberger! - AddreconnectionScheduleroption toStreamableHTTPClientTransport. Lets non-persistent environments (serverless, mobile, desktop sleep/wake) override the defaultsetTimeout-based SSE reconnection scheduling. The scheduler may return a cancel function that is invoked ontransport.close(). -
#1443
4aec5f7Thanks @NSeydoux! - The client credentials providers now support scopes being added to the token request. -
#1689
0784be1Thanks @felixweinberger! - Support Standard Schema for tool and prompt schemasTool and prompt registration now accepts any schema library that implements the Standard Schema spec: Zod v4, Valibot, ArkType, and others.
RegisteredTool.inputSchema,RegisteredTool.outputSchema, andRegisteredPrompt.argsSchemanow useStandardSchemaWithJSON(requires both~standard.validateand~standard.jsonSchema) instead of the Zod-specificAnySchematype.Zod v4 schemas continue to work unchanged — Zod v4 implements the required interfaces natively.
import { type } from 'arktype'; server.registerTool( 'greet', { inputSchema: type({ name: 'string' }) }, async ({ name }) => ({ content: [{ type: 'text', text: `Hello, ${name}!` }] }) );For raw JSON Schema (e.g. TypeBox output), use the new
fromJsonSchemaadapter:import { fromJsonSchema } from '@modelcontextprotocol/server'; import { AjvJsonSchemaValidator } from '@modelcontextprotocol/server/validators/ajv'; server.registerTool( 'greet', { inputSchema: fromJsonSchema({ type: 'object', properties: { name: { type: 'string' } } }, new AjvJsonSchemaValidator()) }, handler );Breaking changes:
experimental.tasks.getTaskResult()no longer accepts aresultSchemaparameter. ReturnsGetTaskPayloadResult(a looseResult); cast to the expected type at the call site.- Removed unused exports from
@modelcontextprotocol/core-internal:SchemaInput,schemaToJson,parseSchemaAsync,getSchemaShape,getSchemaDescription,isOptionalSchema,unwrapOptionalSchema. Use the newstandardSchemaToJsonSchemaandvalidateStandardSchemainstead. completable()remains Zod-specific (it relies on Zod's.shapeintrospection).
-
#1710
e563e63Thanks @felixweinberger! - AddAuthProviderfor composable bearer-token auth; transports adaptOAuthClientProviderautomatically- New
AuthProviderinterface:{ token(): Promise<string | undefined>; onUnauthorized?(ctx): Promise<void> }. Transports calltoken()before every request andonUnauthorized()on 401 (then retry once). - Transport
authProvideroption now acceptsAuthProvider | OAuthClientProvider. OAuth providers are adapted internally viaadaptOAuthProvider()— no changes needed to existingOAuthClientProviderimplementations. - For simple bearer tokens (API keys, gateway-managed tokens, service accounts):
{ authProvider: { token: async () => myKey } }— one-line object literal, no class. - New
adaptOAuthProvider(provider)export for explicit adaptation. - New
handleOAuthUnauthorized(provider, ctx)helper — the standard OAuthonUnauthorizedbehavior. - New
isOAuthClientProvider()type guard. - New
UnauthorizedContexttype. - Exported previously-internal auth helpers for building custom flows:
applyBasicAuth,applyPostAuth,applyPublicAuth,executeTokenRequest.
Transports are simplified internally — ~50 lines of inline OAuth orchestration (auth() calls, WWW-Authenticate parsing, circuit-breaker state) moved into the adapter's
onUnauthorized()implementation.OAuthClientProvideritself is unchanged. - New
-
#1614
1a78b01Thanks @pcarleton! - Apply resolved scope consistently to both DCR and the authorization URL (SEP-835)When
scopes_supportedis present in the protected resource metadata (/.well-known/oauth-protected-resource), the SDK already uses it as the default scope for the authorization URL. This change applies the same resolved scope to the dynamic client registration request body, ensuring both use a consistent value.registerClient()now accepts an optionalscopeparameter that overridesclientMetadata.scopein the registration body.auth()now computes the resolved scope once (WWW-Authenticate → PRMscopes_supported→clientMetadata.scope) and passes it to both DCR and the authorization request.
Patch Changes
-
#1758
e86b183Thanks @KKonstantinov! - tasks - disallow requesting a null TTL -
#1824
fcde488Thanks @felixweinberger! - DropzodfrompeerDependencies(kept as direct dependency)Since Standard Schema support landed,
zodis purely an internal runtime dependency used for protocol message parsing. User-facing schemas (registerTool,registerPrompt) accept any Standard Schema library.zodremains independenciesand auto-installs; users no longer need to install it alongside the SDK. -
#1761
01954e6Thanks @felixweinberger! - Convert remaining capability-assertion throws toSdkError(SdkErrorCode.CapabilityNotSupported, ...). Follow-up to #1454 which missedClient.assertCapability(), the task capability helpers inexperimental/tasks/helpers.ts, and the sampling/elicitation capability checks inexperimental/tasks/server.ts. -
#1632
d99f3eeThanks @matantsach! - Continue OAuth metadata discovery on 502 (Bad Gateway) responses, matching the existing behavior for 4xx. This fixes MCP servers behind reverse proxies that return 502 for path-aware metadata URLs. Other 5xx errors still throw to avoid retrying against overloaded servers. -
#1772
5276439Thanks @felixweinberger! - Always setwindowsHidewhen spawning stdio server processes on Windows, not just in Electron environments. Prevents unwanted console windows in non-Electron Windows applications. -
#1390
9bc9abcThanks @DePasqualeOrg! - Fix StreamableHTTPClientTransport to handle error responses in SSE streams -
#1343
4b5fdcbThanks @christso! - Fix OAuth error handling for servers returning errors with HTTP 200 statusSome OAuth servers (e.g., GitHub) return error responses with HTTP 200 status instead of 4xx. The SDK now checks for an
errorfield in the JSON response before attempting to parse it as tokens, providing users with meaningful error messages. -
#1534
69a0626Thanks @josefaidt! - remove npm references, use pnpm -
#1386
00249ceThanks @PederHP! - Respect capability negotiation in list methods by returning empty lists when server lacks capabilityThe Client now returns empty lists instead of sending requests to servers that don't advertise the corresponding capability:
listPrompts()returns{ prompts: [] }if server lacks prompts capabilitylistResources()returns{ resources: [] }if server lacks resources capabilitylistResourceTemplates()returns{ resourceTemplates: [] }if server lacks resources capabilitylistTools()returns{ tools: [] }if server lacks tools capability
This respects the MCP spec requirement that "Both parties SHOULD respect capability negotiation" and avoids unnecessary server warnings and traffic. The existing
enforceStrictCapabilitiesoption continues to throw errors when set totrue. -
#1534
69a0626Thanks @josefaidt! - clean up package manager usage, all pnpm -
#1595
13a0d34Thanks @bhosmer-ant! - Don't swallow fetchTypeErroras CORS in non-browser environments. Network errors (DNS resolution failure, connection refused, invalid URL) in Node.js and Cloudflare Workers now propagate from OAuth discovery instead of being silently misattributed to CORS and returningundefined. This surfaces the real error to callers rather than masking it as "metadata not found." -
#1279
71ae3acThanks @KKonstantinov! - Initial 2.0.0-alpha.0 client and server package