devframe 0.9.19 → 0.10.0

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.
Files changed (98) hide show
  1. package/dist/_shared-B2PZsp-J.mjs +191 -0
  2. package/dist/{_shared-BIUet_Jh.d.mts → _shared-Dy1UBMUN.d.mts} +13 -14
  3. package/dist/adapters/build.d.mts +3 -4
  4. package/dist/adapters/build.mjs +4 -5
  5. package/dist/adapters/cac.d.mts +3 -4
  6. package/dist/adapters/cac.mjs +3 -3
  7. package/dist/adapters/dev.d.mts +8 -8
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +8 -8
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +4 -123
  13. package/dist/adapters/mcp.mjs +1 -589
  14. package/dist/agentic-D4QQQUjE.d.mts +30 -0
  15. package/dist/cli/main.mjs +12 -260
  16. package/dist/client/index.d.mts +6 -6
  17. package/dist/client/index.mjs +3 -4
  18. package/dist/constants.d.mts +2 -1
  19. package/dist/constants.mjs +2 -1
  20. package/dist/{context-BA5FPz7K.d.mts → context-B4BKPuaa.d.mts} +1 -1
  21. package/dist/{context-BLXXjoBW.mjs → context-C141q8H4.mjs} +5 -5
  22. package/dist/{context-jXO5vzjH.mjs → context-CHpyLX8W.mjs} +1 -1
  23. package/dist/{context-BLHBDQcZ.d.mts → context-CTAxz9ec.d.mts} +108 -47
  24. package/dist/{dev-DbWecpjA.mjs → dev-DM1mIlgi.mjs} +16 -24
  25. package/dist/{diagnostics-DZA6KQ_Z.mjs → diagnostics-Cx4_VjlG.mjs} +11 -3
  26. package/dist/dist-Bw3EbMj4.mjs +305 -0
  27. package/dist/dist-CO98PBnQ.mjs +265 -0
  28. package/dist/{host-agent-C3MBpNCd.mjs → host-agent-ZSKgzMVu.mjs} +2 -7
  29. package/dist/import-runtime-module-BzlEQ9PI.mjs +24 -0
  30. package/dist/in-page-channel/index.d.mts +2 -7
  31. package/dist/in-page-channel/index.mjs +1 -4
  32. package/dist/index-Bia1vKjL.d.mts +218 -0
  33. package/dist/{index-r6NstVmM.d.mts → index-CcPSKbxb.d.mts} +2 -2
  34. package/dist/index-CeEtxDmK.d.mts +78 -0
  35. package/dist/{index-CiA6C705.d.mts → index-DuEm0sDH.d.mts} +1 -1
  36. package/dist/index.d.mts +4 -11
  37. package/dist/index.mjs +1 -10
  38. package/dist/{instance-registry-DCq762YJ.mjs → instance-registry-DtvYxc0Y.mjs} +1 -1
  39. package/dist/{instance-shell-C6Vg97lg.d.mts → instance-shell-DOZSxst6.d.mts} +31 -5
  40. package/dist/{instance-shell-370Oee9K.mjs → instance-shell-wC2sfEU_.mjs} +6 -6
  41. package/dist/interactive-auth-BCa_iamv.mjs +384 -0
  42. package/dist/internal/index.d.mts +66 -22
  43. package/dist/internal/index.mjs +143 -8
  44. package/dist/mrmime-40h5OOIp.mjs +448 -0
  45. package/dist/node/auth.d.mts +2 -2
  46. package/dist/node/hub-internals.d.mts +2 -2
  47. package/dist/node/hub-internals.mjs +2 -2
  48. package/dist/node/index.d.mts +2 -4
  49. package/dist/node/index.mjs +2 -2
  50. package/dist/{nostics-0sKe5HIj.d.mts → nostics-DWvukRwa.d.mts} +11 -2
  51. package/dist/{origin-DGDH8BI9.d.mts → origin-CY6BBHOy.d.mts} +14 -1
  52. package/dist/recipes/interactive-auth.d.mts +2 -2
  53. package/dist/recipes/interactive-auth.mjs +1 -231
  54. package/dist/{remote-assets-D0StJVLp.mjs → remote-assets-B9MeWmW6.mjs} +2 -2
  55. package/dist/rpc/client.d.mts +1 -1
  56. package/dist/rpc/client.mjs +1 -1
  57. package/dist/rpc/dump.d.mts +2 -1
  58. package/dist/rpc/index.d.mts +3 -2
  59. package/dist/rpc/server.d.mts +1 -1
  60. package/dist/rpc/server.mjs +1 -1
  61. package/dist/rpc/transports/sse-client.d.mts +1 -1
  62. package/dist/rpc/transports/sse-server.d.mts +3 -3
  63. package/dist/rpc/transports/ws-bun.d.mts +2 -2
  64. package/dist/rpc/transports/ws-client.d.mts +1 -1
  65. package/dist/rpc/transports/ws-deno.d.mts +2 -2
  66. package/dist/rpc/transports/ws-server.d.mts +2 -2
  67. package/dist/{rpc-core-CvkU23bQ.mjs → rpc-core-BXyMjbKG.mjs} +1 -1
  68. package/dist/{rpc-core-BlL-Ip8n.d.mts → rpc-core-rLrwFEcw.d.mts} +4 -4
  69. package/dist/{services-install-Ben4yh52.mjs → services-install-D5YUwFXW.mjs} +17 -1
  70. package/dist/{sse-client-BcbYwXdD.d.mts → sse-client-DNdscfu_.d.mts} +2 -2
  71. package/dist/{storage-B70AXK64.mjs → storage-CHD1IkqU.mjs} +1 -1
  72. package/dist/types/index.d.mts +4 -4
  73. package/dist/{types-D2vGd7-2.d.mts → types-BmDbfHCx.d.mts} +2 -3
  74. package/dist/utils/debounce.d.mts +50 -0
  75. package/dist/utils/debounce.mjs +88 -0
  76. package/dist/utils/events.d.mts +1 -1
  77. package/dist/utils/launch-editor.d.mts +8 -0
  78. package/dist/utils/launch-editor.mjs +36 -1
  79. package/dist/utils/nostics.d.mts +2 -2
  80. package/dist/utils/origin.d.mts +2 -2
  81. package/dist/utils/origin.mjs +21 -1
  82. package/dist/utils/remote-assets.mjs +1 -1
  83. package/dist/utils/serve-static.mjs +1 -1
  84. package/dist/utils/shared-state.d.mts +1 -1
  85. package/dist/utils/simple-schema.d.mts +3 -2
  86. package/dist/utils/streaming-channel.d.mts +1 -1
  87. package/dist/utils/url.d.mts +31 -0
  88. package/dist/utils/url.mjs +58 -0
  89. package/dist/{ws-client-CNpP6Ium.d.mts → ws-client-6Mrz6eC4.d.mts} +2 -2
  90. package/dist/{ws-server-BB8jhxeT.d.mts → ws-server-y2R76aSW.d.mts} +2 -2
  91. package/package.json +10 -11
  92. package/dist/_shared-U8D-xzrp.mjs +0 -115
  93. package/dist/agent-tool-name-DGzeuWcO.mjs +0 -31
  94. package/dist/client-assets-DNdhagGm.mjs +0 -16
  95. package/dist/nostics-DD6gsDZA.mjs +0 -108
  96. package/dist/recipes/common-rpc-functions.d.mts +0 -70
  97. package/dist/recipes/common-rpc-functions.mjs +0 -115
  98. package/dist/simple-schema-Bi40l-P6.mjs +0 -154
