|
| 1 | +--- |
| 2 | +outline: deep |
| 3 | +--- |
| 4 | + |
| 5 | +# Migrating to 0.8 |
| 6 | + |
| 7 | +0.8 makes RPC schemas validator-neutral and validated at runtime, upgrades the MCP adapter to `@modelcontextprotocol/sdk` v2, and lands the agent-native MCP surface (`ctx.agent`, tool providers, and the `devframe connect` connector). This page covers the changes between 0.7.x and 0.8 — see the [v0.8.0 release notes](https://github.com/devframes/devframe/releases/tag/v0.8.0) for the full changelog. |
| 8 | + |
| 9 | +## RPC schemas are Standard Schema and validated at runtime |
| 10 | + |
| 11 | +`args` and `returns` on `defineRpcFunction` are now typed against [Standard Schema](https://standardschema.dev/) rather than valibot's `GenericSchema`. Any Standard-Schema-compliant validator works — valibot, zod, arktype — so existing valibot schemas keep compiling and inferring types unchanged. |
| 12 | + |
| 13 | +Two things change in practice: |
| 14 | + |
| 15 | +**Devframe no longer bundles a validator.** `valibot` was dropped from `devframe`'s runtime dependencies, so author your schemas with whichever validator you prefer and install it yourself: |
| 16 | + |
| 17 | +```sh |
| 18 | +npm install valibot # or: zod / arktype |
| 19 | +``` |
| 20 | + |
| 21 | +If your app already pulls in zod (the JSON-render integration and the MCP server both use it), prefer zod for your RPC schemas and reuse the dependency. For first-party code that wants zero dependencies, devframe ships a minimal built-in builder at `devframe/utils/simple-schema`: |
| 22 | + |
| 23 | +```ts |
| 24 | +// Bring your own validator … |
| 25 | +import { defineRpcFunction } from 'devframe' |
| 26 | +import * as v from 'valibot' |
| 27 | + |
| 28 | +export const rename = defineRpcFunction({ |
| 29 | + name: 'devframes:plugin:terminals:rename', |
| 30 | + type: 'action', |
| 31 | + args: [v.object({ id: v.string(), title: v.string() })], |
| 32 | + returns: v.void(), |
| 33 | + setup: ctx => ({ handler: ({ id, title }) => { /* … */ } }), |
| 34 | +}) |
| 35 | +``` |
| 36 | + |
| 37 | +```ts |
| 38 | +// … or use the built-in zero-dep builder |
| 39 | +import { defineRpcFunction } from 'devframe' |
| 40 | +import { s } from 'devframe/utils/simple-schema' |
| 41 | + |
| 42 | +export const rename = defineRpcFunction({ |
| 43 | + name: 'devframes:plugin:terminals:rename', |
| 44 | + type: 'action', |
| 45 | + args: [s.object({ id: s.string(), title: s.string() })], |
| 46 | + returns: s.void(), |
| 47 | + setup: ctx => ({ handler: ({ id, title }) => { /* … */ } }), |
| 48 | +}) |
| 49 | +``` |
| 50 | + |
| 51 | +**Declared schemas are now enforced.** Each argument is validated against its schema at the boundary before the handler runs, and the resolved return value is validated on the way out; a mismatch is rejected with a coded diagnostic instead of reaching (or leaving) the handler. Payloads are guarded, not rewritten — extra object fields the schema doesn't mention still reach the handler. Audit any schema that was previously more of a type hint than a contract, since inputs that used to slip through now throw. |
| 52 | + |
| 53 | +See [RPC](./rpc) for the full reference. |
| 54 | + |
| 55 | +## MCP adapter upgraded to `@modelcontextprotocol/sdk` v2 |
| 56 | + |
| 57 | +The MCP adapter now targets the v2 SDK, which ships as scoped `@modelcontextprotocol/server` and `@modelcontextprotocol/client` packages. Swap the peer dependency when you ship MCP support: |
| 58 | + |
| 59 | +| 0.7.x | 0.8 | |
| 60 | +|-------|-----| |
| 61 | +| `@modelcontextprotocol/sdk@^1` | `@modelcontextprotocol/server@^2` | |
| 62 | + |
| 63 | +```sh |
| 64 | +npm uninstall @modelcontextprotocol/sdk |
| 65 | +npm install @modelcontextprotocol/server |
| 66 | +``` |
| 67 | + |
| 68 | +`@modelcontextprotocol/server` remains an optional peer dependency, pulled in only through `devframe/adapters/mcp`. The `devframe connect` connector (below) additionally uses `@modelcontextprotocol/client` — install it too if you drive agents through the connector. |
| 69 | + |
| 70 | +If you imported SDK types directly, the deep `@modelcontextprotocol/sdk/...` subpaths are now flat entries on the scoped packages (e.g. `@modelcontextprotocol/sdk/server/stdio.js` → `@modelcontextprotocol/server/stdio`). See [MCP](/adapters/mcp) for the adapter reference. |
| 71 | + |
| 72 | +## Agent-native MCP surface |
| 73 | + |
| 74 | +0.8 adds the agent host on `ctx.agent` — `registerTool`, `registerToolProvider`, and `registerResource` — plus an instance registry and the `devframe connect` MCP connector shipped in the `devframe` bin. These are additive; existing `agent`-flagged RPCs keep working and are projected to MCP as before. |
| 75 | + |
| 76 | +One type sharpens: an RPC `handler` (and its `dump`) now returns `Thenable<returns>` — the `returns` schema describes the *resolved* value and the runtime always awaits the handler. Synchronous handlers are unaffected; an `async` handler whose declared `returns` was the unwrapped value now type-checks correctly rather than needing the promise spelled into the schema. |
| 77 | + |
| 78 | +See [Agent-Native](./agent-native) for the tool/resource surface and [MCP → `devframe connect`](/adapters/mcp#discovery-devframe-connect) for the connector. |
0 commit comments