You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: apply review feedback and tighten prose to ~65%
- Add the intro point that, with agents, Devframe is a fast foundation for
bespoke or one-off devtools (addresses review comment on the introduction).
- Fix the stale hosted-base default in the definition reference (/__<id>/)
and drop the remaining deprecated cli.distDir mentions.
- Continue the concision pass across the guide, adapters, frameworks,
plugins, and helpers, bringing total markdown to ~65% of the original
while preserving code, tables, warnings, links, and technical facts.
Created with the help of an agent.
The RPC socket shares the HTTP port on`__ws`, advertised *relative* so the client dials its own origin through a reverse proxy. Configure `def.cli.ws`:
38
+
The RPC socket shares the HTTP port at`__ws`, advertised *relative*. Configure `def.cli.ws`:
39
39
40
40
| Field | Scenario | Advertised `websocket`|
41
41
|-------|----------|------------------------|
42
42
|`route`| same server, other route |`{ path: <route> }`|
43
43
|`port`| different port |`{ port, path: <route> }`|
44
44
|`url`| remote origin | URL verbatim |
45
45
46
-
Precedence `url` > `port` > `route`; for `url` the socket stays local on `route` — point your tunnel there.
46
+
Precedence `url` > `port` > `route`; `url`keeps the socket local on `route`.
47
47
48
48
## Port resolution
49
49
50
-
`resolveDevServerPort(def, opts?)` resolves a port before start:
50
+
`resolveDevServerPort(def, opts?)` resolves a port before start.
Copy file name to clipboardExpand all lines: docs/adapters/initiate.md
+10-10Lines changed: 10 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# The Standard Handler
2
2
3
-
`initDevframe()`is the boundary the whole project is built on: it turns a `DevframeDefinition` into a live instance whose `.handler` — a Web Standard `(request: Request) => Promise<Response>` — carries the entire surface (SPA, `__connection.json` discovery, RPC socket, auth gate, MCP route) under one mount base. Every other serving path — the [adapters](./), the [framework packages](/frameworks/), and the [hub](../guide/hub-initiate) — is assembled from it. Mount it in any app with a catch-all route.
3
+
`initDevframe()` turns a `DevframeDefinition` into a live instance whose `.handler` — a Web Standard `(request: Request) => Promise<Response>` — carries the entire surface (SPA, `__connection.json` discovery, RPC socket, auth gate, MCP route) under one mount base. Every other serving path — [adapters](./), [framework packages](/frameworks/), [hub](../guide/hub-initiate) — is assembled from it. Mount it with a catch-all route.
`base` is required, so the mount path is explicit — pass `resolveBasePath(def, 'hosted')` (`def.basePath ?? /__<id>/`) if you don't want to pick one; the instance echoes it back as `devtools.base`. `handler`/`nodeMiddleware` await readiness internally, so hosts never race boot. Creating an instance binds no port — [the WebSocket binding](#the-websocket-binding) is the host's call.
15
+
`base` is required— pass `resolveBasePath(def, 'hosted')` (`def.basePath ?? /__<id>/`) to default it; the instance echoes it back as `devtools.base`. `handler`/`nodeMiddleware` await readiness internally. The instance binds no port — [the WebSocket binding](#the-websocket-binding) is the host's call.
Frameworks with dev-time module reloading (Next, Nitro, SvelteKit) re-evaluate the calling module, so memoize the instance on `globalThis`— otherwise every reload leaks the previous socket. `@devframes/next`'s `createDevframeNextHandler`does this for you.
111
+
Frameworks with dev-time module reloading (Next, Nitro, SvelteKit) re-evaluate the calling module, so memoize the instance on `globalThis`to avoid leaking a socket per reload. `@devframes/next`'s `createDevframeNextHandler`handles this.
112
112
113
113
## The WebSocket binding
114
114
115
-
Fetch handlers hand over `Request`s, so the host binds the RPC socket explicitly. The **local binding** resolves in precedence order:
115
+
Fetch handlers only hand over `Request`s, so the host binds the RPC socket. The **local binding** resolves in this order:
116
116
117
117
1.**`ws.port`** — a side-car server on that exact port.
118
-
2.**`server`** — share the host's `node:http` server; the upgrade binds at `<base>__ws`. No extra ports; the socket follows the app through proxies and HTTPS.
118
+
2.**`server`** — share the host's `node:http` server; the upgrade binds at `<base>__ws`. No extra ports.
119
119
3.**`ws: { sidecar: true }`** — a side-car server on a free port, for hosts whose handlers never see upgrades (Next.js route handlers, Nitro, Rsbuild).
120
-
4.**The host's own upgrades** — with none of the above, the socket waits: `devtools.attach(server)` routes a server's `upgrade` events (returning a detach fn); `devtools.handleUpgrade(req, socket, head)` completes a single one from a listener you own. Built lazily.
120
+
4.**The host's own upgrades** — with none set, the socket waits: `devtools.attach(server)` routes a server's `upgrade` events (returning a detach fn); `devtools.handleUpgrade(req, socket, head)` completes a single one from a listener you own.
121
121
122
-
`ws.url` controls the *advertisement* instead — the browser dials it verbatim. Alone, an external server owns the transport and its auth (wire in the instance's `context` via `createContextRpcServer` + a WS transport); alongside a local binding it overrides only what's advertised (the tunnel pattern).
122
+
`ws.url` controls the *advertisement* instead — the browser dials it verbatim. Alone, an external server owns the transport and its auth (wire the instance's `context` via `createContextRpcServer` + a WS transport); alongside a local binding it overrides only the advertisement (the tunnel pattern).
123
123
124
-
`__connection.json` describes whichever combination is active. Asking a configured instance to also take over host upgrades reports `DF0055` (a local binding owns the socket) or `DF0056` (`ws.url` handed it off).
124
+
`__connection.json` describes the active combination. Asking a configured instance to take over host upgrades reports `DF0055` (a local binding owns the socket) or `DF0056` (`ws.url` handed it off).
125
125
126
126
## Auth
127
127
128
-
The instance **gates by default**. The interactive OTP handler is wired automatically and prints its code/magic-link banner once the public origin is known (the first request, or the `origin` option). Pass `auth: false` for single-user localhost, or a `DevframeAuthHandler` for a custom scheme.
128
+
The instance **gates by default**. The interactive OTP handler wires automatically, printing its code/magic-link banner once the public origin is known (the first request, or the `origin` option). Pass `auth: false` for single-user localhost, or a `DevframeAuthHandler` for a custom scheme.
129
129
130
130
## Relation to the other adapters
131
131
132
-
`createDevServer`, `devframeViteBridge` (`@devframes/vite`), and `@devframes/next` are assembled from this instance internally. To host **many** devframes with shared transport and docks, use [`initHub`](../guide/hub-initiate).
132
+
`createDevServer`, `devframeViteBridge` (`@devframes/vite`), and `@devframes/next` are assembled from it internally. To host **many** devframes, use [`initHub`](../guide/hub-initiate).
Copy file name to clipboardExpand all lines: docs/adapters/mcp.md
+11-11Lines changed: 11 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ outline: deep
4
4
5
5
# MCP
6
6
7
-
Translates a devframe's agent host into a [Model Context Protocol](https://modelcontextprotocol.io) server: agents call flagged RPCs and read exposed resources.
7
+
Exposes a devframe's agent host as a [Model Context Protocol](https://modelcontextprotocol.io) server: agents call flagged RPCs and read resources.
The endpoint speaks Streamable-HTTP at `/__mcp` (`/__<id>/__mcp` under a host), sharing its origin/port. `--mcp` / `--no-mcp` override per run; `__connection.json` advertises the route.
33
+
The endpoint speaks Streamable-HTTP at `/__mcp` (`/__<id>/__mcp` under a host), sharing its origin/port. `--mcp` / `--no-mcp` override; `__connection.json` advertises it.
34
34
35
-
Each session gets its own MCP server from the live context, keyed by `Mcp-Session-Id`. An origin gate requires `Origin` be loopback (or allow-listed); unlike WS it rejects `Origin`-less requests — `devframe connect` sends its loopback origin explicitly. Widen for a tunnel/LAN origin with `cli: { mcp: { allowedOrigins: ['https://tunnel.example.com'] } }`.
35
+
Each session gets its own MCP server, keyed by `Mcp-Session-Id`. An origin gate requires `Origin` be loopback (or allow-listed) and rejects `Origin`-less requests. Widen for a tunnel/LAN origin with `cli: { mcp: { allowedOrigins: ['https://tunnel.example.com'] } }`.
36
36
37
37
### Hosted bridges
38
38
39
-
Both bridges forward the option to their side-car dev server, advertising the endpoint in `__connection.json`:
39
+
Both bridges forward it to their side-car dev server, advertising the endpoint in `__connection.json`:
`createMcpFetchHandler(ctx, options)` returns the endpoint as a `Request → Response` handler plus a `dispose()`for teardown — mount it on any fetch server.
51
+
`createMcpFetchHandler(ctx, options)` returns the endpoint as a `Request → Response` handler plus a `dispose()` — mount on any fetch server.
The `devframe` bin ships an MCP **connector** ([next-devtools-mcp](https://github.com/vercel/next-devtools-mcp)-style) that finds every running devframe. Configure it once:
66
+
The `devframe` bin ships an MCP **connector** ([next-devtools-mcp](https://github.com/vercel/next-devtools-mcp)-style) that finds every running devframe. Configure once:
67
67
68
68
```json
69
69
{
@@ -75,9 +75,9 @@ The `devframe` bin ships an MCP **connector** ([next-devtools-mcp](https://githu
75
75
76
76
Two gateway tools (`devframe:connect:*` ids — see [tool ids and wire names](/guide/agent-native#tool-ids-and-wire-names)):
77
77
78
-
-**`devframe_connect_list-instances`** — list running dev servers and their MCP tools; those without a route hint at `--mcp`.
78
+
-**`devframe_connect_list-instances`** — list running dev servers and their MCP tools.
79
79
-**`devframe_connect_call-tool`** — invoke one tool on an instance (`{ port, tool, args }`) over Streamable-HTTP.
80
80
81
-
Discovery reads the **instance registry**: every `createDevServer` writes `~/.devframe/instances/<pid>-<port>.json` on boot; the connector dials each with its loopback origin. In-process hosts register via `registerDevframeInstance` (`devframe/node`). `--port <n>` probes an explicit port; `DEVFRAME_INSTANCES_DIR` relocates the registry, `DEVFRAME_DISABLE_INSTANCE_REGISTRY=1` opts out.
81
+
Discovery reads the **instance registry**: every `createDevServer` writes `~/.devframe/instances/<pid>-<port>.json`, dialed with a loopback origin. In-process hosts register via `registerDevframeInstance` (`devframe/node`). `--port <n>` probes a port; `DEVFRAME_INSTANCES_DIR` relocates the registry, `DEVFRAME_DISABLE_INSTANCE_REGISTRY=1` opts out.
82
82
83
-
See [Agent-Native](/guide/agent-native) for the full API, safety model, and example.
83
+
See [Agent-Native](/guide/agent-native) for the API and safety model.
0 commit comments