package/dist/cli/main.mjs CHANGED
@@ -1,118 +1,19 @@
1
- import { t as Diagnostic } from "../nostics-D0PvLZsn.mjs";
2
- import { t as diagnostics } from "../diagnostics-DZA6KQ_Z.mjs";
3
- import { n as listLiveDevframeInstances, r as probeDevframeOrigin } from "../instance-registry-DCq762YJ.mjs";
4
- import { t as toAgentToolName } from "../agent-tool-name-DGzeuWcO.mjs";
1
+ import { t as diagnostics } from "../diagnostics-Cx4_VjlG.mjs";
2
+ import { t as importRuntimeModule } from "../import-runtime-module-BzlEQ9PI.mjs";
5
3
  import process from "node:process";
6
- import { joinURL } from "ufo";
7
4
  import { cac } from "cac";
8
- //#region src/cli/connect.ts
9
- /**
10
- * Resolve the per-record bearer from the {@link ConnectServerOptions.authToken}
11
- * option. Exported for focused tests of the credential resolution.
12
- */
13
- function resolveAuthToken(authToken, record) {
14
- return typeof authToken === "function" ? authToken(record) : authToken;
15
- }
16
- /**
17
- * Build the request headers the connector sends to one instance's MCP route:
18
- * the instance's own (loopback) `origin` so the route's origin gate accepts
19
- * this native client, plus `Authorization: Bearer <token>` when a bearer is
20
- * configured. The bearer appears **only** here, never in the connection URL,
21
- * the registry records, or the indexed results. Exported for focused tests.
22
- */
23
- function buildInstanceRequestHeaders(url, token) {
24
- const headers = { origin: new URL(url).origin };
25
- if (token) headers.authorization = `Bearer ${token}`;
26
- return headers;
5
+ //#region src/cli/main.ts
6
+ /** Parse the repeatable `--port` flag value(s) from cac into numbers. */
7
+ function parsePortsFlag(value) {
8
+ return (Array.isArray(value) ? value : value === void 0 ? [] : [value]).map((v) => Number(v)).filter((n) => Number.isInteger(n) && n > 0 && n < 65536);
27
9
  }
28
- const INDEX_TOOL = toAgentToolName("devframe:connect:list-instances");
29
- const CALL_TOOL = toAgentToolName("devframe:connect:call-tool");
30
- const MCP_DISABLED_HINT = "This instance runs without an MCP route. Restart it with the --mcp flag (or set `cli.mcp: true` on its definition) to expose its tools, then list instances again.";
31
- const GATEWAY_TOOLS = [{
32
- name: INDEX_TOOL,
33
- title: "Discover running devframes",
34
- description: "Discover every running devframe dev server on this machine and list each one's MCP tools. Call this FIRST, before assuming which devtools are available; the result names the instance (id, project root, origin) and the port to pass to the call tool. Safe to call freely.",
35
- inputSchema: {
36
- type: "object",
37
- properties: {}
38
- },
39
- annotations: {
40
- readOnlyHint: true,
41
- destructiveHint: false
42
- }
43
- }, {
44
- name: CALL_TOOL,
45
- title: "Call a devframe tool",
46
- description: "Invoke one MCP tool on one running devframe instance discovered via the list-instances tool. Pass the instance's port, the tool name, and the tool's arguments object.",
47
- inputSchema: {
48
- type: "object",
49
- properties: {
50
- port: {
51
- type: "number",
52
- description: "The instance's port, from the list-instances tool."
53
- },
54
- tool: {
55
- type: "string",
56
- description: "Tool name, from the instance's tool list."
57
- },
58
- args: {
59
- type: "object",
60
- description: "Arguments object for the tool. Omit for zero-argument tools."
61
- }
62
- },
63
- required: ["port", "tool"],
64
- additionalProperties: false
65
- }
66
- }];
67
10
  /**
68
- * Start the devframe MCP connector on stdio: a thin discovery + proxy server
69
- * in the shape Vercel's next-devtools-mcp (https://github.com/vercel/next-devtools-mcp)
70
- * validated; credit is due there for the architecture this connector follows.
71
- * It exposes two gateway tools:
72
- * `devframe_connect_list-instances` (discover running devframe instances via
73
- * the instance registry and list each one's MCP tools) and
74
- * `devframe_connect_call-tool` (invoke one tool on one instance over its
75
- * Streamable-HTTP endpoint), and holds no domain knowledge of its own.
11
+ * Load the connector from the optional `@devframes/agentic` peer, mapping a
12
+ * failed load (typically: the peer is not installed) to a thrown `DF0046`.
76
13
  */
77
- async function startConnectServer(options = {}) {
78
- const sdk = await importSdk();
79
- const server = new sdk.Server({
80
- name: "devframe-connect",
81
- version: "0.0.0"
82
- }, { capabilities: { tools: {} } });
83
- server.setRequestHandler("tools/list", async () => ({ tools: GATEWAY_TOOLS }));
84
- server.setRequestHandler("tools/call", async (request) => {
85
- const { name, arguments: args } = request.params;
86
- try {
87
- if (name === INDEX_TOOL) return textResult(await index(sdk, options));
88
- if (name === CALL_TOOL) return textResult(await call(sdk, options, args ?? {}));
89
- return errorResult({
90
- message: `unknown tool "${name}"`,
91
- fix: `Call ${INDEX_TOOL} or ${CALL_TOOL}.`
92
- });
93
- } catch (error) {
94
- return errorResult(toErrorPayload(error));
95
- }
96
- });
97
- const transport = new sdk.StdioServerTransport();
98
- await server.connect(transport);
99
- return { stop: async () => {
100
- await server.close();
101
- } };
102
- }
103
- async function importSdk() {
14
+ async function importConnect() {
104
15
  try {
105
- const [serverMod, stdioMod, clientMod] = await Promise.all([
106
- import("@modelcontextprotocol/server"),
107
- import("@modelcontextprotocol/server/stdio"),
108
- import("@modelcontextprotocol/client")
109
- ]);
110
- return {
111
- Server: serverMod.Server,
112
- StdioServerTransport: stdioMod.StdioServerTransport,
113
- Client: clientMod.Client,
114
- StreamableHTTPClientTransport: clientMod.StreamableHTTPClientTransport
115
- };
16
+ return await importRuntimeModule("@devframes/agentic/connect");
116
17
  } catch (error) {
117
18
  const reason = error instanceof Error ? error.message : String(error);
118
19
  throw diagnostics.DF0046({
@@ -121,156 +22,6 @@ async function importSdk() {
121
22
  });
122
23
  }
123
24
  }
124
- /** Discover instances: registry (prune-on-read) + explicit port probes. */
125
- async function index(sdk, options) {
126
- const { live } = await listLiveDevframeInstances({
127
- instancesDir: options.instancesDir,
128
- timeoutMs: options.timeoutMs
129
- });
130
- const records = [...live];
131
- for (const port of options.ports ?? []) {
132
- if (records.some((r) => r.port === port)) continue;
133
- const probed = await probePort(port, options.timeoutMs);
134
- if (probed) records.push(probed);
135
- }
136
- const instances = await Promise.all(records.map(async (record) => {
137
- const { mcp, ...rest } = record;
138
- const entry = {
139
- ...rest,
140
- mcp: null
141
- };
142
- if (!mcp) {
143
- entry.hint = MCP_DISABLED_HINT;
144
- return entry;
145
- }
146
- const url = `${record.origin}${mcp.path}`;
147
- try {
148
- entry.mcp = {
149
- url,
150
- tools: await listInstanceTools(sdk, url, resolveAuthToken(options.authToken, record))
151
- };
152
- } catch (error) {
153
- entry.mcp = {
154
- url,
155
- error: error instanceof Error ? error.message : String(error)
156
- };
157
- }
158
- return entry;
159
- }));
160
- return {
161
- instances,
162
- ...instances.length === 0 ? { hint: "No running devframe instances found. Start a devframe dev server (with --mcp for tools), or pass --port <n> to devframe connect if the instance predates the registry." } : {}
163
- };
164
- }
165
- /**
166
- * Probe an explicit port for a devframe serving `__connection.json` at `/`,
167
- * reusing the registry's origin-candidate probe (a `localhost`-bound server
168
- * may listen on either address family).
169
- */
170
- async function probePort(port, timeoutMs) {
171
- const probed = await probeDevframeOrigin(`http://localhost:${port}`, "/", timeoutMs);
172
- if (!probed) return null;
173
- const mcpPath = probed.meta.mcp ? joinURL("/", probed.meta.mcp.path) : null;
174
- return {
175
- pid: -1,
176
- port,
177
- origin: probed.origin,
178
- basePath: "/",
179
- id: `port-${port}`,
180
- rootDir: "",
181
- mcp: mcpPath ? { path: mcpPath } : null,
182
- startedAt: 0
183
- };
184
- }
185
- async function listInstanceTools(sdk, url, token) {
186
- return withInstanceClient(sdk, url, token, async (client) => {
187
- return (await client.listTools()).tools.map((tool) => ({
188
- name: tool.name,
189
- description: tool.description
190
- }));
191
- });
192
- }
193
- async function call(sdk, options, args) {
194
- if (typeof args.port !== "number" || typeof args.tool !== "string") throw diagnostics.DF0049();
195
- const { live } = await listLiveDevframeInstances({
196
- instancesDir: options.instancesDir,
197
- timeoutMs: options.timeoutMs
198
- });
199
- const record = live.find((r) => r.port === args.port) ?? await probePort(args.port, options.timeoutMs);
200
- if (!record) throw diagnostics.DF0050({ port: args.port });
201
- if (!record.mcp) throw diagnostics.DF0051({ port: args.port });
202
- return withInstanceClient(sdk, `${record.origin}${record.mcp.path}`, resolveAuthToken(options.authToken, record), async (client) => {
203
- const result = await client.callTool({
204
- name: args.tool,
205
- arguments: args.args ?? {}
206
- });
207
- return {
208
- instance: {
209
- id: record.id,
210
- port: record.port
211
- },
212
- tool: args.tool,
213
- isError: result.isError ?? false,
214
- content: result.content,
215
- ...result.structuredContent ? { structuredContent: result.structuredContent } : {}
216
- };
217
- });
218
- }
219
- async function withInstanceClient(sdk, url, token, fn) {
220
- const transport = new sdk.StreamableHTTPClientTransport(new URL(url), { requestInit: { headers: buildInstanceRequestHeaders(url, token) } });
221
- const client = new sdk.Client({
222
- name: "devframe-connect",
223
- version: "0.0.0"
224
- }, { versionNegotiation: { mode: "auto" } });
225
- await client.connect(transport);
226
- try {
227
- return await fn(client);
228
- } finally {
229
- await client.close().catch(() => {});
230
- }
231
- }
232
- function textResult(value) {
233
- return { content: [{
234
- type: "text",
235
- text: JSON.stringify(value, null, 2)
236
- }] };
237
- }
238
- /**
239
- * Project a thrown value into the connector's structured error payload. A
240
- * nostics `Diagnostic` carries its code, `fix`, and docs URL across so the
241
- * calling agent gets the actionable next step.
242
- */
243
- function toErrorPayload(error) {
244
- if (error instanceof Diagnostic) return {
245
- code: error.code,
246
- message: error.message,
247
- ...error.fix ? { fix: error.fix } : {},
248
- ...error.docs ? { docs: error.docs } : {}
249
- };
250
- return {
251
- message: error instanceof Error ? error.message : String(error),
252
- ...error && typeof error === "object" && "fix" in error && typeof error.fix === "string" ? { fix: error.fix } : {}
253
- };
254
- }
255
- function errorResult(error) {
256
- return {
257
- isError: true,
258
- content: [{
259
- type: "text",
260
- text: JSON.stringify({ error }, null, 2)
261
- }]
262
- };
263
- }
264
- /** Parse the repeatable `--port` flag value(s) from cac into numbers. */
265
- function parsePortsFlag(value) {
266
- return (Array.isArray(value) ? value : value === void 0 ? [] : [value]).map((v) => Number(v)).filter((n) => Number.isInteger(n) && n > 0 && n < 65536);
267
- }
268
- /** Keep the connector process alive until the stdio transport closes it. */
269
- function keepAlive() {
270
- process.stdin.resume();
271
- }
272
- //#endregion
273
- //#region src/cli/main.ts
274
25
  /**
275
26
  * The `devframe` bin is the framework's own CLI, distinct from the per-app
276
27
  * CLI shells authors build with `createCac(definition)`. It hosts the
@@ -279,6 +30,7 @@ function keepAlive() {
279
30
  async function runDevframeCli(argv = process.argv) {
280
31
  const cli = cac("devframe");
281
32
  cli.command("connect", "Run the devframe MCP connector on stdio (discovers running devframe dev servers and proxies their tools)").option("--port <port>", "Probe an explicit port besides the instance registry (repeatable)").option("--instances-dir <dir>", "Override the instance registry directory (default: ~/.devframe/instances, or $DEVFRAME_INSTANCES_DIR)").option("--timeout <ms>", "Probe timeout per instance in milliseconds", { default: 1e3 }).action(async (options) => {
33
+ const { startConnectServer } = await importConnect();
282
34
  await startConnectServer({
283
35
  ports: parsePortsFlag(options.port),
284
36
  instancesDir: options.instancesDir,
@@ -290,7 +42,7 @@ async function runDevframeCli(argv = process.argv) {
290
42
  */
291
43
  authToken: process.env.DEVFRAME_MCP_AUTH_TOKEN
292
44
  });
293
- keepAlive();
45
+ process.stdin.resume();
294
46
  });
