@devframes/next 0.7.16 → 0.8.1

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/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CreateDevServerOptions } from "devframe/adapters/dev";
2
- import { ConnectionMeta, DevframeDefinition, DevframeHost, DevframeStorageScope } from "devframe/types";
2
+ import { ConnectionMeta, DevframeDefinition, DevframeHost, DevframeNodeContext, DevframeStorageScope } from "devframe/types";
3
3
  //#region src/config.d.ts
4
4
  /**
5
5
  * Minimal shape of the bits of `next.config` this helper reads/writes, so the
@@ -45,9 +45,11 @@ interface CreateDevframeNextHandlerOptions {
45
45
  /** Flag bag forwarded to `def.setup(ctx, { flags })`. */
46
46
  flags?: Record<string, unknown>;
47
47
  /**
48
- * Whether the side-car runs its own auth gate. Defaults to `false`: this is a
49
- * hosted adapter and the Next app owns authentication. Pass `true` for
50
- * devframe's interactive gate or a handler for a custom scheme.
48
+ * Whether the side-car runs its own auth gate. **Gates by default** (defers
49
+ * to `createDevServer` — devframe's interactive OTP unless the definition's
50
+ * `cli.auth` opts out), so the side-car socket isn't silently reachable by
51
+ * anything that can open it. Pass `false` to opt out for a single-user
52
+ * localhost host, or a handler for a custom scheme.
51
53
  */
52
54
  auth?: CreateDevServerOptions['auth'];
53
55
  /** Origin the Next app is reachable at, for docks needing an absolute URL. */
@@ -125,6 +127,20 @@ interface CreateDevframeNextHostOptions {
125
127
  */
126
128
  connectionMeta?: ConnectionMeta;
127
129
  }
130
+ interface DevframeNextHostMcpOptions {
131
+ /** Name reported in the MCP handshake. Default: `'devframe (next)'`. */
132
+ serverName?: string;
133
+ /** Version reported in the MCP handshake. Default: `'0.0.0'`. */
134
+ serverVersion?: string;
135
+ /** Expose shared-state keys as MCP resources / `devframe:state:read`. Default: `true`. */
136
+ exposeSharedState?: boolean | ((key: string) => boolean);
137
+ /**
138
+ * Origin allow-list beyond the loopback default. `false` disables the
139
+ * origin gate entirely. Note the MCP route rejects `Origin`-less requests
140
+ * (see `createMcpFetchHandler`).
141
+ */
142
+ allowedOrigins?: readonly string[] | false;
143
+ }
128
144
  interface DevframeNextHost {
129
145
  /**
130
146
  * The {@link DevframeHost} to hand to `createHubContext` / `createHostContext`.
@@ -152,6 +168,20 @@ interface DevframeNextHost {
152
168
  * `503` so a racing client retries rather than caching a wrong endpoint.
153
169
  */
154
170
  setConnectionMeta: (meta: ConnectionMeta) => void;
171
+ /**
172
+ * Serve an MCP Streamable-HTTP endpoint at `path` **in-process** — on the
173
+ * Next app's own origin, through the same catch-all route as the SPAs (the
174
+ * `/_next/mcp` shape). Built on `createMcpFetchHandler` from
175
+ * `devframe/adapters/mcp` (imported lazily: `@modelcontextprotocol/server`
176
+ * stays an optional peer). Advertise the path in the connection meta
177
+ * (`mcp: { path }` — same origin, no port) and register the instance via
178
+ * `registerDevframeInstance` so `devframe connect` can discover it.
179
+ *
180
+ * @experimental
181
+ */
182
+ mountMcp: (ctx: DevframeNodeContext, path: string, options?: DevframeNextHostMcpOptions) => Promise<{
183
+ dispose: () => Promise<void>;
184
+ }>;
155
185
  }
156
186
  /**
157
187
  * Build a Node-runtime {@link DevframeHost} for a Next.js App Router app that
@@ -170,4 +200,4 @@ interface DevframeNextHost {
170
200
  */
