asynthetic 0.1.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -0
- package/data/maps/npm/ai/4.x-to-5.json +249 -0
- package/data/maps/npm/modelcontextprotocol-sdk/1.x-to-2.json +284 -0
- package/data/maps/npm/next/v14-to-v15.json +199 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +160 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +166 -0
- package/dist/server.js.map +1 -0
- package/dist/store/create-store.d.ts +2 -0
- package/dist/store/create-store.js +18 -0
- package/dist/store/create-store.js.map +1 -0
- package/dist/store/local-store.d.ts +14 -0
- package/dist/store/local-store.js +69 -0
- package/dist/store/local-store.js.map +1 -0
- package/dist/store/store.d.ts +50 -0
- package/dist/store/store.js +90 -0
- package/dist/store/store.js.map +1 -0
- package/dist/store/supabase-store.d.ts +11 -0
- package/dist/store/supabase-store.js +61 -0
- package/dist/store/supabase-store.js.map +1 -0
- package/dist/types/migration-map.d.ts +107 -0
- package/dist/types/migration-map.js +48 -0
- package/dist/types/migration-map.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ecosystem": "npm",
|
|
3
|
+
"package": "@modelcontextprotocol/sdk",
|
|
4
|
+
"from_version": "1.29.0",
|
|
5
|
+
"to_version": "2.0.0-beta.2",
|
|
6
|
+
"summary": "The monolithic @modelcontextprotocol/sdk package is retired in v2 and split into @modelcontextprotocol/server, @modelcontextprotocol/client, @modelcontextprotocol/core (wire schemas), and runtime adapters (@modelcontextprotocol/node, express, hono, fastify). v2 is ESM-only, requires Node.js 20+, and requires Zod ^4.2.0 (Zod v3 schemas fail silently at registration). The variadic server.tool()/prompt()/resource() methods are removed in favor of registerTool()/registerPrompt()/registerResource() config objects using Standard Schema. The handler `extra` parameter is restructured into a `ctx` object (ctx.mcpReq / ctx.http). setRequestHandler/setNotificationHandler take method strings instead of Zod request schemas. McpError is renamed ProtocolError; OAuth error classes are consolidated into OAuthError + OAuthErrorCode. SSEServerTransport and WebSocketClientTransport are removed. Separately from the package upgrade, v2 can OPT IN to the 2026-07-28 stateless protocol revision (no initialize handshake, no Mcp-Session-Id, server/discover probing, inputRequired() replacing sampling/elicitation push); upgrading the SDK alone does NOT change the wire protocol. An official codemod automates most of the mechanical migration: npx @modelcontextprotocol/codemod@beta v1-to-v2 . — v1.x remains supported with bug fixes and security updates for at least 6 months after v2 ships (stable expected 2026-07-28).",
|
|
7
|
+
"breaking_changes": [
|
|
8
|
+
{
|
|
9
|
+
"title": "Package split: @modelcontextprotocol/sdk is retired",
|
|
10
|
+
"description": "The single @modelcontextprotocol/sdk package splits into focused packages: @modelcontextprotocol/server (servers), @modelcontextprotocol/client (clients), @modelcontextprotocol/core (shared Zod wire schemas), @modelcontextprotocol/node (Node HTTP transport), and framework adapters @modelcontextprotocol/express / hono / fastify. Deep subpath imports (…/server/mcp.js, …/client/index.js) are replaced by package barrels and short subpaths.",
|
|
11
|
+
"category": "import-change",
|
|
12
|
+
"affected_symbols": ["@modelcontextprotocol/sdk"],
|
|
13
|
+
"before_code": "import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';",
|
|
14
|
+
"after_code": "import { McpServer } from '@modelcontextprotocol/server';\nimport { StdioServerTransport } from '@modelcontextprotocol/server/stdio';\nimport { Client } from '@modelcontextprotocol/client';",
|
|
15
|
+
"migration_note": "Replace the @modelcontextprotocol/sdk dependency with @modelcontextprotocol/server and/or @modelcontextprotocol/client. Server code imports from @modelcontextprotocol/server; client code from @modelcontextprotocol/client; shared *Schema constants from @modelcontextprotocol/core. The official codemod rewrites import paths automatically: npx @modelcontextprotocol/codemod@beta v1-to-v2 .",
|
|
16
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"title": "ESM-only, Node.js 20+ required",
|
|
20
|
+
"description": "v2 packages ship as ESM only and require Node.js 20+, Bun, or Deno. CommonJS require() of the SDK no longer works.",
|
|
21
|
+
"category": "config-change",
|
|
22
|
+
"affected_symbols": [],
|
|
23
|
+
"before_code": null,
|
|
24
|
+
"after_code": null,
|
|
25
|
+
"migration_note": "Ensure the consuming project runs on Node 20+ and can load ESM (\"type\": \"module\" in package.json, or import from an ESM context). Projects stuck on CJS or Node <20 must stay on v1.x, which remains supported with bug fixes and security updates for at least 6 months after v2 ships.",
|
|
26
|
+
"source_url": "https://blog.modelcontextprotocol.io/posts/sdk-betas-2026-07-28/"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"title": "Zod v3 no longer supported — requires zod ^4.2.0",
|
|
30
|
+
"description": "v2 depends on zod ^4.2.0. Zod v3 can still be installed alongside, but v3 schemas fail SILENTLY at runtime when registered as tool/prompt schemas — no compile error, no throw at registration.",
|
|
31
|
+
"category": "config-change",
|
|
32
|
+
"affected_symbols": ["zod"],
|
|
33
|
+
"before_code": "// package.json\n\"zod\": \"^3.23.0\"",
|
|
34
|
+
"after_code": "// package.json\n\"zod\": \"^4.2.0\"\n\n// imports\nimport * as z from 'zod'; // or 'zod/v4'",
|
|
35
|
+
"migration_note": "Upgrade zod to ^4.2.0 BEFORE upgrading the SDK. This failure mode is dangerous: with Zod v3 still installed, schema registration appears to succeed but validation is broken at runtime. Audit every z.* schema passed to registerTool/registerPrompt for Zod v4 compatibility.",
|
|
36
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"title": "server.tool()/prompt()/resource() variadic methods removed",
|
|
40
|
+
"description": "The variadic registration methods server.tool(), server.prompt(), and server.resource() are removed. Registration uses registerTool()/registerPrompt()/registerResource() with a single config object (description, inputSchema, etc.).",
|
|
41
|
+
"category": "removal",
|
|
42
|
+
"affected_symbols": ["McpServer.tool", "McpServer.prompt", "McpServer.resource"],
|
|
43
|
+
"before_code": "server.tool('greet', 'Greet a user', { name: z.string() }, async ({ name }) => ({\n content: [{ type: 'text', text: `Hello, ${name}!` }]\n}));",
|
|
44
|
+
"after_code": "server.registerTool('greet', {\n description: 'Greet a user',\n inputSchema: z.object({ name: z.string() })\n}, async ({ name }) => ({\n content: [{ type: 'text', text: `Hello, ${name}!` }]\n}));",
|
|
45
|
+
"migration_note": "Move positional description/schema arguments into the config object. Note the schema becomes a full z.object(...) rather than a raw shape (see the Standard Schema entry). The codemod handles the mechanical rewrite.",
|
|
46
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"title": "Tool/prompt schemas use Standard Schema — raw Zod shapes deprecated",
|
|
50
|
+
"description": "inputSchema/outputSchema accept any Standard Schema-compliant object (Zod v4, Valibot, ArkType). Passing a raw shape like { name: z.string() } still works via @deprecated overloads but is slated for removal.",
|
|
51
|
+
"category": "deprecation",
|
|
52
|
+
"affected_symbols": ["registerTool", "registerPrompt", "inputSchema", "outputSchema"],
|
|
53
|
+
"before_code": "server.registerTool('greet', {\n inputSchema: { name: z.string() } // raw shape\n}, handler);",
|
|
54
|
+
"after_code": "server.registerTool('greet', {\n inputSchema: z.object({ name: z.string() }) // explicit schema object\n}, handler);",
|
|
55
|
+
"migration_note": "Wrap raw shapes in z.object(...). This also unlocks non-Zod validators (Valibot, ArkType) since v2 targets the Standard Schema interface.",
|
|
56
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"title": "Handler context `extra` restructured into `ctx` (ctx.mcpReq / ctx.http)",
|
|
60
|
+
"description": "The second handler parameter is renamed extra → ctx and remapped: extra.signal → ctx.mcpReq.signal; extra.requestId → ctx.mcpReq.id; extra.sendRequest() → ctx.mcpReq.send(); extra.sendNotification() → ctx.mcpReq.notify(); extra.requestInfo → ctx.http?.req (web-standard Request); extra.authInfo → ctx.http?.authInfo; extra.closeSSEStream/closeStandaloneSSEStream → ctx.http?.closeSSE()/closeStandaloneSSE(). ctx.http is optional (undefined on stdio).",
|
|
61
|
+
"category": "signature-change",
|
|
62
|
+
"affected_symbols": ["RequestHandlerExtra", "extra.signal", "extra.requestId", "extra.sendRequest", "extra.sendNotification", "extra.requestInfo", "extra.authInfo"],
|
|
63
|
+
"before_code": "server.registerTool('search', config, async (args, extra) => {\n extra.signal.throwIfAborted();\n await extra.sendNotification({ method: 'notifications/progress', params: { progress: 1 } });\n});",
|
|
64
|
+
"after_code": "server.registerTool('search', config, async (args, ctx) => {\n ctx.mcpReq.signal.throwIfAborted();\n await ctx.mcpReq.notify({ method: 'notifications/progress', params: { progress: 1 } });\n});",
|
|
65
|
+
"migration_note": "Protocol-level members live under ctx.mcpReq; HTTP-level members under the OPTIONAL ctx.http (guard with ?. — it is undefined on stdio). The experimental task members (extra.taskStore, extra.taskId, extra.taskRequestedTtl) are removed entirely (see experimental tasks entry). The RequestHandlerExtra<TReq, TNotif> type is replaced by ServerContext/ClientContext without type parameters.",
|
|
66
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"title": "setRequestHandler/setNotificationHandler take method strings, not Zod schemas",
|
|
70
|
+
"description": "Spec handlers are registered by method string ('tools/call') instead of a request schema constant (CallToolRequestSchema). Custom (non-spec) methods use a 3-argument form with explicit { params, result } schemas.",
|
|
71
|
+
"category": "signature-change",
|
|
72
|
+
"affected_symbols": ["setRequestHandler", "setNotificationHandler"],
|
|
73
|
+
"before_code": "import { CallToolRequestSchema, ToolListChangedNotificationSchema } from '@modelcontextprotocol/sdk/types.js';\n\nserver.setRequestHandler(CallToolRequestSchema, async (request, extra) => { /* ... */ });\nclient.setNotificationHandler(ToolListChangedNotificationSchema, async (n) => { /* ... */ });",
|
|
74
|
+
"after_code": "server.setRequestHandler('tools/call', async (request, ctx) => { /* ... */ });\nclient.setNotificationHandler('notifications/tools/list_changed', async (n) => { /* ... */ });\n\n// custom methods declare schemas explicitly:\nserver.setRequestHandler('acme/search',\n { params: SearchParams, result: SearchResult },\n async (params, ctx) => { /* ... */ });",
|
|
75
|
+
"migration_note": "Replace each schema constant with its wire method string. For custom methods, pass { params, result } as the second argument; the handler then receives parsed params directly.",
|
|
76
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"title": "McpError renamed to ProtocolError; ErrorCode to ProtocolErrorCode",
|
|
80
|
+
"description": "The protocol-level JSON-RPC error class McpError is renamed ProtocolError, and the ErrorCode enum is renamed ProtocolErrorCode. A new SdkError + SdkErrorCode pair covers SDK-local failures (RequestTimeout, ConnectionClosed, InvalidResult).",
|
|
81
|
+
"category": "rename",
|
|
82
|
+
"affected_symbols": ["McpError", "ErrorCode"],
|
|
83
|
+
"before_code": "import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';\n\nthrow new McpError(ErrorCode.InvalidParams, 'bad input');",
|
|
84
|
+
"after_code": "import { ProtocolError, ProtocolErrorCode } from '@modelcontextprotocol/core';\n\nthrow new ProtocolError(ProtocolErrorCode.InvalidParams, 'bad input');",
|
|
85
|
+
"migration_note": "Rename McpError → ProtocolError and ErrorCode → ProtocolErrorCode everywhere. Catch-blocks that distinguish transport/SDK failures should also check the new SdkError/SdkErrorCode.",
|
|
86
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"title": "StreamableHTTPError renamed SdkHttpError; HTTP status moves from .code to .status",
|
|
90
|
+
"description": "StreamableHTTPError becomes SdkHttpError (extending SdkError), and the HTTP status is read from .status instead of .code.",
|
|
91
|
+
"category": "rename",
|
|
92
|
+
"affected_symbols": ["StreamableHTTPError"],
|
|
93
|
+
"before_code": "if (error instanceof StreamableHTTPError && error.code === 401) { /* ... */ }",
|
|
94
|
+
"after_code": "if (error instanceof SdkHttpError && error.status === 401) { /* ... */ }",
|
|
95
|
+
"migration_note": "Rename the class and switch .code → .status in every check. .code on the old class held the HTTP status, which collided with JSON-RPC error codes — hence the rename.",
|
|
96
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"title": "OAuth error classes consolidated into OAuthError + OAuthErrorCode",
|
|
100
|
+
"description": "The ~12 individual OAuth error classes (InvalidRequestError, InvalidClientError, InvalidGrantError, UnauthorizedClientError, …) are replaced by a single OAuthError class discriminated by OAuthErrorCode.",
|
|
101
|
+
"category": "removal",
|
|
102
|
+
"affected_symbols": ["InvalidRequestError", "InvalidClientError", "InvalidGrantError", "UnauthorizedClientError"],
|
|
103
|
+
"before_code": "if (error instanceof InvalidClientError) { /* ... */ }",
|
|
104
|
+
"after_code": "if (error instanceof OAuthError && error.code === OAuthErrorCode.InvalidClient) { /* ... */ }",
|
|
105
|
+
"migration_note": "Replace each instanceof check on a specific OAuth error class with instanceof OAuthError plus a code comparison against the matching OAuthErrorCode member.",
|
|
106
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"title": "SSEServerTransport and WebSocketClientTransport removed",
|
|
110
|
+
"description": "The deprecated HTTP+SSE server transport and the WebSocket client transport are removed from v2. A frozen v1 copy of the SSE transport is published at @modelcontextprotocol/server-legacy/sse for servers that must keep supporting legacy SSE clients.",
|
|
111
|
+
"category": "removal",
|
|
112
|
+
"affected_symbols": ["SSEServerTransport", "WebSocketClientTransport"],
|
|
113
|
+
"before_code": "import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';",
|
|
114
|
+
"after_code": "// preferred: migrate to Streamable HTTP\nimport { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';\n// escape hatch for legacy SSE clients:\nimport { SSEServerTransport } from '@modelcontextprotocol/server-legacy/sse';",
|
|
115
|
+
"migration_note": "Migrate SSE deployments to Streamable HTTP. If legacy SSE clients must still be served, depend on @modelcontextprotocol/server-legacy — but treat it as frozen, unmaintained code. There is no v2 WebSocket client transport.",
|
|
116
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"title": "StreamableHTTPServerTransport split by runtime (Node vs web-standard)",
|
|
120
|
+
"description": "StreamableHTTPServerTransport is replaced by NodeStreamableHTTPServerTransport (from @modelcontextprotocol/node, for Node's http module) and WebStandardStreamableHTTPServerTransport (from @modelcontextprotocol/server, for web-standard Request/Response runtimes). For HTTP servers, createMcpHandler from @modelcontextprotocol/server is the new high-level entry point.",
|
|
121
|
+
"category": "rename",
|
|
122
|
+
"affected_symbols": ["StreamableHTTPServerTransport"],
|
|
123
|
+
"before_code": "import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\n\nconst transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });",
|
|
124
|
+
"after_code": "import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';\n\nconst transport = new NodeStreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });",
|
|
125
|
+
"migration_note": "Pick the transport matching your runtime: @modelcontextprotocol/node for Node http, @modelcontextprotocol/server's WebStandardStreamableHTTPServerTransport for fetch-style runtimes, or the express/hono/fastify adapter packages. Upgrading the transport does NOT change the wire protocol — v2 still speaks the 2025-era protocol (sessions, initialize) unless you explicitly opt in to 2026-07-28 via createMcpHandler(factory)/serveStdio(buildServer).",
|
|
126
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"title": "Wire-schema constants move from sdk/types.js to @modelcontextprotocol/core",
|
|
130
|
+
"description": "All Zod wire-schema constants (CallToolResultSchema, InitializeRequestSchema, …) move from @modelcontextprotocol/sdk/types.js to the @modelcontextprotocol/core package.",
|
|
131
|
+
"category": "import-change",
|
|
132
|
+
"affected_symbols": ["CallToolResultSchema", "@modelcontextprotocol/sdk/types.js"],
|
|
133
|
+
"before_code": "import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';",
|
|
134
|
+
"after_code": "import { CallToolResultSchema } from '@modelcontextprotocol/core';",
|
|
135
|
+
"migration_note": "Add @modelcontextprotocol/core as a dependency wherever wire schemas are imported directly. Note many uses disappear entirely because setRequestHandler and client.request() no longer take schema arguments. Zod-free alternatives isSpecType.X(value) and specTypeSchemas are exported from the client/server packages.",
|
|
136
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"title": "Header access is web-standard Headers — bracket access removed",
|
|
140
|
+
"description": "IsomorphicHeaders (plain-object headers with bracket access) is replaced by the web-standard Headers class on ctx.http.req.",
|
|
141
|
+
"category": "signature-change",
|
|
142
|
+
"affected_symbols": ["IsomorphicHeaders", "extra.requestInfo.headers"],
|
|
143
|
+
"before_code": "const sessionId = extra.requestInfo?.headers['mcp-session-id'];",
|
|
144
|
+
"after_code": "const sessionId = ctx.http?.req?.headers.get('mcp-session-id');\nconst debug = new URL(ctx.http!.req!.url).searchParams.get('debug');",
|
|
145
|
+
"migration_note": "Replace bracket access with .get(name) (case-insensitive). URL/query parsing goes through new URL(ctx.http.req.url).",
|
|
146
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"title": "Result-schema argument dropped from client.request()/sendRequest() for spec methods",
|
|
150
|
+
"description": "For spec-defined methods, the result-schema second argument to client.request(), client.callTool(), and ctx.mcpReq.send() is removed — the SDK knows the result shape from the method string.",
|
|
151
|
+
"category": "signature-change",
|
|
152
|
+
"affected_symbols": ["Client.request", "Client.callTool", "extra.sendRequest"],
|
|
153
|
+
"before_code": "const r = await extra.sendRequest(\n { method: 'sampling/createMessage', params },\n CreateMessageResultSchema\n);",
|
|
154
|
+
"after_code": "const r = await ctx.mcpReq.send(\n { method: 'sampling/createMessage', params }\n);",
|
|
155
|
+
"migration_note": "Delete the schema argument for spec methods. Custom methods keep explicit schemas via the 3-arg setRequestHandler form on the receiving side.",
|
|
156
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"title": "completable() nesting inverted for optional schemas",
|
|
160
|
+
"description": "Optional completable prompt arguments invert: the completable wraps the base schema and .optional() is applied to the result, not the input.",
|
|
161
|
+
"category": "signature-change",
|
|
162
|
+
"affected_symbols": ["completable"],
|
|
163
|
+
"before_code": "completable(z.string().optional(), callback)",
|
|
164
|
+
"after_code": "completable(z.string(), callback).optional()",
|
|
165
|
+
"migration_note": "Move .optional() from the inner schema to the completable(...) result.",
|
|
166
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"title": "list*() client methods auto-aggregate paginated results",
|
|
170
|
+
"description": "listTools(), listResources(), etc. now follow pagination cursors automatically and return the aggregated list, up to listMaxPages (default 100). Exceeding the cap throws SdkError with SdkErrorCode.ListPaginationExceeded.",
|
|
171
|
+
"category": "behavior-change",
|
|
172
|
+
"affected_symbols": ["Client.listTools", "Client.listResources", "Client.listPrompts", "listMaxPages"],
|
|
173
|
+
"before_code": "// v1: one page per call; caller loops on nextCursor\nlet cursor;\ndo {\n const page = await client.listTools({ cursor });\n tools.push(...page.tools);\n cursor = page.nextCursor;\n} while (cursor);",
|
|
174
|
+
"after_code": "// v2: aggregation is automatic\nconst { tools } = await client.listTools();",
|
|
175
|
+
"migration_note": "Delete manual cursor loops — they would now iterate over already-aggregated results. Set listMaxPages if servers may expose more than 100 pages, and handle SdkErrorCode.ListPaginationExceeded.",
|
|
176
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"title": "Custom Accept headers are appended, not replaced",
|
|
180
|
+
"description": "StreamableHTTPClientTransport now appends custom Accept values from requestInit.headers to the protocol-required media types (application/json, text/event-stream) instead of letting them replace the header.",
|
|
181
|
+
"category": "behavior-change",
|
|
182
|
+
"affected_symbols": ["StreamableHTTPClientTransport", "requestInit.headers.Accept"],
|
|
183
|
+
"before_code": "// v1: this REPLACED the Accept header entirely\nnew StreamableHTTPClientTransport(url, { requestInit: { headers: { Accept: 'custom/type' } } });",
|
|
184
|
+
"after_code": "// v2: same code now sends\n// Accept: application/json, text/event-stream, custom/type",
|
|
185
|
+
"migration_note": "Code that relied on overriding Accept (e.g. to suppress SSE) no longer can; servers that dispatch on an exact Accept value may behave differently after upgrade.",
|
|
186
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"title": "Experimental tasks (SEP-2663) removed",
|
|
190
|
+
"description": "The experimental task API is removed: extra.taskStore, extra.taskId, extra.taskRequestedTtl, and the task-handler schema constants (GetTaskRequestSchema, …).",
|
|
191
|
+
"category": "removal",
|
|
192
|
+
"affected_symbols": ["extra.taskStore", "extra.taskId", "extra.taskRequestedTtl", "GetTaskRequestSchema"],
|
|
193
|
+
"before_code": null,
|
|
194
|
+
"after_code": null,
|
|
195
|
+
"migration_note": "There is no v2 equivalent in the beta; Tasks land as part of the 2026-07-28 spec revision. Servers using experimental tasks should stay on v1.x until the stable v2 tasks API ships.",
|
|
196
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"title": "OAuth client hardening: TLS-only token endpoints, issuer binding, finishAuth(params)",
|
|
200
|
+
"description": "Several security behavior changes: (1) exchangeAuthorization()/refreshAuthorization()/fetchToken() throw InsecureTokenEndpointError for non-https token endpoints (loopback exempt); (2) they also throw OAuthError when the AS returns HTTP 200 with an {error} JSON body; (3) credentials are stamped with an issuer field and enforced per-AS (SEP-2352); (4) transport.finishAuth() takes the full callback URLSearchParams to read code + iss for RFC 9207 mix-up defense; (5) StreamableHTTPClientTransport gains onInsufficientScope ('reauthorize' default | 'throw') for 403 scope step-up (SEP-2350).",
|
|
201
|
+
"category": "behavior-change",
|
|
202
|
+
"affected_symbols": ["exchangeAuthorization", "refreshAuthorization", "finishAuth", "OAuthClientProvider", "onInsufficientScope"],
|
|
203
|
+
"before_code": "await transport.finishAuth(code);",
|
|
204
|
+
"after_code": "const params = new URL(callbackUrl).searchParams;\nif (params.get('state') !== expectedState) throw new Error('state mismatch');\nawait transport.finishAuth(params); // reads `code` + `iss`",
|
|
205
|
+
"migration_note": "Pass the full callback searchParams to finishAuth(). Implement the optional discoveryState()/saveDiscoveryState() methods on OAuthClientProvider for issuer binding. Plain-http token endpoints (except localhost/127.0.0.1/::1) now hard-fail. New error classes to handle: InsecureTokenEndpointError, IssuerMismatchError, InsufficientScopeError, AuthorizationServerMismatchError.",
|
|
206
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"title": "Removed Zod compat helpers and misc types",
|
|
210
|
+
"description": "Removed: schemaToJson (use z.toJSONSchema() or fromJsonSchema()), parseSchemaAsync (use the schema library's .safeParseAsync()), getSchemaShape(), getSchemaDescription(), isOptionalSchema(), unwrapOptionalSchema(), AnySchema, SchemaOutput, toJsonSchemaCompat, plus Protocol and mergeCapabilities from shared/protocol.js. SchemaInput<T> is replaced by StandardSchemaWithJSON.InferInput<T>. The ResourceTemplate TYPE (wire type) is renamed ResourceTemplateType; the ResourceTemplate CLASS is unchanged.",
|
|
211
|
+
"category": "removal",
|
|
212
|
+
"affected_symbols": ["schemaToJson", "parseSchemaAsync", "getSchemaShape", "SchemaInput", "Protocol", "mergeCapabilities", "ResourceTemplate"],
|
|
213
|
+
"before_code": "import { schemaToJson } from '@modelcontextprotocol/sdk/server/zod-compat.js';\nconst json = schemaToJson(mySchema);",
|
|
214
|
+
"after_code": "import * as z from 'zod';\nconst json = z.toJSONSchema(mySchema);",
|
|
215
|
+
"migration_note": "The codemod rewrites SchemaInput<T> automatically. Watch the ResourceTemplate name collision: type-position uses become ResourceTemplateType, value/class uses stay ResourceTemplate.",
|
|
216
|
+
"source_url": "https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"deprecations": [
|
|
220
|
+
{
|
|
221
|
+
"symbol": "Server.createMessage()",
|
|
222
|
+
"replacement": "ctx.mcpReq.send({ method: 'sampling/createMessage', params })",
|
|
223
|
+
"removal_timeline": "The server→client sampling channel is eliminated in the 2026-07-28 protocol revision; handlers there return inputRequired(...) instead.",
|
|
224
|
+
"note": "Marked @deprecated in v2 but still functional on the 2025-era protocol."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"symbol": "Server.listRoots()",
|
|
228
|
+
"replacement": "ctx.mcpReq.send({ method: 'roots/list' })",
|
|
229
|
+
"removal_timeline": "The roots capability is deprecated by the 2026-07-28 protocol revision.",
|
|
230
|
+
"note": "Marked @deprecated in v2 but still functional on the 2025-era protocol."
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"symbol": "Server.sendLoggingMessage()",
|
|
234
|
+
"replacement": null,
|
|
235
|
+
"removal_timeline": "The logging capability is deprecated by the 2026-07-28 protocol revision.",
|
|
236
|
+
"note": "Marked @deprecated in v2; ctx.mcpReq.log() is likewise deprecated."
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"symbol": "Client.setLoggingLevel()",
|
|
240
|
+
"replacement": null,
|
|
241
|
+
"removal_timeline": "The logging capability is deprecated by the 2026-07-28 protocol revision.",
|
|
242
|
+
"note": "Marked @deprecated in v2."
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"symbol": "Client.sendRootsListChanged()",
|
|
246
|
+
"replacement": null,
|
|
247
|
+
"removal_timeline": "The roots capability is deprecated by the 2026-07-28 protocol revision.",
|
|
248
|
+
"note": "Marked @deprecated in v2."
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"symbol": "ctx.mcpReq.requestSampling()",
|
|
252
|
+
"replacement": "inputRequired(...) return pattern (2026-07-28 protocol)",
|
|
253
|
+
"removal_timeline": "Eliminated when serving the 2026-07-28 revision.",
|
|
254
|
+
"note": "On 2026-07-28, handlers return inputRequired({ inputRequests: ... }) and read responses on retry via acceptedContent(ctx.mcpReq.inputResponses, id)."
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"symbol": "capabilities.roots / capabilities.sampling / capabilities.logging",
|
|
258
|
+
"replacement": "inputRequired(...) return-value pattern for input; no logging replacement",
|
|
259
|
+
"removal_timeline": "These server→client request channels do not exist on the 2026-07-28 protocol revision.",
|
|
260
|
+
"note": "Declaring them is deprecated in v2 even on the 2025-era protocol."
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"symbol": "registerClient() (OAuth Dynamic Client Registration)",
|
|
264
|
+
"replacement": null,
|
|
265
|
+
"removal_timeline": null,
|
|
266
|
+
"note": "Marked @deprecated in v2; throws RegistrationRejectedError with status/body/submittedMetadata on rejection."
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"symbol": "Raw Zod shape overloads of registerTool()/registerPrompt()",
|
|
270
|
+
"replacement": "z.object({ ... }) / any Standard Schema object",
|
|
271
|
+
"removal_timeline": "Deprecated overloads slated for removal in a later v2 release.",
|
|
272
|
+
"note": "Still functional in 2.0.0-beta.2."
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
"source_urls": [
|
|
276
|
+
"https://ts.sdk.modelcontextprotocol.io/v2/migration/upgrade-to-v2.html",
|
|
277
|
+
"https://ts.sdk.modelcontextprotocol.io/v2/migration/support-2026-07-28.html",
|
|
278
|
+
"https://blog.modelcontextprotocol.io/posts/sdk-betas-2026-07-28/",
|
|
279
|
+
"https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/",
|
|
280
|
+
"https://github.com/modelcontextprotocol/typescript-sdk/releases"
|
|
281
|
+
],
|
|
282
|
+
"last_verified": "2026-07-03",
|
|
283
|
+
"status": "draft"
|
|
284
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ecosystem": "npm",
|
|
3
|
+
"package": "next",
|
|
4
|
+
"from_version": "14.2.35",
|
|
5
|
+
"to_version": "15.0.0",
|
|
6
|
+
"summary": "Next.js 15 (published 2024-10-21) makes request-time APIs asynchronous and flips core caching defaults. cookies(), headers(), draftMode(), and the params/searchParams props (in layout.js, page.js, route.js, default.js, generateMetadata, generateViewport, and metadata image files) now return Promises and must be awaited (or unwrapped with React use() in client components); synchronous access temporarily works with dev warnings. Caching inverts: fetch() requests, GET Route Handlers, and client-router page segments are no longer cached by default — restore with cache: 'force-cache', dynamic = 'force-static', and experimental.staleTimes respectively. The App Router requires React 19 (Pages Router keeps React 18 compatibility); useFormState is deprecated for useActionState. The external @next/font package is removed in favor of built-in next/font. next.config renames: experimental.bundlePagesExternals -> bundlePagesRouterDependencies, experimental.serverComponentsExternalPackages -> serverExternalPackages. runtime = 'experimental-edge' now errors (use 'edge'). NextRequest geo/ip are removed (use @vercel/functions). next/image drops squoosh (sharp is used automatically), Speed Insights auto-instrumentation is removed, and the minimum Node.js version is 18.18.0. Codemods automate most of it: npx @next/codemod@canary upgrade latest, and next-async-request-api for the async APIs.",
|
|
7
|
+
"breaking_changes": [
|
|
8
|
+
{
|
|
9
|
+
"title": "cookies(), headers(), draftMode() are now async",
|
|
10
|
+
"description": "The request-time APIs from next/headers return Promises in Next.js 15. Synchronous access still works temporarily (with a dev warning) via the UnsafeUnwrapped* types, but is slated for removal.",
|
|
11
|
+
"category": "signature-change",
|
|
12
|
+
"affected_symbols": ["cookies", "headers", "draftMode"],
|
|
13
|
+
"before_code": "import { cookies, headers } from 'next/headers'\n\nconst cookieStore = cookies()\nconst token = cookieStore.get('token')\n\nconst headersList = headers()\nconst userAgent = headersList.get('user-agent')",
|
|
14
|
+
"after_code": "import { cookies, headers } from 'next/headers'\n\nconst cookieStore = await cookies()\nconst token = cookieStore.get('token')\n\nconst headersList = await headers()\nconst userAgent = headersList.get('user-agent')",
|
|
15
|
+
"migration_note": "Add await at every call site (the enclosing function becomes async). Codemod: npx @next/codemod@canary next-async-request-api . — the escape hatch cookies() as unknown as UnsafeUnwrappedCookies logs warnings and only buys time until the next major.",
|
|
16
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"title": "params and searchParams props are now Promises in pages, layouts, and metadata",
|
|
20
|
+
"description": "params (in layout.js, page.js, default.js, generateMetadata, generateViewport, opengraph-image, twitter-image, icon, apple-icon) and searchParams (in page.js) are Promise-typed. Server components await them; client components unwrap with React's use().",
|
|
21
|
+
"category": "signature-change",
|
|
22
|
+
"affected_symbols": ["params", "searchParams", "generateMetadata", "generateViewport"],
|
|
23
|
+
"before_code": "type Params = { slug: string }\ntype SearchParams = { [key: string]: string | string[] | undefined }\n\nexport default async function Page({\n params,\n searchParams,\n}: {\n params: Params\n searchParams: SearchParams\n}) {\n const { slug } = params\n const { query } = searchParams\n}",
|
|
24
|
+
"after_code": "type Params = Promise<{ slug: string }>\ntype SearchParams = Promise<{ [key: string]: string | string[] | undefined }>\n\nexport default async function Page(props: {\n params: Params\n searchParams: SearchParams\n}) {\n const params = await props.params\n const searchParams = await props.searchParams\n const slug = params.slug\n const query = searchParams.query\n}\n\n// Client ('use client') components cannot be async — unwrap with use():\n// import { use } from 'react'\n// const params = use(props.params)",
|
|
25
|
+
"migration_note": "Update BOTH the runtime access (await / use()) and the prop TYPES (Params becomes Promise<{...}>) — type-only fixes that skip the await produce '[object Promise]' bugs. This is the single most common v15 break agents write incorrectly from v14-era training data. Codemod: next-async-request-api.",
|
|
26
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"title": "params in Route Handlers are now a Promise",
|
|
30
|
+
"description": "The second argument of Route Handler methods (GET, POST, …) carries params as a Promise that must be awaited.",
|
|
31
|
+
"category": "signature-change",
|
|
32
|
+
"affected_symbols": ["route.js params", "GET", "POST"],
|
|
33
|
+
"before_code": "type Params = { slug: string }\n\nexport async function GET(request: Request, segmentData: { params: Params }) {\n const params = segmentData.params\n const slug = params.slug\n}",
|
|
34
|
+
"after_code": "type Params = Promise<{ slug: string }>\n\nexport async function GET(request: Request, segmentData: { params: Params }) {\n const params = await segmentData.params\n const slug = params.slug\n}",
|
|
35
|
+
"migration_note": "Same Promise pattern as pages: update the type to Promise<...> and await it inside the handler.",
|
|
36
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"title": "fetch() requests are no longer cached by default",
|
|
40
|
+
"description": "Server-side fetch() in the App Router defaults to uncached in v15 (v14 cached by default). Additionally, dynamic = 'force-dynamic' now sets a no-store default on the fetch cache.",
|
|
41
|
+
"category": "behavior-change",
|
|
42
|
+
"affected_symbols": ["fetch", "fetchCache"],
|
|
43
|
+
"before_code": "export default async function RootLayout() {\n const a = await fetch('https://...') // Cached by default in v14\n}",
|
|
44
|
+
"after_code": "export default async function RootLayout() {\n const a = await fetch('https://...') // NOT cached in v15\n const b = await fetch('https://...', { cache: 'force-cache' }) // Cached\n}\n\n// Or opt a whole layout/page back in:\nexport const fetchCache = 'default-cache'",
|
|
45
|
+
"migration_note": "Silent performance/cost regression rather than a compile error: origin APIs get hit on every request after upgrading. Re-add caching per request (cache: 'force-cache') or per segment (fetchCache = 'default-cache').",
|
|
46
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"title": "GET Route Handlers are no longer cached by default",
|
|
50
|
+
"description": "In v14, GET Route Handlers were cached by default unless they used dynamic functions/config. In v15 they are uncached by default. Metadata routes (sitemap.ts, opengraph-image.tsx, icon.tsx) remain static by default.",
|
|
51
|
+
"category": "behavior-change",
|
|
52
|
+
"affected_symbols": ["GET", "dynamic"],
|
|
53
|
+
"before_code": "// v14: cached by default\nexport async function GET() {}",
|
|
54
|
+
"after_code": "// v15: opt back into static caching explicitly\nexport const dynamic = 'force-static'\n\nexport async function GET() {}",
|
|
55
|
+
"migration_note": "Audit GET route handlers that relied on implicit caching (e.g. expensive computations, third-party calls) and add export const dynamic = 'force-static' where the old behavior is wanted.",
|
|
56
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"title": "Client Router Cache: page segments no longer reused on navigation",
|
|
60
|
+
"description": "Page segments get a staleTime of 0: navigating via <Link> or useRouter always fetches fresh page data. Shared layouts and loading.js stay cached (loading.js for 5 minutes), and back/forward navigation still restores from cache.",
|
|
61
|
+
"category": "behavior-change",
|
|
62
|
+
"affected_symbols": ["staleTimes", "Link", "useRouter"],
|
|
63
|
+
"before_code": "// v14: revisiting a page within 30s reused the client cache — no config needed",
|
|
64
|
+
"after_code": "// next.config.js — opt back into v14-like behavior:\n/** @type {import('next').NextConfig} */\nconst nextConfig = {\n experimental: {\n staleTimes: {\n dynamic: 30,\n static: 180,\n },\n },\n}\n\nmodule.exports = nextConfig",
|
|
65
|
+
"migration_note": "Apps that felt 'instant' on back-and-forth navigation may issue more server requests after upgrading. experimental.staleTimes restores the old feel; leaving the default guarantees fresh data.",
|
|
66
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"title": "App Router requires React 19",
|
|
70
|
+
"description": "Minimum react/react-dom is 19 for the App Router. The Pages Router retains React 18 backward compatibility (running both React versions in one app is possible but not recommended).",
|
|
71
|
+
"category": "config-change",
|
|
72
|
+
"affected_symbols": ["react", "react-dom", "@types/react", "@types/react-dom"],
|
|
73
|
+
"before_code": "// package.json\n\"react\": \"^18.3.1\",\n\"react-dom\": \"^18.3.1\"",
|
|
74
|
+
"after_code": "// package.json\n\"react\": \"19.x\",\n\"react-dom\": \"19.x\"\n// TypeScript: also upgrade @types/react and @types/react-dom",
|
|
75
|
+
"migration_note": "Upgrade React together with Next (npx @next/codemod@canary upgrade latest handles it). useFormState is deprecated in favor of useActionState (see deprecations); useFormStatus gains data/method/action keys on React 19.",
|
|
76
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"title": "@next/font package removed — use built-in next/font",
|
|
80
|
+
"description": "The external @next/font package no longer works; the font utilities are built into next/font. Font-family hashing was also removed.",
|
|
81
|
+
"category": "removal",
|
|
82
|
+
"affected_symbols": ["@next/font", "@next/font/google", "@next/font/local"],
|
|
83
|
+
"before_code": "import { Inter } from '@next/font/google'",
|
|
84
|
+
"after_code": "import { Inter } from 'next/font/google'",
|
|
85
|
+
"migration_note": "Rename imports and drop the @next/font dependency. Codemod: built-in-next-font.",
|
|
86
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"title": "next.config: experimental.serverComponentsExternalPackages -> serverExternalPackages",
|
|
90
|
+
"description": "The option is stable and renamed; the experimental key no longer applies.",
|
|
91
|
+
"category": "config-change",
|
|
92
|
+
"affected_symbols": ["experimental.serverComponentsExternalPackages", "serverExternalPackages"],
|
|
93
|
+
"before_code": "const nextConfig = {\n experimental: {\n serverComponentsExternalPackages: ['package-name'],\n },\n}",
|
|
94
|
+
"after_code": "const nextConfig = {\n serverExternalPackages: ['package-name'],\n}",
|
|
95
|
+
"migration_note": "Move the array to the top level under the new name. v15 also adds next.config.ts support with the NextConfig type if you want typed config while touching this file.",
|
|
96
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"title": "next.config: experimental.bundlePagesExternals -> bundlePagesRouterDependencies",
|
|
100
|
+
"description": "The Pages Router external-bundling option is stable and renamed.",
|
|
101
|
+
"category": "config-change",
|
|
102
|
+
"affected_symbols": ["experimental.bundlePagesExternals", "bundlePagesRouterDependencies"],
|
|
103
|
+
"before_code": "const nextConfig = {\n experimental: {\n bundlePagesExternals: true,\n },\n}",
|
|
104
|
+
"after_code": "const nextConfig = {\n bundlePagesRouterDependencies: true,\n}",
|
|
105
|
+
"migration_note": "Top-level rename; combine with serverExternalPackages to opt specific packages out of bundling across both routers.",
|
|
106
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"title": "runtime = 'experimental-edge' now errors",
|
|
110
|
+
"description": "The segment config value 'experimental-edge' (same meaning as 'edge') is no longer accepted — builds error until it is renamed.",
|
|
111
|
+
"category": "config-change",
|
|
112
|
+
"affected_symbols": ["runtime"],
|
|
113
|
+
"before_code": "export const runtime = 'experimental-edge'",
|
|
114
|
+
"after_code": "export const runtime = 'edge'",
|
|
115
|
+
"migration_note": "Straight rename. Codemod: app-dir-runtime-config-experimental-edge.",
|
|
116
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"title": "NextRequest geo and ip properties removed",
|
|
120
|
+
"description": "request.geo and request.ip are gone from NextRequest — those values come from the hosting provider. On Vercel, use geolocation() and ipAddress() from @vercel/functions.",
|
|
121
|
+
"category": "removal",
|
|
122
|
+
"affected_symbols": ["NextRequest.geo", "NextRequest.ip"],
|
|
123
|
+
"before_code": "import type { NextRequest } from 'next/server'\n\nexport function middleware(request: NextRequest) {\n const city = request.geo?.city\n const ip = request.ip\n}",
|
|
124
|
+
"after_code": "import { geolocation, ipAddress } from '@vercel/functions'\nimport type { NextRequest } from 'next/server'\n\nexport function middleware(request: NextRequest) {\n const { city } = geolocation(request)\n const ip = ipAddress(request)\n}",
|
|
125
|
+
"migration_note": "npm install @vercel/functions on Vercel; on other hosts read the equivalent request headers your provider sets. A codemod automates the Vercel variant.",
|
|
126
|
+
"source_url": "https://nextjs.org/docs/app/guides/upgrading/version-15"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"title": "next/image: squoosh removed, sharp used automatically; Content-Disposition now attachment",
|
|
130
|
+
"description": "The squoosh WASM optimizer is removed and sharp becomes the (auto-installed at runtime) optimizer for next start and standalone output. The optimized-image Content-Disposition default changed to attachment, and src values with leading/trailing spaces now error.",
|
|
131
|
+
"category": "removal",
|
|
132
|
+
"affected_symbols": ["squoosh", "sharp", "next/image"],
|
|
133
|
+
"before_code": "// v14 self-hosting: sharp was a manual recommendation\n// npm install sharp (falls back to squoosh if missing)",
|
|
134
|
+
"after_code": "// v15: no manual step — sharp is used automatically with\n// `next start` or standalone output mode",
|
|
135
|
+
"migration_note": "Self-hosted deployments no longer silently fall back to slow WASM optimization. Watch the Content-Disposition change if images were expected to render inline when opened directly, and trim whitespace in src values.",
|
|
136
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"title": "Speed Insights auto-instrumentation removed",
|
|
140
|
+
"description": "Next.js no longer auto-instruments Vercel Speed Insights; the dedicated @vercel/speed-insights package is required.",
|
|
141
|
+
"category": "removal",
|
|
142
|
+
"affected_symbols": ["Speed Insights"],
|
|
143
|
+
"before_code": null,
|
|
144
|
+
"after_code": "// npm install @vercel/speed-insights\nimport { SpeedInsights } from '@vercel/speed-insights/next'\n// render <SpeedInsights /> in the root layout",
|
|
145
|
+
"migration_note": "Follow the Vercel Speed Insights quickstart — metrics silently stop flowing after the upgrade otherwise.",
|
|
146
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"title": "Minimum Node.js version is 18.18.0",
|
|
150
|
+
"description": "Next.js 15 raises the minimum required Node.js version to 18.18.0.",
|
|
151
|
+
"category": "config-change",
|
|
152
|
+
"affected_symbols": ["node"],
|
|
153
|
+
"before_code": null,
|
|
154
|
+
"after_code": "// package.json\n\"engines\": { \"node\": \">=18.18.0\" }",
|
|
155
|
+
"migration_note": "Update CI images, Dockerfiles, and engines fields; older 18.x patch lines fail.",
|
|
156
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"title": "revalidateTag/revalidatePath during render now throw",
|
|
160
|
+
"description": "Calling revalidateTag() or revalidatePath() while a component is rendering is an error in v15; they belong in Server Actions or Route Handlers.",
|
|
161
|
+
"category": "behavior-change",
|
|
162
|
+
"affected_symbols": ["revalidateTag", "revalidatePath"],
|
|
163
|
+
"before_code": "// v14: calling revalidateTag('posts') inside a rendering\n// Server Component happened to work",
|
|
164
|
+
"after_code": "'use server'\n// v15: revalidation belongs in Server Actions / Route Handlers\nexport async function updatePosts() {\n // ...mutate data...\n revalidateTag('posts')\n}",
|
|
165
|
+
"migration_note": "Move revalidation calls out of render paths into the mutation that triggers them.",
|
|
166
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"title": "next/dynamic: suspense prop removed; ssr:false disallowed in Server Components",
|
|
170
|
+
"description": "The deprecated suspense prop is removed (no empty Suspense boundary is inserted in the App Router), and using next/dynamic with ssr: false inside a Server Component is now an error.",
|
|
171
|
+
"category": "removal",
|
|
172
|
+
"affected_symbols": ["next/dynamic", "suspense", "ssr: false"],
|
|
173
|
+
"before_code": "// In a Server Component (v14 tolerated this):\nconst Widget = dynamic(() => import('./widget'), { ssr: false })",
|
|
174
|
+
"after_code": "// Move the dynamic(..., { ssr: false }) call into a Client Component:\n'use client'\nimport dynamic from 'next/dynamic'\nconst Widget = dynamic(() => import('./widget'), { ssr: false })",
|
|
175
|
+
"migration_note": "Wrap client-only dynamic imports in a 'use client' component and render that from the server tree.",
|
|
176
|
+
"source_url": "https://nextjs.org/blog/next-15"
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"deprecations": [
|
|
180
|
+
{
|
|
181
|
+
"symbol": "Synchronous access to cookies()/headers()/draftMode()/params/searchParams",
|
|
182
|
+
"replacement": "await the API (server) or unwrap with React use() (client); UnsafeUnwrappedCookies/UnsafeUnwrappedHeaders/UnsafeUnwrappedDraftMode type the interim",
|
|
183
|
+
"removal_timeline": "Temporary compatibility only — warns in development and production until the next major version, where synchronous access is removed.",
|
|
184
|
+
"note": "The codemod (next-async-request-api) converts most call sites; the UnsafeUnwrapped* casts exist to unblock incremental migration, not as a destination."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"symbol": "useFormState",
|
|
188
|
+
"replacement": "useActionState (React 19)",
|
|
189
|
+
"removal_timeline": "Still available in React 19 but deprecated; will be removed in a future React release.",
|
|
190
|
+
"note": "useActionState adds direct access to the pending state. useFormStatus additionally gains data, method, and action keys on React 19."
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"source_urls": [
|
|
194
|
+
"https://nextjs.org/docs/app/guides/upgrading/version-15",
|
|
195
|
+
"https://nextjs.org/blog/next-15"
|
|
196
|
+
],
|
|
197
|
+
"last_verified": "2026-07-03",
|
|
198
|
+
"status": "draft"
|
|
199
|
+
}
|
package/dist/index.d.ts
ADDED