@devframes/next 0.7.15 → 0.8.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.
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
@@ -125,6 +125,19 @@ interface CreateDevframeNextHostOptions {
125
125
  */
126
126
  connectionMeta?: ConnectionMeta;
127
127
  }
128
+ interface DevframeNextHostMcpOptions {
129
+ /** Name reported in the MCP handshake. Default: `'devframe (next)'`. */
130
+ serverName?: string;
131
+ /** Version reported in the MCP handshake. Default: `'0.0.0'`. */
132
+ serverVersion?: string;
133
+ /** Expose shared-state keys as MCP resources / `devframe:state:read`. Default: `true`. */
134
+ exposeSharedState?: boolean | ((key: string) => boolean);
135
+ /**
136
+ * Origin allow-list beyond the loopback default. `false` disables the
137
+ * origin gate entirely.
138
+ */
139
+ allowedOrigins?: readonly string[] | false;
140
+ }
128
141
  interface DevframeNextHost {
129
142
  /**
130
143
  * The {@link DevframeHost} to hand to `createHubContext` / `createHostContext`.
@@ -152,6 +165,20 @@ interface DevframeNextHost {
152
165
  * `503` so a racing client retries rather than caching a wrong endpoint.
153
166
  */
154
167
  setConnectionMeta: (meta: ConnectionMeta) => void;
168
+ /**
169
+ * Serve an MCP Streamable-HTTP endpoint at `path` **in-process** — on the
170
+ * Next app's own origin, through the same catch-all route as the SPAs (the
171
+ * `/_next/mcp` shape). Built on `createMcpFetchHandler` from
172
+ * `devframe/adapters/mcp` (imported lazily: `@modelcontextprotocol/server`
173
+ * stays an optional peer). Advertise the path in the connection meta
174
+ * (`mcp: { path }` — same origin, no port) and register the instance via
175
+ * `registerDevframeInstance` so `devframe connect` can discover it.
176
+ *
177
+ * @experimental
178
+ */
179
+ mountMcp: (ctx: DevframeNodeContext, path: string, options?: DevframeNextHostMcpOptions) => Promise<{
180
+ dispose: () => Promise<void>;
181
+ }>;
155
182
  }
156
183
  /**
157
184
  * Build a Node-runtime {@link DevframeHost} for a Next.js App Router app that
@@ -170,4 +197,4 @@ interface DevframeNextHost {
170
197
  */
171
198
  declare function createDevframeNextHost(options: CreateDevframeNextHostOptions): DevframeNextHost;
172
199
  //#endregion
173
- export { type CreateDevframeNextHandlerOptions, type CreateDevframeNextHostOptions, type DevframeNextConfig, type DevframeNextHandler, type DevframeNextHost, createDevframeNextHandler, createDevframeNextHost, withDevframe };
200
+ 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
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/next",
3
3
  "type": "module",
4
- "version": "0.7.15",
4
+ "version": "0.8.0",
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.15"
40
+ "devframe": "0.8.0"
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.15"
58
+ "devframe": "0.8.0"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "tsdown",