|
1 | 1 | --- |
2 | 2 | title: 'Migrating to 0.9' |
3 | | -description: '0.9 removes the compatibility shims deprecated across the 0.7 series and trims the public API of devframe and @devframes/hub. Each change has a drop-in replacement.' |
| 3 | +description: '0.9 removes the compatibility shims deprecated across the 0.7 series, trims the public API of devframe and @devframes/hub, and moves the MCP surface to the stateless MCP 2026-07-28 protocol.' |
4 | 4 | --- |
5 | 5 |
|
6 | | -0.9 removes the compatibility shims deprecated across the 0.7 series and trims the public API of `devframe` and `@devframes/hub`. Each change has a drop-in replacement. |
| 6 | +0.9 removes the compatibility shims deprecated across the 0.7 series and trims the public API of `devframe` and `@devframes/hub`. Each change has a drop-in replacement. It also moves the [MCP](/adapters/mcp) surface to the stateless [MCP 2026-07-28 protocol](https://modelcontextprotocol.io/specification/2026-07-28) — the devframe API is unchanged; see [The MCP endpoints are stateless](#the-mcp-endpoints-are-stateless). |
7 | 7 |
|
8 | 8 | ## `devframe/adapters/cli` is removed |
9 | 9 |
|
@@ -332,3 +332,23 @@ export const DELETE = (req: Request) => hub.handler(req) |
332 | 332 | ``` |
333 | 333 |
|
334 | 334 | `@devframes/vite/hub` and `@devframes/nuxt/hub` recommend the native [Vite DevTools](https://devtools.vite.dev) / [Nuxt DevTools](https://devtools.nuxt.com) once (silence with `{ quiet: true }`); `@devframes/next/hub` stays quiet. |
| 335 | + |
| 336 | +## The MCP endpoints are stateless |
| 337 | + |
| 338 | +The [MCP](/adapters/mcp) surface serves the stateless [2026-07-28 protocol](https://modelcontextprotocol.io/specification/2026-07-28). The devframe API you author against — `createMcpServer`, `createMcpFetchHandler`, `mountMcpHttp`, `cli.mcp`, and the agent host — is unchanged; the change is in how the endpoints serve requests on the wire. |
| 339 | + |
| 340 | +- **HTTP** serves each request through the SDK's `createMcpHandler`, building a fresh server per request. There is no `Mcp-Session-Id` and no `initialize` handshake to open a session, so a request reaches any server instance without affinity. A `GET` or `DELETE` (the 2025 session operations) is answered `405`. 2025-era clients keep listing and calling tools and resources through the SDK's stateless legacy path; the live server-push channel for `list_changed` notifications is available to modern clients over the `subscriptions/listen` stream they open. |
| 341 | +- **stdio** serves the connection through the SDK's `serveStdio`, pinning one server instance per connection and negotiating the 2026-07-28 era (falling back to the 2025 handshake for a 2025-era opening). |
| 342 | +- **`devframe connect`** probes each instance with `server/discover` and negotiates the modern era, falling back to the 2025 handshake for a 2025-only instance. |
| 343 | + |
| 344 | +A client that connects to devframe's HTTP endpoint should negotiate the modern era to use the stateless protocol; one left on the default (2025-era) negotiation is still served through the stateless legacy path: |
| 345 | + |
| 346 | +```ts |
| 347 | +import { Client } from '@modelcontextprotocol/client' |
| 348 | + |
| 349 | +const client = new Client( |
| 350 | + { name: 'my-client', version: '1.0.0' }, |
| 351 | + { versionNegotiation: { mode: 'auto' } }, |
| 352 | +) |
| 353 | +await client.connect(transport) |
| 354 | +``` |
0 commit comments