295
47
  cli.help();
296
48
  cli.parse(argv, { run: false });
@@ -1,9 +1,9 @@
1
- import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-CiA6C705.mjs";
2
- import { E as RpcFunctionsCollector, _ as RpcFunctionDefinition } from "../types-D2vGd7-2.mjs";
3
- import { Q as DevframeServiceMeta, Vt as EventEmitter, b as StreamSink, ct as DevframeSettings, d as RpcSharedStateHost, et as DevframeServiceScopeOf, gt as SettingsForNamespace, ht as ScopedSharedStates, it as DevframeServicesState, k as SharedState, mt as ScopedServerFunctions, pt as ScopedRpcFn, t as ConnectionMeta, u as RpcSharedStateGetOptions, vt as DevframeRpcClientFunctions, y as StreamReader, yt as DevframeRpcServerFunctions } from "../context-BLHBDQcZ.mjs";
4
- import { t as SseRpcChannelOptions } from "../sse-client-BcbYwXdD.mjs";
5
- import { t as WsRpcChannelOptions } from "../ws-client-CNpP6Ium.mjs";
6
- import { BirpcOptions, BirpcReturn } from "birpc";
1
+ import { i as BirpcReturn, r as BirpcOptions } from "../index-Bia1vKjL.mjs";
2
+ import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-DuEm0sDH.mjs";
3
+ import { h as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-BmDbfHCx.mjs";
4
+ import { Ct as DevframeRpcClientFunctions, Kt as EventEmitter, at as DevframeServiceScopeOf, b as StreamSink, bt as ScopedSharedStates, d as RpcSharedStateHost, k as SharedState, lt as DevframeServicesState, pt as DevframeSettings, rt as DevframeServiceMeta, t as ConnectionMeta, u as RpcSharedStateGetOptions, vt as ScopedRpcFn, wt as DevframeRpcServerFunctions, xt as SettingsForNamespace, y as StreamReader, yt as ScopedServerFunctions } from "../context-CTAxz9ec.mjs";
5
+ import { t as SseRpcChannelOptions } from "../sse-client-DNdscfu_.mjs";
6
+ import { t as WsRpcChannelOptions } from "../ws-client-6Mrz6eC4.mjs";
7
7
  //#region src/client/connection.d.ts
8
8
  export interface DevframeConnection {
9
9
  /** Server-advertised transport and serialization metadata. */
@@ -1,12 +1,11 @@
1
- import { n as DEVFRAME_EVENTS, t as defineDiagnostics } from "../nostics-DD6gsDZA.mjs";
1
+ import { n as defineDiagnostics, r as DEVFRAME_EVENTS, t as createBirpc } from "../dist-Bw3EbMj4.mjs";
2
2
  import { t as hash } from "../hash-DdPnc4k3.mjs";
3
3
  import { createEventEmitter } from "../utils/events.mjs";
4
+ import { withBase, withProtocol } from "../utils/url.mjs";
4
5
  import { t as createSharedState } from "../shared-state-eQVYHNqA.mjs";
5
6
  import { i as structuredCloneStringify, n as structuredCloneParse, t as structuredCloneDeserialize } from "../structured-clone-CgtQ61SA.mjs";
6
7
  import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
7
8
  import { toAgentToolName } from "../utils/agent-tool-name.mjs";
8
- import { withBase, withProtocol } from "ufo";
9
- import { createBirpc } from "birpc";
10
9
  //#region src/constants.ts
11
10
  /** Devframe runtime routes and static output conventions. */
12
11
  const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
@@ -1670,7 +1669,7 @@ function createScopedClientContext(rpc, namespace) {
1670
1669
  };
1671
1670
  }
1672
1671
  //#endregion
1673
- //#region src/adapters/mcp/to-json-schema.ts
1672
+ //#region src/agent/to-json-schema.ts
1674
1673
  const FALLBACK_OBJECT_SCHEMA = Object.freeze({
1675
1674
  type: "object",
1676
1675
  additionalProperties: true
@@ -113,7 +113,8 @@ export declare const DEVFRAME_SSE_SESSION_HEADER = "x-birpc-session";
113
113
  * Route the Streamable-HTTP MCP endpoint is bound to, relative to a
114
114
  * devframe's base path. Sits next to `__connection.json` and the WS route
115
115
  * so an MCP client reaches it on the same origin the SPA loaded from; the
116
- * dev server shares one port for HTTP, WS, and MCP. Opt-in via `cli.mcp`.
116
+ * dev server shares one port for HTTP, WS, and MCP. Opt-in via the host's
117
+ * `mcp` setting.
117
118
  */
118
119
  export declare const DEVFRAME_MCP_ROUTE = "__mcp";
119
120
  export declare const DEVFRAME_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
@@ -36,7 +36,8 @@ const DEVFRAME_SSE_SESSION_HEADER = "x-birpc-session";
36
36
  * Route the Streamable-HTTP MCP endpoint is bound to, relative to a
37
37
  * devframe's base path. Sits next to `__connection.json` and the WS route
38
38
  * so an MCP client reaches it on the same origin the SPA loaded from; the
39
- * dev server shares one port for HTTP, WS, and MCP. Opt-in via `cli.mcp`.
39
+ * dev server shares one port for HTTP, WS, and MCP. Opt-in via the host's
40
+ * `mcp` setting.
40
41
  */
41
42
  const DEVFRAME_MCP_ROUTE = "__mcp";
42
43
  const DEVFRAME_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
@@ -1,4 +1,4 @@
1
- import { k as SharedState, o as DevframeNodeContext } from "./context-BLHBDQcZ.mjs";
1
+ import { k as SharedState, o as DevframeNodeContext } from "./context-CTAxz9ec.mjs";
2
2
  //#region src/node/hub-internals/context.d.ts
3
3
  interface InternalAnonymousAuthStorage {
4
4
  trusted: Record<string, {
@@ -4,11 +4,11 @@ import { RpcFunctionsCollectorBase } from "./rpc/index.mjs";
4
4
  import { defineRpcFunction } from "./index.mjs";
5
5
  import { t as DEVFRAME_EVENTS } from "./events-BV4Dj59a.mjs";
6
6
  import { DEVFRAME_SERVICES_STATE_KEY } from "./constants.mjs";
7
- import { t as diagnostics$1 } from "./diagnostics-DZA6KQ_Z.mjs";
8
- import { i as createEventEmitter, t as DevframeAgentHost } from "./host-agent-C3MBpNCd.mjs";
9
- import { n as createDebug, t as resolveStaticAssetsSource } from "./remote-assets-D0StJVLp.mjs";
10
- import { i as satisfiesVersionRange, n as expandResolveFrom, r as importServicePackage, t as deepMergeOptionSets } from "./services-install-Ben4yh52.mjs";
11
- import { t as createStorage } from "./storage-B70AXK64.mjs";
7
+ import { t as diagnostics$1 } from "./diagnostics-Cx4_VjlG.mjs";
8
+ import { r as createEventEmitter, t as DevframeAgentHost } from "./host-agent-ZSKgzMVu.mjs";
9
+ import { n as createDebug, t as resolveStaticAssetsSource } from "./remote-assets-B9MeWmW6.mjs";
10
+ import { a as satisfiesVersionRange, n as expandResolveFrom, r as importServicePackage, t as deepMergeOptionSets } from "./services-install-D5YUwFXW.mjs";
11
+ import { t as createStorage } from "./storage-CHD1IkqU.mjs";
12
12
  import { join } from "pathe";
13
13
  import { createSharedState } from "devframe/utils/shared-state";
14
14
  import process from "node:process";
@@ -1,5 +1,5 @@
1
1
  import { n as randomToken } from "./crypto-token-TVbGGFuj.mjs";
2
- import { t as createStorage } from "./storage-B70AXK64.mjs";
2
+ import { t as createStorage } from "./storage-CHD1IkqU.mjs";
3
3
  import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "./revoke-cqztiCX4.mjs";
4
4
  import { join } from "pathe";
5
5
  //#region src/node/hub-internals/context.ts
@@ -1,10 +1,10 @@
1
- import { d as RpcFunctionsCollectorBase } from "./index-CiA6C705.mjs";
2
- import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-D2vGd7-2.mjs";
1
+ import { i as BirpcReturn } from "./index-Bia1vKjL.mjs";
2
+ import { d as RpcFunctionsCollectorBase } from "./index-DuEm0sDH.mjs";
3
+ import { t as StandardSchemaV1 } from "./index-CeEtxDmK.mjs";
4
+ import { g as RpcFunctionDefinitionAny, h as RpcFunctionDefinition } from "./types-BmDbfHCx.mjs";
3
5
  import { n as DevframeRpcConnection, t as DevframeNodeRpcSessionMeta } from "./session-r6PDixP6.mjs";
4
6
  import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-eBvSKZMS.mjs";
5
- import { m as defineDiagnostics } from "./nostics-0sKe5HIj.mjs";
6
- import { BirpcReturn } from "birpc";
7
- import { StandardSchemaV1 } from "@standard-schema/spec";
7
+ import { h as defineDiagnostics } from "./nostics-DWvukRwa.mjs";
8
8
  import { CAC } from "cac";
9
9
  //#region src/types/events.d.ts
10
10
  interface EventsMap {
@@ -1204,17 +1204,20 @@ interface DevframeSseOptions {
1204
1204
  type McpAuthorization = string | ((request: Request) => boolean | Promise<boolean>) | false;
1205
1205
  /**
1206
1206
  * The route-based MCP setting accepted everywhere a host mounts a devframe
1207
- * (`cli.mcp`, `initDevframe` / `initHub` / `createDevServer` options, the
1208
- * framework kits):
1207
+ * (`initDevframe` / `initHub` / `createDevServer` options, `createCac` /
1208
+ * `--mcp`, the framework kits):
1209
1209
  *
1210
1210
  * - `'auto'`, the default: mount the route when the devframe exposes an
1211
1211
  * agent surface (an `agent`-flagged RPC function, or a tool / resource /
1212
- * provider registered on `ctx.agent`). An empty agent surface mounts
1213
- * nothing and loads no MCP code.
1214
- * - `true`: always mount at the default `__mcp` route.
1215
- * - `false`: never mount.
1216
- * - {@link McpRouteOptions}: always mount, with a custom route path, origin
1217
- * allow-list, or {@link McpAuthorization} identity check.
1212
+ * provider registered on `ctx.agent`) AND the optional `@devframes/agentic`
1213
+ * peer (the MCP adapter and SDK) is installed. An empty agent surface
1214
+ * mounts nothing and loads no MCP code; a non-empty one without the peer
1215
+ * warns once (DF0078) and mounts nothing.
1216
+ * - `true`: always mount at the default `__mcp` route; a missing
1217
+ * `@devframes/agentic` throws DF0079.
1218
+ * - `false`: never mount, and never probe or warn.
1219
+ * - {@link McpRouteOptions}: always mount (like `true`), with a custom route
1220
+ * path, origin allow-list, or {@link McpAuthorization} identity check.
1218
1221
  *
1219
1222
  * A mounted route trusts same-machine callers by default (the loopback
1220
1223
  * origin gate), exactly like `mcp: true`.
@@ -1298,36 +1301,6 @@ interface DevframeCliOptions {
1298
1301
  * @default true
1299
1302
  */
1300
1303
  auth?: boolean | DevframeAuthHandler;
1301
- /**
1302
- * Expose a route-based MCP server alongside the standalone dev server,
1303
- * speaking the MCP Streamable-HTTP transport at `/__mcp` (relative to the
1304
- * base path). It surfaces the same `ctx.agent` tools + shared-state
1305
- * resources as the stdio `mcp` command, but against the live server.
1306
- *
1307
- * Defaults to `'auto'`: the route mounts once the devframe exposes an
1308
- * agent surface (an `agent`-flagged RPC, a registered tool / resource).
1309
- * See {@link McpSetting} for the full contract, and
1310
- * {@link McpRouteOptions} for the route path, origin allow-list, and
1311
- * {@link McpAuthorization} identity check.
1312
- *
1313
- * The `--mcp` / `--no-mcp` CLI flags override this per run. Whether to expose
1314
- * MCP is a hosting decision, so programmatic hosts pass it to
1315
- * `initDevframe` / `initHub` / `createDevServer` instead.
1316
- *
1317
- * @deprecated Whether to expose MCP is a hosting decision, not a capability
1318
- * of the tool. Pass `mcp` to `createCac` (or the programmatic host) instead.
1319
- * This field is still read as a fallback, and will be removed in a future
1320
- * release.
1321
- */
1322
- mcp?: McpSetting;
1323
- /**
1324
- * Author's SPA dist, served as the devframe's UI.
1325
- *
1326
- * @deprecated Moved to the top-level {@link DevframeDefinition.clientAssets}.
1327
- * Set `clientAssets` on the definition instead. This field is still read as a
1328
- * fallback when `clientAssets` is unset, so existing definitions keep working.
1329
- */
1330
- distDir?: StaticAssetsSource;
1331
1304
  /**
1332
1305
  * How the browser reaches the RPC WebSocket. Defaults to sharing the HTTP
1333
1306
  * port on the `__ws` route. See {@link DevframeWsOptions} for the
@@ -1545,8 +1518,7 @@ interface DevframeDefinition {
1545
1518
  * ship inside the node package.
1546
1519
  *
1547
1520
  * Consumed by every adapter that serves the UI (`dev`, `build`, `vite`,
1548
- * `next`, and the hub install path). When unset, the deprecated
1549
- * {@link DevframeCliOptions.distDir} is read as a fallback.
1521
+ * `next`, and the hub install path).
1550
1522
  */
1551
1523
  clientAssets?: StaticAssetsSource;
1552
1524
  /** RPC-level configuration for this devframe (see {@link DevframeRpcOptions}). */
@@ -1583,6 +1555,95 @@ type DevframeSnapshotRpcEntry = string | {
1583
1555
  inputs: DevframeSnapshotRpcInputs;
1584
1556
  };
1585
1557
  //#endregion
1558
+ //#region src/types/mcp.d.ts
1559
+ /**
1560
+ * The MCP adapter surface, typed here so `devframe` (which probes for and
1561
+ * lazily loads `@devframes/agentic`) and `@devframes/agentic/mcp` (which
1562
+ * implements it) share one contract without a type-level dependency cycle.
1563
+ * None of these shapes reference the MCP SDK: the SDK is an implementation
1564
+ * detail of `@devframes/agentic`, freely swappable behind this surface.
1565
+ * The h3-bound `mountMcpHttp` shapes live in `node/agentic.ts` (exported via
1566
+ * `devframe/internal`) instead: `devframe/types` must stay lib-neutral, and
1567
+ * h3's declarations are not.
1568
+ */
1569
+ interface CreateMcpServerOptions {
1570
+ /**
1571
+ * Transport to use. `createMcpServer` itself runs `'stdio'` (a standalone
1572
+ * process with its own host context); the Streamable-HTTP transport is
1573
+ * served route-based by the dev server instead; see `mountMcpHttp` and
1574
+ * the `mcp` option on `createDevServer` / `createCac`'s `--mcp` flag.
1575
+ */
1576
+ transport?: 'stdio';
1577
+ /**
1578
+ * Expose shared-state keys as MCP resources.
1579
+ * - `true` (default): every key the host publishes
1580
+ * - `false`: none
1581
+ * - `(key) => boolean`: filter
1582
+ */
1583
+ exposeSharedState?: boolean | ((key: string) => boolean);
1584
+ /** Override the name reported in the MCP handshake. */
1585
+ serverName?: string;
1586
+ /** Override the version reported in the MCP handshake. Defaults to `definition.version ?? '0.0.0'`. */
1587
+ serverVersion?: string;
1588
+ /** Called once the transport is connected. */
1589
+ onReady?: (info: {
1590
+ transport: 'stdio';
1591
+ }) => void;
1592
+ }
1593
+ interface McpServerHandle {
1594
+ stop: () => Promise<void>;
1595
+ }
1596
+ interface CreateMcpFetchHandlerOptions {
1597
+ /** Name reported in the MCP handshake. */
1598
+ serverName: string;
1599
+ /** Version reported in the MCP handshake. */
1600
+ serverVersion: string;
1601
+ /** Expose shared-state keys as MCP resources; see {@link CreateMcpServerOptions.exposeSharedState}. */
1602
+ exposeSharedState: boolean | ((key: string) => boolean);
1603
+ /**
1604
+ * Optional identity check, layered on top of the origin gate and checked
1605
+ * **after** it: a bearer token string (matched in constant time against
1606
+ * `Authorization: Bearer <token>`), a `(request) => boolean` callback, or
1607
+ * `false` (the default) for origin-only, trusting same-machine callers. A
1608
+ * callback governs identity only and cannot relax the origin gate. See
1609
+ * {@link McpAuthorization}.
1610
+ */
1611
+ authorization?: McpAuthorization;
1612
+ /**
1613
+ * Origin allow-list beyond the loopback default. `false` disables the
1614
+ * origin gate entirely. Default: loopback-only.
1615
+ *
1616
+ * Unlike the WS transport, the MCP route does **not** allow `Origin`-less
1617
+ * requests: a route-based endpoint is reachable by any local process, so a
1618
+ * request must carry an `Origin` that passes the gate. Native clients
1619
+ * (e.g. `devframe connect`) send their loopback origin explicitly.
1620
+ */
1621
+ allowedOrigins?: readonly string[] | false;
1622
+ }
1623
+ /** Connection facts a host knows about a request beyond the `Request` itself. */
1624
+ interface McpConnectionInfo {
1625
+ /**
1626
+ * The connecting peer's remote address (a node socket's `remoteAddress`),
1627
+ * used to prove a same-machine caller when the endpoint relies on the
1628
+ * loopback origin default with no identity check. A host that can resolve a
1629
+ * trustworthy peer address (the h3/node mount) supplies it; when it's
1630
+ * omitted the origin gate stays the only locality signal.
1631
+ */
1632
+ remoteAddress?: string;
1633
+ }
1634
+ interface McpFetchHandler {
1635
+ /**
1636
+ * WHATWG-`fetch` handler for the MCP endpoint. Hand every method
1637
+ * (POST/GET/DELETE) on the endpoint's path to it; routing by path is the
1638
+ * host's job. Pass {@link McpConnectionInfo} when the host can resolve the
1639
+ * peer address so the default trust boundary can enforce same-machine
1640
+ * locality.
1641
+ */
1642
+ fetch: (request: Request, connection?: McpConnectionInfo) => Promise<Response>;
1643
+ /** Tear down the handler (aborts in-flight exchanges, drops the change bridge). */
1644
+ dispose: () => Promise<void>;
1645
+ }
1646
+ //#endregion
1586
1647
  //#region src/utils/shared-state.d.ts
1587
1648
  type ImmutablePrimitive = undefined | null | boolean | string | number | Function;
1588
1649
  type Immutable<T> = T extends ImmutablePrimitive ? T : T extends Array<infer U> ? ImmutableArray<U> : T extends Map<infer K, infer V> ? ImmutableMap<K, V> : T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>;
@@ -2089,7 +2150,7 @@ interface ConnectionMeta {
2089
2150
  sse?: string | ConnectionMetaSse;
2090
2151
  /**
2091
2152
  * Present when the dev server exposes a route-based MCP endpoint
2092
- * (`cli.mcp`). Advertises the MCP Streamable-HTTP route so in-browser
2153
+ * (the host's `mcp` setting). Advertises the MCP Streamable-HTTP route so in-browser
2093
2154
  * tooling (e.g. an MCP inspector) can discover it without guessing the
2094
2155
  * path. `path` is relative to `__connection.json`'s location, like the
2095
2156
  * WebSocket `path`. `port` is set when the endpoint lives on a side-car
@@ -2184,4 +2245,4 @@ interface ConnectionMeta {
2184
2245
  */
2185
2246
  interface DevframeConnectionConfigsRegistry {}
2186
2247
  //#endregion
2187
- export { DevframeServiceOf as $, SharedStateEvents as A, AgentHandle as At, DevframeSetupInfo as B, DevframeAgentHostEvents as Bt, createStreamSink as C, DevframeDiagnosticsHost as Ct, ImmutableObject as D, InferCliFlags as Dt, ImmutableMap as E, CliFlagsSchema as Et, DevframeDefinition as F, AgentTool as Ft, McpAuthorization as G, DevframeSnapshotRpcInputs as H, EventUnsubscribe as Ht, DevframeDeploymentKind as I, AgentToolInput as It, DevframeServiceDefinition as J, McpRouteOptions as K, DevframeDockDefaults as L, AgentToolProvider as Lt, SharedStatePatch as M, AgentResource as Mt, createSharedState as N, AgentResourceContent as Nt, ImmutableSet as O, defineCliFlags as Ot, DevframeCliOptions as P, AgentResourceInput as Pt, DevframeServiceMeta as Q, DevframeDuplicationStrategy as R, AgentToolProviderHandle as Rt, createStreamReader as S, DevframeStorageScope as St, ImmutableArray as T, DevframeAuthHandler as Tt, DevframeSseOptions as U, EventsMap as Ut, DevframeSnapshotRpcEntry as V, EventEmitter as Vt, DevframeWsOptions as W, DevframeServiceId as X, DevframeServiceDescriptor as Y, DevframeServiceInput as Z, CreateStreamSinkOptions as _, DevframeViewHost as _t, DevframeConnectionConfigsRegistry as a, DevframeScopedNodeContext as at, StreamSink as b, DevframeRpcSharedStates as bt, RpcBroadcastOptions as c, DevframeSettings as ct, RpcSharedStateHost as d, ScopedBroadcastOptions as dt, DevframeServiceScopeOf as et, RpcStreamingChannel as f, ScopedClientFunctions as ft, CreateStreamReaderOptions as g, SettingsForNamespace as gt, BufferedChunk as h, ScopedSharedStates as ht, DevframeCapabilities as i, DevframeServicesState as it, SharedStateOptions as j, AgentManifest as jt, SharedState as k, parseCliFlags as kt, RpcFunctionsHost as l, DevframeSettingsRegistry as lt, RpcStreamingHost as m, ScopedServerFunctions as mt, ConnectionMetaSse as n, DevframeServicesRegistry as nt, DevframeNodeContext as o, DevframeScopedNodeRpc as ot, RpcStreamingChannelOptions as p, ScopedRpcFn as pt, McpSetting as q, ConnectionMetaWebsocket as r, DevframeServicesScopeRegistry as rt, DevframeNodeRpcSession as s, DevframeScopedStreamingHost as st, ConnectionMeta as t, DevframeServicesHost as tt, RpcSharedStateGetOptions as u, DevframeSettingsStore as ut, StreamErrorPayload as v, DevframeRpcClientFunctions as vt, Immutable as w, DevframeDiagnosticsLogger as wt, StreamSinkEvents as x, DevframeHost as xt, StreamReader as y, DevframeRpcServerFunctions as yt, DevframeRpcOptions as z, DevframeAgentHost as zt };
2248
+ export { DevframeServiceDefinition as $, SharedStateEvents as A, DevframeAuthHandler as At, DevframeDefinition as B, AgentTool as Bt, createStreamSink as C, DevframeRpcClientFunctions as Ct, ImmutableObject as D, DevframeStorageScope as Dt, ImmutableMap as E, DevframeHost as Et, CreateMcpServerOptions as F, AgentHandle as Ft, DevframeSetupInfo as G, DevframeAgentHostEvents as Gt, DevframeDockDefaults as H, AgentToolProvider as Ht, McpConnectionInfo as I, AgentManifest as It, DevframeSseOptions as J, EventsMap as Jt, DevframeSnapshotRpcEntry as K, EventEmitter as Kt, McpFetchHandler as L, AgentResource as Lt, SharedStatePatch as M, InferCliFlags as Mt, createSharedState as N, defineCliFlags as Nt, ImmutableSet as O, DevframeDiagnosticsHost as Ot, CreateMcpFetchHandlerOptions as P, parseCliFlags as Pt, McpSetting as Q, McpServerHandle as R, AgentResourceContent as Rt, createStreamReader as S, DevframeViewHost as St, ImmutableArray as T, DevframeRpcSharedStates as Tt, DevframeDuplicationStrategy as U, AgentToolProviderHandle as Ut, DevframeDeploymentKind as V, AgentToolInput as Vt, DevframeRpcOptions as W, DevframeAgentHost as Wt, McpAuthorization as X, DevframeWsOptions as Y, McpRouteOptions as Z, CreateStreamSinkOptions as _, ScopedClientFunctions as _t, DevframeConnectionConfigsRegistry as a, DevframeServiceScopeOf as at, StreamSink as b, ScopedSharedStates as bt, RpcBroadcastOptions as c, DevframeServicesScopeRegistry as ct, RpcSharedStateHost as d, DevframeScopedNodeRpc as dt, DevframeServiceDescriptor as et, RpcStreamingChannel as f, DevframeScopedStreamingHost as ft, CreateStreamReaderOptions as g, ScopedBroadcastOptions as gt, BufferedChunk as h, DevframeSettingsStore as ht, DevframeCapabilities as i, DevframeServiceOf as it, SharedStateOptions as j, CliFlagsSchema as jt, SharedState as k, DevframeDiagnosticsLogger as kt, RpcFunctionsHost as l, DevframeServicesState as lt, RpcStreamingHost as m, DevframeSettingsRegistry as mt, ConnectionMetaSse as n, DevframeServiceInput as nt, DevframeNodeContext as o, DevframeServicesHost as ot, RpcStreamingChannelOptions as p, DevframeSettings as pt, DevframeSnapshotRpcInputs as q, EventUnsubscribe as qt, ConnectionMetaWebsocket as r, DevframeServiceMeta as rt, DevframeNodeRpcSession as s, DevframeServicesRegistry as st, ConnectionMeta as t, DevframeServiceId as tt, RpcSharedStateGetOptions as u, DevframeScopedNodeContext as ut, StreamErrorPayload as v, ScopedRpcFn as vt, Immutable as w, DevframeRpcServerFunctions as wt, StreamSinkEvents as x, SettingsForNamespace as xt, StreamReader as y, ScopedServerFunctions as yt, DevframeCliOptions as z, AgentResourceInput as zt };