@modern-js/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/NOTICE.md +12 -0
- package/README.md +227 -0
- package/THIRD-PARTY-LICENSE +21 -0
- package/dist/cjs/bff.cjs +889 -0
- package/dist/cjs/build.cjs +936 -0
- package/dist/cjs/config.cjs +42 -0
- package/dist/cjs/hono.cjs +874 -0
- package/dist/cjs/server.cjs +887 -0
- package/dist/esm/react.mjs +29 -0
- package/dist/esm-node/bff.mjs +42 -0
- package/dist/esm-node/build.mjs +142 -0
- package/dist/esm-node/config.mjs +4 -0
- package/dist/esm-node/hono.mjs +26 -0
- package/dist/esm-node/server.mjs +747 -0
- package/dist/runtime/mcp-app.dev.html +238 -0
- package/dist/runtime/mcp-app.html +238 -0
- package/dist/types/artifact.d.ts +11 -0
- package/dist/types/bff.d.ts +22 -0
- package/dist/types/build.d.ts +12 -0
- package/dist/types/config.d.ts +104 -0
- package/dist/types/definition.d.ts +214 -0
- package/dist/types/hono.d.ts +26 -0
- package/dist/types/loader.d.ts +5 -0
- package/dist/types/react.d.ts +108 -0
- package/dist/types/resources.d.ts +15 -0
- package/dist/types/runtime/components/error-boundary.d.ts +21 -0
- package/dist/types/runtime/components/remote-component-container.d.ts +65 -0
- package/dist/types/runtime/context/MFContext.d.ts +27 -0
- package/dist/types/runtime/context/MFProvider.d.ts +22 -0
- package/dist/types/runtime/hooks/useRemoteComponent.d.ts +53 -0
- package/dist/types/runtime/loaders/mf-loader.d.ts +37 -0
- package/dist/types/runtime/loaders/snapshot-loader.d.ts +19 -0
- package/dist/types/runtime/loaders/vmok-loader.d.ts +25 -0
- package/dist/types/runtime/loaders/vmok-manifest-plugin.d.ts +4 -0
- package/dist/types/runtime/mcp-app.d.ts +1 -0
- package/dist/types/runtime/styles/styles.d.ts +1 -0
- package/dist/types/runtime/utils/remote-types.d.ts +19 -0
- package/dist/types/runtime/utils/types.d.ts +10 -0
- package/dist/types/server.d.ts +30 -0
- package/package.json +117 -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/NOTICE.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
Portions of the configuration loading and browser runtime incorporate
|
|
4
|
+
MIT-licensed code:
|
|
5
|
+
|
|
6
|
+
Copyright (c) 2025 Web Infra
|
|
7
|
+
|
|
8
|
+
The corresponding license is reproduced verbatim in `THIRD-PARTY-LICENSE`.
|
|
9
|
+
Additional upstream author attribution: Frédéric Barthelet.
|
|
10
|
+
|
|
11
|
+
MCP SDK, MCP Apps SDK, React and Module Federation retain their upstream licenses
|
|
12
|
+
in the corresponding dependencies and bundled license notices.
|
package/README.md
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# MCP Apps core (experimental)
|
|
2
|
+
|
|
3
|
+
场景化接入与调试见 [MCP Apps 使用指南](../../../docs/guides/mcp-apps-usage.md),包含独立 Hono、可选 MF 和 ngrok。
|
|
4
|
+
|
|
5
|
+
Build and deploy MCP servers and remote React views independently using
|
|
6
|
+
`mcp_apps.ts`. The package provides configuration and handler loading,
|
|
7
|
+
result/view binding, local React HTML compilation, a Hono adapter, and optional MF/Vmok rendering.
|
|
8
|
+
|
|
9
|
+
## Default local view and Hono
|
|
10
|
+
|
|
11
|
+
A standard Modern.js app can declare a local card without MF:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
export default defineMcpApps({
|
|
15
|
+
remotes: [],
|
|
16
|
+
tools: [{ name: 'greet', handler: { module: './tools', exportName: 'greet' },
|
|
17
|
+
view: { module: './src/components/Greeting.tsx' } }],
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Compile it with `compileMcpApps({ configPath, outDir })` from the `/build` entry,
|
|
22
|
+
then mount the generated definition in any Hono application:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { Hono } from 'hono';
|
|
26
|
+
import { mcpApps } from '@modern-js/mcp-apps/hono';
|
|
27
|
+
const app = new Hono();
|
|
28
|
+
app.all('/mcp', mcpApps({ configPath: './dist/mcp-apps/mcp_apps.mjs' }));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For a standalone Node server, install `hono`, `@hono/node-server` and this package,
|
|
32
|
+
copy the application's entire `dist/mcp-apps/` directory (plus external handler
|
|
33
|
+
dependencies), then add a listener to the code above:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { serve } from '@hono/node-server';
|
|
37
|
+
serve({ fetch: app.fetch, hostname: '127.0.0.1', port: 8090 });
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Independent deployment is tested by `scripts/deployment-smoke.mjs` using a minimal
|
|
41
|
+
Hono fixture, with no separate example project required.
|
|
42
|
+
|
|
43
|
+
The adapter does not start a listener. Install authentication middleware first.
|
|
44
|
+
Handlers receive the Hono context as `context.context`. Integrated Modern.js
|
|
45
|
+
applications use `mcpApps()` from `@modern-js/plugin-mcp-apps/bff` in
|
|
46
|
+
`api/lambda/index.ts`; the BFF and Hono adapters share the artifact loader and SDK
|
|
47
|
+
transport. Copy the entire compiled artifact directory when
|
|
48
|
+
moving to a standalone server. Local cards register `ui://local/<tool>` resources
|
|
49
|
+
and bundle React, JS and CSS into their HTML, without MF or external scripts.
|
|
50
|
+
Local views currently support React components (not `renderMode: 'mount'`).
|
|
51
|
+
|
|
52
|
+
Local `view.html` may point to independently hosted HTTPS HTML; the server fetches
|
|
53
|
+
it for resource reads. `view.csp` declares any network origins used by that HTML.
|
|
54
|
+
Local JSX/TSX and CSS are bundled by esbuild; Modern.js-specific CSS preprocessors
|
|
55
|
+
or runtime features are not automatically inherited. Use MF for views requiring
|
|
56
|
+
the application's full MF build pipeline.
|
|
57
|
+
|
|
58
|
+
## Optional MF app definition
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// mcp_apps.ts — server-owned app definition
|
|
62
|
+
import { defineMcpApps } from '@modern-js/mcp-apps/config';
|
|
63
|
+
|
|
64
|
+
export default defineMcpApps({
|
|
65
|
+
remotes: [{
|
|
66
|
+
name: 'mcp_ui',
|
|
67
|
+
baseUrl: 'https://cdn.example.com/releases/1/mf-manifest.json',
|
|
68
|
+
manifestType: 'mf',
|
|
69
|
+
csp: {
|
|
70
|
+
resourceDomains: ['https://cdn.example.com'],
|
|
71
|
+
connectDomains: ['https://cdn.example.com'],
|
|
72
|
+
},
|
|
73
|
+
}],
|
|
74
|
+
tools: [{
|
|
75
|
+
name: 'greet',
|
|
76
|
+
remote: 'mcp_ui',
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: { name: { type: 'string' } },
|
|
80
|
+
required: ['name'],
|
|
81
|
+
},
|
|
82
|
+
annotations: { readOnlyHint: true },
|
|
83
|
+
handler: { module: './tools', exportName: 'greet', runtime: 'local' },
|
|
84
|
+
view: { module: './Greeting', runtime: 'browser' },
|
|
85
|
+
}],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// tools.ts — deployed with the server, never bundled into the UI
|
|
91
|
+
import type { RemoteToolHandler } from '@modern-js/mcp-apps/config';
|
|
92
|
+
|
|
93
|
+
export const greet: RemoteToolHandler = input => {
|
|
94
|
+
const { name } = input as { name: string };
|
|
95
|
+
const message = `Hello, ${name}!`;
|
|
96
|
+
return {
|
|
97
|
+
content: [{ type: 'text', text: message }],
|
|
98
|
+
structuredContent: { message },
|
|
99
|
+
viewProps: { message },
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { createMcpAppsHandler } from '@modern-js/mcp-apps/server';
|
|
106
|
+
|
|
107
|
+
const handleMcp = createMcpAppsHandler({
|
|
108
|
+
configPath: './mcp_apps.ts', // use compiled ./mcp_apps.mjs in production
|
|
109
|
+
serverInfo: { name: 'greeting', version: '1.0.0' },
|
|
110
|
+
});
|
|
111
|
+
// app.all('/mcp', c => handleMcp(c.req.raw)); // Hono or any Web Request adapter
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`createMcpAppsHandler` loads the trusted local definition lazily and retries failed
|
|
115
|
+
initialization. Config loading supports TS/TSX, JS/MJS/CJS, JSON, extensionless paths,
|
|
116
|
+
and default/config/mcpApps exports. Relative handler modules resolve from
|
|
117
|
+
the definition directory. TypeScript is compiled to ESM with esbuild; compiled
|
|
118
|
+
JS is imported directly. No request-supplied config URLs are accepted.
|
|
119
|
+
|
|
120
|
+
`createMcpHandler(definition, options)` is the lower-level synchronous registration
|
|
121
|
+
entry when the application already loaded its definition. `materializeMcpAppsConfig`
|
|
122
|
+
exports a serialized definition; it does not compile/copy referenced handlers.
|
|
123
|
+
|
|
124
|
+
## Publish the remote UI
|
|
125
|
+
|
|
126
|
+
Expose `./Greeting` with the existing MF or Vmok build tooling. Standard MF emits
|
|
127
|
+
`mf-manifest.json`, remote entry and chunks; Vmok emits its own manifest. Publish
|
|
128
|
+
those artifacts normally, then set `remotes[].baseUrl`/`browserEntry` to their URL.
|
|
129
|
+
There is no second UI manifest to generate, copy, or maintain.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import type { App } from '@modern-js/mcp-apps/react';
|
|
133
|
+
|
|
134
|
+
export default function Greeting({ message, mcpApp }: {
|
|
135
|
+
message?: string;
|
|
136
|
+
mcpApp?: App;
|
|
137
|
+
}) {
|
|
138
|
+
return <button onClick={() => mcpApp?.callServerTool({
|
|
139
|
+
name: 'greet', arguments: { name: 'Ada' },
|
|
140
|
+
})}>{message}</button>;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The renderer owns the host connection and passes `mcpApp` to the remote.
|
|
145
|
+
It also passes the original tool arguments merged with `viewProps`. Do not start
|
|
146
|
+
another `useApp`/`useMcpApp` connection inside that remote. Store explicit
|
|
147
|
+
`callServerTool` results in component state if the view needs to update itself.
|
|
148
|
+
The optional React hooks entry remains available for independently authored apps
|
|
149
|
+
that own their host connection.
|
|
150
|
+
|
|
151
|
+
`view.renderMode` accepts `component` (default) or `mount`, and `exportName` defaults
|
|
152
|
+
to `default`. Legacy top-level `module/exportName/renderMode` are normalized into
|
|
153
|
+
the explicit view definition. Handler-only tools can omit `remote` and use
|
|
154
|
+
`remotes: []`; view-only tools can omit `handler`. Explicit `annotations` are
|
|
155
|
+
preserved, never forced read-only.
|
|
156
|
+
|
|
157
|
+
## Compatibility and deployment
|
|
158
|
+
|
|
159
|
+
- The server registers `ui://mf/<remote-slug>/<tool-slug>` resources
|
|
160
|
+
plus remote-level aliases. URI collisions fail at startup.
|
|
161
|
+
- Resources contain the packaged, self-contained browser renderer. The renderer
|
|
162
|
+
reads `structuredContent.resource.moduleFederation` and loads the remote UI.
|
|
163
|
+
- Handler results use the `tool/resource/args/viewProps` envelope, business
|
|
164
|
+
`structuredContent`, `content` and `_meta`. Render information is included in
|
|
165
|
+
structuredContent.
|
|
166
|
+
- `outputSchema`, when supplied, validates business structuredContent before the
|
|
167
|
+
view envelope is attached. It is advertised in tools/list for handler-only tools;
|
|
168
|
+
view tools omit the advertised outputSchema to avoid contradicting that envelope.
|
|
169
|
+
- Browser `manifestType` defaults to `vmok`. New standard MF
|
|
170
|
+
projects should explicitly set `manifestType: 'mf'`.
|
|
171
|
+
- Browser MF and Vmok loaders support snapshot/static publicPath normalization.
|
|
172
|
+
Vmok region placeholder handling targets `region.cn`.
|
|
173
|
+
Standard MF is tested end-to-end; internal Vmok deployment still needs validation.
|
|
174
|
+
- `handler.runtime: 'vmok-server'` uses an optional runtime loader and
|
|
175
|
+
requires `serverEntry`. Install the compatible `@vmok/kit` where the core can
|
|
176
|
+
resolve it, or inject `loadRemoteHandler`; internal packages are not dependencies.
|
|
177
|
+
- Pin remote URLs to immutable releases. Remote assets must support cross-origin
|
|
178
|
+
loading, and their script/CSS/fetch origins must be declared in remote CSP.
|
|
179
|
+
- Production deploys contain the compiled definition and handler modules. No UI
|
|
180
|
+
source or copied UI manifest is needed. The Node process does not import React;
|
|
181
|
+
React is bundled into resource HTML for execution only inside the host iframe.
|
|
182
|
+
- Node 20+; pinned MCP SDK 1.30.0 / Apps SDK 1.7.5. Stateless POST-only HTTP with a
|
|
183
|
+
new SDK server/transport per request. No persistent sessions, resumable SSE,
|
|
184
|
+
server-initiated requests or cross-request cancellation routing in this version.
|
|
185
|
+
- Input/output schemas use strict JSON Schema 2020-12 validation, not lossy Zod
|
|
186
|
+
conversion. Unsupported keywords fail at startup. Inputs are not type-inferred.
|
|
187
|
+
- Handler context provides `toolName/remote/handler/extra/signal/fetch/
|
|
188
|
+
fetchJson/serverUrl` fields and adds `request/context`. `createContext(request)`
|
|
189
|
+
supplies request-local context. Host visibility is not an authorization boundary.
|
|
190
|
+
- Authentication, request-size limits and Host/Origin policy belong in HTTP
|
|
191
|
+
middleware. Errors from createContext propagate to that middleware. Tool failures
|
|
192
|
+
are generic to clients; use `onError` for server diagnostics. Handlers must honor
|
|
193
|
+
AbortSignal to stop external work; timeout cannot roll back side effects.
|
|
194
|
+
|
|
195
|
+
Modern.js CLI integration is provided by `@modern-js/plugin-mcp-apps`; see its
|
|
196
|
+
[README](../../cli/plugin-mcp-apps/README.md). The creator includes `mcp-apps`
|
|
197
|
+
and `mcp-server` templates. See `NOTICE.md` and `THIRD-PARTY-LICENSE` for
|
|
198
|
+
third-party license information.
|
|
199
|
+
|
|
200
|
+
`@modern-js/mcp-apps/build` exports `compileMcpApps({ configPath, outDir,
|
|
201
|
+
tsconfig?, alias?, development? })`. It bundles local code dependencies, keeps
|
|
202
|
+
runtime environment evaluation in the definition, and publishes a relocatable
|
|
203
|
+
`mcp_apps.mjs` only after all handler artifacts are ready. It also copies the
|
|
204
|
+
matching development/production renderer. Local handler references must remain
|
|
205
|
+
stable between build and runtime. Files read dynamically are application assets
|
|
206
|
+
and need separate deployment handling.
|
|
207
|
+
|
|
208
|
+
## Verify locally
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
pnpm --filter @modern-js/mcp-apps build
|
|
212
|
+
pnpm --filter @examples/mcp-apps-modern build
|
|
213
|
+
pnpm --filter @modern-js/mcp-apps test
|
|
214
|
+
pnpm --filter @modern-js/mcp-apps test:deployment
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The deployment test packs this package and installs it in a temporary directory,
|
|
218
|
+
then runs the compiled definition/handlers with no UI source, React installation,
|
|
219
|
+
or app-tools dependency. npm network access is needed for that isolated install.
|
|
220
|
+
|
|
221
|
+
For browser verification, start the Modern.js example and run
|
|
222
|
+
`node packages/toolkit/mcp-apps/scripts/browser-fixture.mjs` from the repository root.
|
|
223
|
+
It defaults to the integrated example at `http://127.0.0.1:8080/mcp`. For your own
|
|
224
|
+
standalone server, set `MCP_ENDPOINT` to its endpoint.
|
|
225
|
+
Open `http://127.0.0.1:8092` and click `Greet again`. The official AppBridge fixture
|
|
226
|
+
is test-only and excluded from the npm package; it does not replace target-host
|
|
227
|
+
compatibility testing.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Web Infra
|
|
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.
|