171
201
  declare function createDevframeNextHost(options: CreateDevframeNextHostOptions): DevframeNextHost;
172
202
  //#endregion
173
- export { type CreateDevframeNextHandlerOptions, type CreateDevframeNextHostOptions, type DevframeNextConfig, type DevframeNextHandler, type DevframeNextHost, createDevframeNextHandler, createDevframeNextHost, withDevframe };
203
+ export { type CreateDevframeNextHandlerOptions, type CreateDevframeNextHostOptions, type DevframeNextConfig, type DevframeNextHandler, type DevframeNextHost, type DevframeNextHostMcpOptions, createDevframeNextHandler, createDevframeNextHost, withDevframe };
package/dist/index.mjs CHANGED
@@ -55,6 +55,7 @@ function stripTrailingSlash(base) {
55
55
  function createDevframeNextHost(options) {
56
56
  const app = new H3();
57
57
  const metaBases = /* @__PURE__ */ new Set();
58
+ const mcpMounts = /* @__PURE__ */ new Map();
58
59
  let connectionMeta = options.connectionMeta;
59
60
  const host = {
60
61
  mountStatic(base, distDir) {
@@ -70,6 +71,8 @@ function createDevframeNextHost(options) {
70
71
  };
71
72
  async function fetch(request) {
72
73
  const { pathname } = new URL(request.url);
74
+ const mcp = mcpMounts.get(stripTrailingSlash(pathname));
75
+ if (mcp) return mcp.fetch(request);
73
76
  if (pathname.endsWith(META_SUFFIX) && metaBases.has(pathname.slice(0, -META_SUFFIX.length))) {
74
77
  if (!connectionMeta) return new Response(null, { status: 503 });
75
78
  return Response.json(connectionMeta);
@@ -83,6 +86,21 @@ function createDevframeNextHost(options) {
83
86
  fetch,
84
87
  setConnectionMeta(meta) {
85
88
  connectionMeta = meta;
89
+ },
90
+ async mountMcp(ctx, path, mcpOptions = {}) {
91
+ const { createMcpFetchHandler } = await import("devframe/adapters/mcp");
92
+ const handler = createMcpFetchHandler(ctx, {
93
+ serverName: mcpOptions.serverName ?? "devframe (next)",
94
+ serverVersion: mcpOptions.serverVersion ?? "0.0.0",
95
+ exposeSharedState: mcpOptions.exposeSharedState ?? true,
96
+ allowedOrigins: mcpOptions.allowedOrigins
97
+ });
98
+ const key = stripTrailingSlash(path);
99
+ mcpMounts.set(key, handler);
100
+ return { dispose: async () => {
101
+ mcpMounts.delete(key);
102
+ await handler.dispose();
103
+ } };
86
104
  }
87
105
  };
88
106
  }
@@ -141,7 +159,7 @@ function createDevframeNextHandler(def, options = {}) {
141
159
  port,
142
160
  flags: options.flags,
143
161
  openBrowser: false,
144
- auth: options.auth ?? false,
162
+ auth: options.auth,
145
163
  mcp: options.mcp
146
164
  });
147
165
  const mcpMeta = resolveMcpConnectionMeta(def, options.mcp, port);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/next",
3
3
  "type": "module",
4
- "version": "0.7.16",
4
+ "version": "0.8.1",
5
5
  "description": "Next.js host integration for Devframe — serve mounted devframe SPAs and connection meta from an App Router route (experimental)",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "peerDependencies": {
38
38
  "next": "^14.0.0 || ^15.0.0 || ^16.0.0",
39
39
  "react": "^18.0.0 || ^19.0.0",
40
- "devframe": "0.7.16"
40
+ "devframe": "0.8.1"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "next": {
@@ -55,7 +55,7 @@
55
55
  "@types/react": "^19.2.17",
56
56
  "react": "^19.2.8",
57
57
  "tsdown": "^0.22.14",
58
- "devframe": "0.7.16"
58
+ "devframe": "0.8.1"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "tsdown",