@modern-js/plugin-mcp-apps 0.0.0-canary-20260924035651
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/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/cjs/bff-runtime.cjs +92 -0
- package/dist/cjs/bff.cjs +56 -0
- package/dist/cjs/cli.cjs +154 -0
- package/dist/cjs/server.cjs +96 -0
- package/dist/esm-node/bff-runtime.mjs +54 -0
- package/dist/esm-node/bff.mjs +18 -0
- package/dist/esm-node/cli.mjs +104 -0
- package/dist/esm-node/server.mjs +46 -0
- package/dist/esm-node/z~0.mjs +2 -0
- package/dist/types/bff-runtime.d.ts +4 -0
- package/dist/types/bff.d.ts +23 -0
- package/dist/types/cli.d.ts +5 -0
- package/dist/types/options.d.ts +21 -0
- package/dist/types/server.d.ts +5 -0
- package/dist/types/shared.d.ts +8 -0
- package/package.json +79 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-present Modern.js
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Modern.js MCP Apps plugin (experimental)
|
|
2
|
+
|
|
3
|
+
场景化接入与调试见 [MCP Apps 使用指南](../../../docs/guides/mcp-apps-usage.md),包含独立 Hono、可选 MF 和 ngrok。
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
7
|
+
import { bffPlugin } from '@modern-js/plugin-bff';
|
|
8
|
+
import { mcpAppsPlugin } from '@modern-js/plugin-mcp-apps';
|
|
9
|
+
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
bff: { prefix: '/mcp' },
|
|
12
|
+
plugins: [appTools(), bffPlugin(), mcpAppsPlugin()],
|
|
13
|
+
});
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The plugin compiles MCP definitions and handlers and binds artifacts during BFF
|
|
17
|
+
initialization. HTTP routing belongs to BFF; add the following API entry and install `@modern-js/plugin-bff` and
|
|
18
|
+
`@modern-js/mcp-apps` in dependencies.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// api/lambda/index.ts
|
|
22
|
+
import { mcpApps } from '@modern-js/plugin-mcp-apps/bff';
|
|
23
|
+
|
|
24
|
+
export const { POST, GET, DELETE, PUT, PATCH, OPTIONS } = mcpApps();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For an existing BFF application, keep its prefix and put the route in
|
|
28
|
+
`api/lambda/mcp.ts` (for example `/api/mcp`). Do not register BFF twice.
|
|
29
|
+
Pass `serverInfo` or `onError` to `mcpApps()`. The integration binds the artifact
|
|
30
|
+
using the BFF runtime context; route depth, custom output directories and CJS/ESM
|
|
31
|
+
API modules do not require application-level path resolution. Export the returned
|
|
32
|
+
functions directly so BFF can recognize them; apply authentication in BFF middleware.
|
|
33
|
+
For manually hosted artifacts, the lower-level `@modern-js/mcp-apps/bff` adapter
|
|
34
|
+
remains available with explicit root/entry options.
|
|
35
|
+
|
|
36
|
+
## Options
|
|
37
|
+
|
|
38
|
+
| Option | Default | Meaning |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `config` | `mcp_apps.ts` | Trusted definition path, relative to project root |
|
|
41
|
+
| `tsconfig` | esbuild's nearest tsconfig | Config/handler compilation settings |
|
|
42
|
+
| `alias` | None | Explicit static server import aliases; tsconfig paths also work |
|
|
43
|
+
|
|
44
|
+
`modern dev` bundles the definition and local handlers into the framework internal MCP directory (normally `node_modules/.modern-js/mcp-apps/`). Config, handler and imported source changes trigger debounced
|
|
45
|
+
recompilation. A new module generation is published atomically after successful
|
|
46
|
+
compilation; invalid changes log an error and retain the last working generation.
|
|
47
|
+
Development uses a development React renderer; production uses a production
|
|
48
|
+
renderer, so dev-compiled remote JSX runs against a matching React dispatcher.
|
|
49
|
+
The watcher is disposed on CLI exit/restart. Artifact revisions cancel obsolete
|
|
50
|
+
requests when a new generation is loaded. BFF owns API runtime reloads.
|
|
51
|
+
|
|
52
|
+
`modern build` emits `dist/mcp-apps/`, including compiled handler dependencies,
|
|
53
|
+
the definition entry, and packaged resource HTML. `modern serve` uses those files,
|
|
54
|
+
not source modules. `modern deploy` includes the same artifacts in `.output/`.
|
|
55
|
+
Both CJS and ESM application configurations are supported by the package exports;
|
|
56
|
+
the generated MCP server modules are ESM on Node 20+.
|
|
57
|
+
|
|
58
|
+
Configuration is evaluated at runtime so remote URLs can depend on environment
|
|
59
|
+
variables. Local handler module references must be unchanged between build and
|
|
60
|
+
runtime; changing that set requires rebuilding. The compiler bundles imported
|
|
61
|
+
local code/JSON; separately read files, native addons and other runtime assets
|
|
62
|
+
still need application deployment handling.
|
|
63
|
+
|
|
64
|
+
## UI and server separation
|
|
65
|
+
|
|
66
|
+
UI continues to use existing MF/Vmok exposes and manifests. The integrated endpoint uses BFF and does not require a UI entry or React rendering. The `mcp-server`
|
|
67
|
+
template uses an `api/` directory with no `src/` to select Modern.js API-only mode.
|
|
68
|
+
For UI integration, use the `mcp-apps` template or an existing federation setup.
|
|
69
|
+
|
|
70
|
+
The underlying core is also usable without app-tools: see
|
|
71
|
+
`examples/mcp-apps-modern` and the [Hono adapter documentation](../../toolkit/mcp-apps/README.md#default-local-view-and-hono). For a local integrated app,
|
|
72
|
+
run `pnpm --filter @examples/mcp-apps-modern dev` in this repository after building
|
|
73
|
+
the core and this plugin.
|
|
74
|
+
|
|
75
|
+
## HTTP behavior
|
|
76
|
+
|
|
77
|
+
The MCP endpoint is a BFF API route. Register authentication/origin policy before
|
|
78
|
+
BFF dispatch. The adapter rebuilds the HTTP request from the already parsed BFF
|
|
79
|
+
input and returns the SDK Response directly, including notification status 202.
|
|
80
|
+
Handler `context.context` is the request's Hono Context, allowing access to
|
|
81
|
+
middleware-provided identity; contexts are isolated between concurrent requests.
|
|
82
|
+
The transport remains stateless and POST-only; GET/DELETE return 405.
|
|
83
|
+
|
|
84
|
+
No server plugin `onClose` hook is assumed. Per-request transports are released
|
|
85
|
+
by the core, request disconnects abort handlers, and compiler watchers belong to
|
|
86
|
+
the CLI lifecycle. Custom `server/modern.server.ts` middleware and ordinary pages
|
|
87
|
+
remain independent of MCP registration.
|
|
88
|
+
|
|
89
|
+
## Tests
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
pnpm --filter @modern-js/mcp-apps build
|
|
93
|
+
pnpm --filter @modern-js/plugin-mcp-apps build
|
|
94
|
+
pnpm --filter @modern-js/plugin-mcp-apps test
|
|
95
|
+
pnpm --filter tests test:framework integration/mcp-apps/tests/index.test.ts --retry=0
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Local views and Hono
|
|
99
|
+
|
|
100
|
+
The default template uses local `view.module` components, compiled into standalone
|
|
101
|
+
HTML in `dist/mcp-apps/`. MF is selected explicitly with `--template mcp-apps --mf`.
|
|
102
|
+
The BFF runtime uses `@modern-js/mcp-apps/bff` internally; standalone Hono uses
|
|
103
|
+
`@modern-js/mcp-apps/hono`. Both share the artifact loader and SDK transport. UI source changes participate in MCP development recompilation.
|
|
104
|
+
|
|
105
|
+
The legacy `server-plugin` export remains available for explicit Web Server
|
|
106
|
+
integration, but `mcpAppsPlugin()` no longer installs it or registers HTTP routes.
|
|
107
|
+
|
|
108
|
+
Include `ts-node` (`^10.9.2`) in devDependencies for BFF TypeScript loading and
|
|
109
|
+
API module hot reload on Node 20+. For ESM projects, use `"type": "module"` and
|
|
110
|
+
TypeScript `module: "esnext"`, `moduleResolution: "bundler"` together.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
default: ()=>mcpBffRuntime
|
|
32
|
+
});
|
|
33
|
+
const bff_namespaceObject = require("@modern-js/mcp-apps/bff");
|
|
34
|
+
const server_core_namespaceObject = require("@modern-js/server-core");
|
|
35
|
+
const MCP_BFF_ENDPOINT = Symbol.for('@modern-js/plugin-mcp-apps/bff');
|
|
36
|
+
function mcpBffRuntime(options) {
|
|
37
|
+
return {
|
|
38
|
+
name: '@modern-js/plugin-mcp-apps/bff-runtime',
|
|
39
|
+
pre: [
|
|
40
|
+
'@modern-js/plugin-bff'
|
|
41
|
+
],
|
|
42
|
+
required: [
|
|
43
|
+
'@modern-js/plugin-bff'
|
|
44
|
+
],
|
|
45
|
+
setup (api) {
|
|
46
|
+
const bind = ()=>{
|
|
47
|
+
const ctx = api.getServerContext();
|
|
48
|
+
const root = options.development ? ctx.appDirectory : ctx.distDirectory;
|
|
49
|
+
if (!root) throw new Error('MCP Apps requires a BFF application directory');
|
|
50
|
+
const handlers = new Map();
|
|
51
|
+
const infos = ctx.apiHandlerInfos ?? [];
|
|
52
|
+
const apiHandlerInfos = infos.map((info)=>{
|
|
53
|
+
const endpointOptions = Reflect.get(info.handler, MCP_BFF_ENDPOINT);
|
|
54
|
+
if (!endpointOptions) return info;
|
|
55
|
+
let handler = handlers.get(info.handler);
|
|
56
|
+
if (!handler) {
|
|
57
|
+
const handle = (0, bff_namespaceObject.createMcpBffHandler)({
|
|
58
|
+
...endpointOptions,
|
|
59
|
+
root,
|
|
60
|
+
development: options.development,
|
|
61
|
+
entry: options.development ? options.devEntry : options.entry
|
|
62
|
+
});
|
|
63
|
+
handler = (input)=>handle(input, (0, server_core_namespaceObject.useHonoContext)());
|
|
64
|
+
handlers.set(info.handler, handler);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
...info,
|
|
68
|
+
handler
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
api.updateServerContext({
|
|
72
|
+
...ctx,
|
|
73
|
+
apiHandlerInfos
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
api.prepareApiServer((input, next)=>{
|
|
77
|
+
bind();
|
|
78
|
+
next(input);
|
|
79
|
+
});
|
|
80
|
+
api.onReset(({ event })=>{
|
|
81
|
+
if ('file-change' === event.type) bind();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
exports["default"] = __webpack_exports__["default"];
|
|
87
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
88
|
+
"default"
|
|
89
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
90
|
+
Object.defineProperty(exports, '__esModule', {
|
|
91
|
+
value: true
|
|
92
|
+
});
|
package/dist/cjs/bff.cjs
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
mcpApps: ()=>mcpApps
|
|
32
|
+
});
|
|
33
|
+
const MCP_BFF_ENDPOINT = Symbol.for('@modern-js/plugin-mcp-apps/bff');
|
|
34
|
+
function mcpApps(options = {}) {
|
|
35
|
+
const endpoint = (_input)=>{
|
|
36
|
+
throw new Error('MCP endpoint is not initialized. Enable bffPlugin() and mcpAppsPlugin(), and export the handlers returned by mcpApps() from an API route.');
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(endpoint, MCP_BFF_ENDPOINT, {
|
|
39
|
+
value: options
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
POST: endpoint,
|
|
43
|
+
GET: endpoint,
|
|
44
|
+
DELETE: endpoint,
|
|
45
|
+
PUT: endpoint,
|
|
46
|
+
PATCH: endpoint,
|
|
47
|
+
OPTIONS: endpoint
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.mcpApps = __webpack_exports__.mcpApps;
|
|
51
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
52
|
+
"mcpApps"
|
|
53
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
54
|
+
Object.defineProperty(exports, '__esModule', {
|
|
55
|
+
value: true
|
|
56
|
+
});
|
package/dist/cjs/cli.cjs
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
14
|
+
var define = (defs, kind)=>{
|
|
15
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
[kind]: defs[key]
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
define(getters, "get");
|
|
21
|
+
define(values, "value");
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
(()=>{
|
|
28
|
+
__webpack_require__.r = (exports1)=>{
|
|
29
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
+
value: 'Module'
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
var __webpack_exports__ = {};
|
|
38
|
+
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
default: ()=>cli,
|
|
41
|
+
mcpAppsPlugin: ()=>mcpAppsPlugin
|
|
42
|
+
});
|
|
43
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
44
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
45
|
+
const build_namespaceObject = require("@modern-js/mcp-apps/build");
|
|
46
|
+
const utils_namespaceObject = require("@modern-js/utils");
|
|
47
|
+
const mcpAppsPlugin = (options = {})=>({
|
|
48
|
+
name: '@modern-js/plugin-mcp-apps',
|
|
49
|
+
required: [
|
|
50
|
+
'@modern-js/plugin-bff'
|
|
51
|
+
],
|
|
52
|
+
setup (api) {
|
|
53
|
+
let dependencies = new Set();
|
|
54
|
+
let watcher;
|
|
55
|
+
let timer;
|
|
56
|
+
let pending = Promise.resolve();
|
|
57
|
+
let closed = false;
|
|
58
|
+
let rebuildFailed = false;
|
|
59
|
+
const paths = ()=>{
|
|
60
|
+
const ctx = api.getAppContext();
|
|
61
|
+
return {
|
|
62
|
+
root: ctx.appDirectory,
|
|
63
|
+
source: external_node_path_default().resolve(ctx.appDirectory, options.config ?? 'mcp_apps.ts'),
|
|
64
|
+
devOut: external_node_path_default().join(ctx.internalDirectory, 'mcp-apps'),
|
|
65
|
+
prodOut: external_node_path_default().join(ctx.distDirectory, 'mcp-apps')
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const compile = async (dev)=>{
|
|
69
|
+
const { root, source, devOut, prodOut } = paths();
|
|
70
|
+
const result = await (0, build_namespaceObject.compileMcpApps)({
|
|
71
|
+
configPath: source,
|
|
72
|
+
outDir: dev ? devOut : prodOut,
|
|
73
|
+
tsconfig: options.tsconfig ? external_node_path_default().resolve(root, options.tsconfig) : void 0,
|
|
74
|
+
alias: options.alias,
|
|
75
|
+
development: dev
|
|
76
|
+
});
|
|
77
|
+
dependencies = new Set(result.dependencies.map((file)=>external_node_path_default().resolve(file)));
|
|
78
|
+
rebuildFailed = false;
|
|
79
|
+
if (dev) watcher?.add([
|
|
80
|
+
...dependencies
|
|
81
|
+
]);
|
|
82
|
+
if (dev) utils_namespaceObject.logger.info('[MCP Apps] definition and handlers ready');
|
|
83
|
+
};
|
|
84
|
+
const close = async ()=>{
|
|
85
|
+
closed = true;
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
await watcher?.close();
|
|
88
|
+
await pending;
|
|
89
|
+
};
|
|
90
|
+
api.onBeforeExit(close);
|
|
91
|
+
api.onBeforeRestart(close);
|
|
92
|
+
api.onBeforeDev(async ()=>{
|
|
93
|
+
closed = false;
|
|
94
|
+
await compile(true);
|
|
95
|
+
const { root, devOut, prodOut } = paths();
|
|
96
|
+
watcher = utils_namespaceObject.chokidar.watch([
|
|
97
|
+
root,
|
|
98
|
+
...dependencies
|
|
99
|
+
], {
|
|
100
|
+
ignoreInitial: true,
|
|
101
|
+
ignored: [
|
|
102
|
+
/[\\/]node_modules(?:[\\/]|$)/,
|
|
103
|
+
/[\\/]\.git(?:[\\/]|$)/,
|
|
104
|
+
external_node_path_default().join(root, '.output'),
|
|
105
|
+
devOut,
|
|
106
|
+
prodOut,
|
|
107
|
+
external_node_path_default().dirname(prodOut)
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
watcher.on('error', (error)=>utils_namespaceObject.logger.error('[MCP Apps] watcher failed', error));
|
|
111
|
+
watcher.on('all', (event, file)=>{
|
|
112
|
+
if (closed || !dependencies.has(external_node_path_default().resolve(file)) && !(rebuildFailed && 'add' === event)) return;
|
|
113
|
+
if (!dependencies.has(external_node_path_default().resolve(file)) && !/\.(?:[cm]?[jt]sx?|json)$/.test(file)) return;
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
timer = setTimeout(()=>{
|
|
116
|
+
pending = pending.then(async ()=>{
|
|
117
|
+
if (!closed) await compile(true);
|
|
118
|
+
}).catch((error)=>{
|
|
119
|
+
rebuildFailed = true;
|
|
120
|
+
utils_namespaceObject.logger.error('[MCP Apps] rebuild failed; keeping last successful build', error);
|
|
121
|
+
});
|
|
122
|
+
}, 60);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
api.onAfterBuild(()=>compile(false));
|
|
126
|
+
api._internalServerPlugins(({ plugins })=>{
|
|
127
|
+
const { root, devOut } = paths();
|
|
128
|
+
plugins.push({
|
|
129
|
+
name: '@modern-js/plugin-mcp-apps/bff-runtime',
|
|
130
|
+
options: {
|
|
131
|
+
development: [
|
|
132
|
+
'dev',
|
|
133
|
+
'start'
|
|
134
|
+
].includes(api.getAppContext().command),
|
|
135
|
+
devEntry: external_node_path_default().relative(root, external_node_path_default().join(devOut, 'mcp_apps.mjs')).split(external_node_path_default().sep).join('/'),
|
|
136
|
+
entry: 'mcp-apps/mcp_apps.mjs'
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
plugins
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
const cli = mcpAppsPlugin;
|
|
146
|
+
exports["default"] = __webpack_exports__["default"];
|
|
147
|
+
exports.mcpAppsPlugin = __webpack_exports__.mcpAppsPlugin;
|
|
148
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
149
|
+
"default",
|
|
150
|
+
"mcpAppsPlugin"
|
|
151
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
152
|
+
Object.defineProperty(exports, '__esModule', {
|
|
153
|
+
value: true
|
|
154
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
(()=>{
|
|
13
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
14
|
+
var define = (defs, kind)=>{
|
|
15
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
[kind]: defs[key]
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
define(getters, "get");
|
|
21
|
+
define(values, "value");
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
(()=>{
|
|
25
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
+
})();
|
|
27
|
+
(()=>{
|
|
28
|
+
__webpack_require__.r = (exports1)=>{
|
|
29
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
+
value: 'Module'
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
+
value: true
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
var __webpack_exports__ = {};
|
|
38
|
+
__webpack_require__.r(__webpack_exports__);
|
|
39
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
+
createArtifactHandler: ()=>server_namespaceObject.createArtifactHandler,
|
|
41
|
+
default: ()=>mcpAppsServerPlugin
|
|
42
|
+
});
|
|
43
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
44
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
45
|
+
const hono_namespaceObject = require("@modern-js/mcp-apps/hono");
|
|
46
|
+
const server_namespaceObject = require("@modern-js/mcp-apps/server");
|
|
47
|
+
function endpointPath(endpoint = '/mcp') {
|
|
48
|
+
if (!/^\/(?:[a-zA-Z0-9_.~-]+\/?)+$/.test(endpoint) || endpoint.endsWith('/') || endpoint.split('/').some((part)=>'.' === part || '..' === part)) throw new Error('MCP endpoint must be an exact absolute path without wildcards, parameters or trailing slash');
|
|
49
|
+
return endpoint;
|
|
50
|
+
}
|
|
51
|
+
function mcpAppsServerPlugin(options = {}) {
|
|
52
|
+
const endpoint = endpointPath(options.endpoint);
|
|
53
|
+
return {
|
|
54
|
+
name: '@modern-js/plugin-mcp-apps/server-plugin',
|
|
55
|
+
setup (api) {
|
|
56
|
+
let handler;
|
|
57
|
+
api.onPrepare(()=>{
|
|
58
|
+
const ctx = api.getServerContext();
|
|
59
|
+
const development = options.development ?? 'development' === process.env.NODE_ENV;
|
|
60
|
+
const base = development ? ctx.appDirectory : ctx.distDirectory;
|
|
61
|
+
if (!base) throw new Error('MCP Apps requires a server application/artifact directory');
|
|
62
|
+
const entry = external_node_path_default().resolve(base, development && options.devEntry ? options.devEntry : options.entry ?? 'mcp-apps/mcp_apps.mjs');
|
|
63
|
+
handler = (0, server_namespaceObject.createArtifactHandler)(entry, {
|
|
64
|
+
development,
|
|
65
|
+
serverInfo: options.serverInfo
|
|
66
|
+
});
|
|
67
|
+
ctx.middlewares.push({
|
|
68
|
+
name: 'mcp-apps',
|
|
69
|
+
path: endpoint,
|
|
70
|
+
method: 'all',
|
|
71
|
+
order: 'post',
|
|
72
|
+
before: [
|
|
73
|
+
'bind-bff',
|
|
74
|
+
'render'
|
|
75
|
+
],
|
|
76
|
+
handler: (0, hono_namespaceObject.mcpApps)({
|
|
77
|
+
handler,
|
|
78
|
+
endpoint
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
api.onReset(({ event })=>{
|
|
83
|
+
if ('file-change' === event.type) handler?.reset();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
exports.createArtifactHandler = __webpack_exports__.createArtifactHandler;
|
|
89
|
+
exports["default"] = __webpack_exports__["default"];
|
|
90
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
91
|
+
"createArtifactHandler",
|
|
92
|
+
"default"
|
|
93
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
94
|
+
Object.defineProperty(exports, '__esModule', {
|
|
95
|
+
value: true
|
|
96
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createMcpBffHandler } from "@modern-js/mcp-apps/bff";
|
|
2
|
+
import { useHonoContext } from "@modern-js/server-core";
|
|
3
|
+
import { MCP_BFF_ENDPOINT } from "./z~0.mjs";
|
|
4
|
+
function mcpBffRuntime(options) {
|
|
5
|
+
return {
|
|
6
|
+
name: '@modern-js/plugin-mcp-apps/bff-runtime',
|
|
7
|
+
pre: [
|
|
8
|
+
'@modern-js/plugin-bff'
|
|
9
|
+
],
|
|
10
|
+
required: [
|
|
11
|
+
'@modern-js/plugin-bff'
|
|
12
|
+
],
|
|
13
|
+
setup (api) {
|
|
14
|
+
const bind = ()=>{
|
|
15
|
+
const ctx = api.getServerContext();
|
|
16
|
+
const root = options.development ? ctx.appDirectory : ctx.distDirectory;
|
|
17
|
+
if (!root) throw new Error('MCP Apps requires a BFF application directory');
|
|
18
|
+
const handlers = new Map();
|
|
19
|
+
const infos = ctx.apiHandlerInfos ?? [];
|
|
20
|
+
const apiHandlerInfos = infos.map((info)=>{
|
|
21
|
+
const endpointOptions = Reflect.get(info.handler, MCP_BFF_ENDPOINT);
|
|
22
|
+
if (!endpointOptions) return info;
|
|
23
|
+
let handler = handlers.get(info.handler);
|
|
24
|
+
if (!handler) {
|
|
25
|
+
const handle = createMcpBffHandler({
|
|
26
|
+
...endpointOptions,
|
|
27
|
+
root,
|
|
28
|
+
development: options.development,
|
|
29
|
+
entry: options.development ? options.devEntry : options.entry
|
|
30
|
+
});
|
|
31
|
+
handler = (input)=>handle(input, useHonoContext());
|
|
32
|
+
handlers.set(info.handler, handler);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
...info,
|
|
36
|
+
handler
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
api.updateServerContext({
|
|
40
|
+
...ctx,
|
|
41
|
+
apiHandlerInfos
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
api.prepareApiServer((input, next)=>{
|
|
45
|
+
bind();
|
|
46
|
+
next(input);
|
|
47
|
+
});
|
|
48
|
+
api.onReset(({ event })=>{
|
|
49
|
+
if ('file-change' === event.type) bind();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export default mcpBffRuntime;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MCP_BFF_ENDPOINT } from "./z~0.mjs";
|
|
2
|
+
function mcpApps(options = {}) {
|
|
3
|
+
const endpoint = (_input)=>{
|
|
4
|
+
throw new Error('MCP endpoint is not initialized. Enable bffPlugin() and mcpAppsPlugin(), and export the handlers returned by mcpApps() from an API route.');
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(endpoint, MCP_BFF_ENDPOINT, {
|
|
7
|
+
value: options
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
POST: endpoint,
|
|
11
|
+
GET: endpoint,
|
|
12
|
+
DELETE: endpoint,
|
|
13
|
+
PUT: endpoint,
|
|
14
|
+
PATCH: endpoint,
|
|
15
|
+
OPTIONS: endpoint
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export { mcpApps };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import node_path from "node:path";
|
|
2
|
+
import { compileMcpApps } from "@modern-js/mcp-apps/build";
|
|
3
|
+
import { chokidar, logger } from "@modern-js/utils";
|
|
4
|
+
const mcpAppsPlugin = (options = {})=>({
|
|
5
|
+
name: '@modern-js/plugin-mcp-apps',
|
|
6
|
+
required: [
|
|
7
|
+
'@modern-js/plugin-bff'
|
|
8
|
+
],
|
|
9
|
+
setup (api) {
|
|
10
|
+
let dependencies = new Set();
|
|
11
|
+
let watcher;
|
|
12
|
+
let timer;
|
|
13
|
+
let pending = Promise.resolve();
|
|
14
|
+
let closed = false;
|
|
15
|
+
let rebuildFailed = false;
|
|
16
|
+
const paths = ()=>{
|
|
17
|
+
const ctx = api.getAppContext();
|
|
18
|
+
return {
|
|
19
|
+
root: ctx.appDirectory,
|
|
20
|
+
source: node_path.resolve(ctx.appDirectory, options.config ?? 'mcp_apps.ts'),
|
|
21
|
+
devOut: node_path.join(ctx.internalDirectory, 'mcp-apps'),
|
|
22
|
+
prodOut: node_path.join(ctx.distDirectory, 'mcp-apps')
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const compile = async (dev)=>{
|
|
26
|
+
const { root, source, devOut, prodOut } = paths();
|
|
27
|
+
const result = await compileMcpApps({
|
|
28
|
+
configPath: source,
|
|
29
|
+
outDir: dev ? devOut : prodOut,
|
|
30
|
+
tsconfig: options.tsconfig ? node_path.resolve(root, options.tsconfig) : void 0,
|
|
31
|
+
alias: options.alias,
|
|
32
|
+
development: dev
|
|
33
|
+
});
|
|
34
|
+
dependencies = new Set(result.dependencies.map((file)=>node_path.resolve(file)));
|
|
35
|
+
rebuildFailed = false;
|
|
36
|
+
if (dev) watcher?.add([
|
|
37
|
+
...dependencies
|
|
38
|
+
]);
|
|
39
|
+
if (dev) logger.info('[MCP Apps] definition and handlers ready');
|
|
40
|
+
};
|
|
41
|
+
const close = async ()=>{
|
|
42
|
+
closed = true;
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
await watcher?.close();
|
|
45
|
+
await pending;
|
|
46
|
+
};
|
|
47
|
+
api.onBeforeExit(close);
|
|
48
|
+
api.onBeforeRestart(close);
|
|
49
|
+
api.onBeforeDev(async ()=>{
|
|
50
|
+
closed = false;
|
|
51
|
+
await compile(true);
|
|
52
|
+
const { root, devOut, prodOut } = paths();
|
|
53
|
+
watcher = chokidar.watch([
|
|
54
|
+
root,
|
|
55
|
+
...dependencies
|
|
56
|
+
], {
|
|
57
|
+
ignoreInitial: true,
|
|
58
|
+
ignored: [
|
|
59
|
+
/[\\/]node_modules(?:[\\/]|$)/,
|
|
60
|
+
/[\\/]\.git(?:[\\/]|$)/,
|
|
61
|
+
node_path.join(root, '.output'),
|
|
62
|
+
devOut,
|
|
63
|
+
prodOut,
|
|
64
|
+
node_path.dirname(prodOut)
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
watcher.on('error', (error)=>logger.error('[MCP Apps] watcher failed', error));
|
|
68
|
+
watcher.on('all', (event, file)=>{
|
|
69
|
+
if (closed || !dependencies.has(node_path.resolve(file)) && !(rebuildFailed && 'add' === event)) return;
|
|
70
|
+
if (!dependencies.has(node_path.resolve(file)) && !/\.(?:[cm]?[jt]sx?|json)$/.test(file)) return;
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
timer = setTimeout(()=>{
|
|
73
|
+
pending = pending.then(async ()=>{
|
|
74
|
+
if (!closed) await compile(true);
|
|
75
|
+
}).catch((error)=>{
|
|
76
|
+
rebuildFailed = true;
|
|
77
|
+
logger.error('[MCP Apps] rebuild failed; keeping last successful build', error);
|
|
78
|
+
});
|
|
79
|
+
}, 60);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
api.onAfterBuild(()=>compile(false));
|
|
83
|
+
api._internalServerPlugins(({ plugins })=>{
|
|
84
|
+
const { root, devOut } = paths();
|
|
85
|
+
plugins.push({
|
|
86
|
+
name: '@modern-js/plugin-mcp-apps/bff-runtime',
|
|
87
|
+
options: {
|
|
88
|
+
development: [
|
|
89
|
+
'dev',
|
|
90
|
+
'start'
|
|
91
|
+
].includes(api.getAppContext().command),
|
|
92
|
+
devEntry: node_path.relative(root, node_path.join(devOut, 'mcp_apps.mjs')).split(node_path.sep).join('/'),
|
|
93
|
+
entry: 'mcp-apps/mcp_apps.mjs'
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
plugins
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const cli = mcpAppsPlugin;
|
|
103
|
+
export default cli;
|
|
104
|
+
export { mcpAppsPlugin };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import node_path from "node:path";
|
|
2
|
+
import { mcpApps } from "@modern-js/mcp-apps/hono";
|
|
3
|
+
import { createArtifactHandler } from "@modern-js/mcp-apps/server";
|
|
4
|
+
function endpointPath(endpoint = '/mcp') {
|
|
5
|
+
if (!/^\/(?:[a-zA-Z0-9_.~-]+\/?)+$/.test(endpoint) || endpoint.endsWith('/') || endpoint.split('/').some((part)=>'.' === part || '..' === part)) throw new Error('MCP endpoint must be an exact absolute path without wildcards, parameters or trailing slash');
|
|
6
|
+
return endpoint;
|
|
7
|
+
}
|
|
8
|
+
function mcpAppsServerPlugin(options = {}) {
|
|
9
|
+
const endpoint = endpointPath(options.endpoint);
|
|
10
|
+
return {
|
|
11
|
+
name: '@modern-js/plugin-mcp-apps/server-plugin',
|
|
12
|
+
setup (api) {
|
|
13
|
+
let handler;
|
|
14
|
+
api.onPrepare(()=>{
|
|
15
|
+
const ctx = api.getServerContext();
|
|
16
|
+
const development = options.development ?? 'development' === process.env.NODE_ENV;
|
|
17
|
+
const base = development ? ctx.appDirectory : ctx.distDirectory;
|
|
18
|
+
if (!base) throw new Error('MCP Apps requires a server application/artifact directory');
|
|
19
|
+
const entry = node_path.resolve(base, development && options.devEntry ? options.devEntry : options.entry ?? 'mcp-apps/mcp_apps.mjs');
|
|
20
|
+
handler = createArtifactHandler(entry, {
|
|
21
|
+
development,
|
|
22
|
+
serverInfo: options.serverInfo
|
|
23
|
+
});
|
|
24
|
+
ctx.middlewares.push({
|
|
25
|
+
name: 'mcp-apps',
|
|
26
|
+
path: endpoint,
|
|
27
|
+
method: 'all',
|
|
28
|
+
order: 'post',
|
|
29
|
+
before: [
|
|
30
|
+
'bind-bff',
|
|
31
|
+
'render'
|
|
32
|
+
],
|
|
33
|
+
handler: mcpApps({
|
|
34
|
+
handler,
|
|
35
|
+
endpoint
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
api.onReset(({ event })=>{
|
|
40
|
+
if ('file-change' === event.type) handler?.reset();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export default mcpAppsServerPlugin;
|
|
46
|
+
export { createArtifactHandler };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ServerPlugin } from '@modern-js/server-core';
|
|
2
|
+
import { type McpAppsBffRuntimeOptions } from './shared.js';
|
|
3
|
+
/** Bind artifacts to BFF-discovered functions. Never registers HTTP middleware. */
|
|
4
|
+
export default function mcpBffRuntime(options: McpAppsBffRuntimeOptions): ServerPlugin;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { McpBffOptions } from '@modern-js/mcp-apps/bff';
|
|
2
|
+
export type McpEndpointOptions = Pick<McpBffOptions, 'serverInfo' | 'onError'>;
|
|
3
|
+
/** Declare a BFF endpoint. Its compiled artifact is bound by the BFF lifecycle. */
|
|
4
|
+
export declare function mcpApps(options?: McpEndpointOptions): {
|
|
5
|
+
POST: (_input: {
|
|
6
|
+
data?: unknown;
|
|
7
|
+
}) => Promise<Response>;
|
|
8
|
+
GET: (_input: {
|
|
9
|
+
data?: unknown;
|
|
10
|
+
}) => Promise<Response>;
|
|
11
|
+
DELETE: (_input: {
|
|
12
|
+
data?: unknown;
|
|
13
|
+
}) => Promise<Response>;
|
|
14
|
+
PUT: (_input: {
|
|
15
|
+
data?: unknown;
|
|
16
|
+
}) => Promise<Response>;
|
|
17
|
+
PATCH: (_input: {
|
|
18
|
+
data?: unknown;
|
|
19
|
+
}) => Promise<Response>;
|
|
20
|
+
OPTIONS: (_input: {
|
|
21
|
+
data?: unknown;
|
|
22
|
+
}) => Promise<Response>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
2
|
+
import type { McpAppsPluginOptions } from './options.js';
|
|
3
|
+
export type { McpAppsPluginOptions } from './options.js';
|
|
4
|
+
export declare const mcpAppsPlugin: (options?: McpAppsPluginOptions) => CliPlugin<AppTools>;
|
|
5
|
+
export default mcpAppsPlugin;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface McpAppsPluginOptions {
|
|
2
|
+
/** Trusted application definition, relative to the project root. */
|
|
3
|
+
config?: string;
|
|
4
|
+
/** Optional tsconfig for config/handler compilation. */
|
|
5
|
+
tsconfig?: string;
|
|
6
|
+
/** Static server-only import aliases in addition to tsconfig paths. */
|
|
7
|
+
alias?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
export interface McpAppsServerOptions {
|
|
10
|
+
development?: boolean;
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/** Relative to appDirectory, only used in development. */
|
|
13
|
+
devEntry?: string;
|
|
14
|
+
/** Relative to distDirectory; serialized into the production launcher. */
|
|
15
|
+
entry?: string;
|
|
16
|
+
serverInfo?: {
|
|
17
|
+
name: string;
|
|
18
|
+
version: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function endpointPath(endpoint?: string): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ServerPlugin } from '@modern-js/server-core';
|
|
2
|
+
import { type McpAppsServerOptions } from './options.js';
|
|
3
|
+
export type { McpAppsServerOptions } from './options.js';
|
|
4
|
+
export { createArtifactHandler } from '@modern-js/mcp-apps/server';
|
|
5
|
+
export default function mcpAppsServerPlugin(options?: McpAppsServerOptions): ServerPlugin;
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modern-js/plugin-mcp-apps",
|
|
3
|
+
"version": "0.0.0-canary-20260924035651",
|
|
4
|
+
"description": "Modern.js integration for independently deployable MCP Apps",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/web-infra-dev/modern.js",
|
|
9
|
+
"directory": "packages/cli/plugin-mcp-apps"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/types/cli.d.ts",
|
|
22
|
+
"import": "./dist/esm-node/cli.mjs",
|
|
23
|
+
"require": "./dist/cjs/cli.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./server-plugin": {
|
|
26
|
+
"types": "./dist/types/server.d.ts",
|
|
27
|
+
"import": "./dist/esm-node/server.mjs",
|
|
28
|
+
"require": "./dist/cjs/server.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./bff": {
|
|
31
|
+
"types": "./dist/types/bff.d.ts",
|
|
32
|
+
"import": "./dist/esm-node/bff.mjs",
|
|
33
|
+
"require": "./dist/cjs/bff.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./bff-runtime": {
|
|
36
|
+
"types": "./dist/types/bff-runtime.d.ts",
|
|
37
|
+
"import": "./dist/esm-node/bff-runtime.mjs",
|
|
38
|
+
"require": "./dist/cjs/bff-runtime.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@modern-js/mcp-apps": "0.0.0-canary-20260924035651",
|
|
43
|
+
"@modern-js/utils": "0.0.0-canary-20260924035651",
|
|
44
|
+
"@modern-js/server-core": "0.0.0-canary-20260924035651"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@rslib/core": "1.0.1",
|
|
48
|
+
"@types/node": "^20",
|
|
49
|
+
"typescript": "^5",
|
|
50
|
+
"@scripts/rstest-config": "0.0.0-canary-20260924035651",
|
|
51
|
+
"@modern-js/app-tools": "0.0.0-canary-20260924035651"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public",
|
|
55
|
+
"registry": "https://registry.npmjs.org/"
|
|
56
|
+
},
|
|
57
|
+
"typesVersions": {
|
|
58
|
+
"*": {
|
|
59
|
+
".": [
|
|
60
|
+
"dist/types/cli.d.ts"
|
|
61
|
+
],
|
|
62
|
+
"server-plugin": [
|
|
63
|
+
"dist/types/server.d.ts"
|
|
64
|
+
],
|
|
65
|
+
"bff": [
|
|
66
|
+
"dist/types/bff.d.ts"
|
|
67
|
+
],
|
|
68
|
+
"bff-runtime": [
|
|
69
|
+
"dist/types/bff-runtime.d.ts"
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"types": "./dist/types/cli.d.ts",
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "rslib build",
|
|
76
|
+
"test": "rstest",
|
|
77
|
+
"typecheck": "tsc --noEmit"
|
|
78
|
+
}
|
|
79
|
+
}
|