@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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +12 -0
  3. package/README.md +227 -0
  4. package/THIRD-PARTY-LICENSE +21 -0
  5. package/dist/cjs/bff.cjs +889 -0
  6. package/dist/cjs/build.cjs +936 -0
  7. package/dist/cjs/config.cjs +42 -0
  8. package/dist/cjs/hono.cjs +874 -0
  9. package/dist/cjs/server.cjs +887 -0
  10. package/dist/esm/react.mjs +29 -0
  11. package/dist/esm-node/bff.mjs +42 -0
  12. package/dist/esm-node/build.mjs +142 -0
  13. package/dist/esm-node/config.mjs +4 -0
  14. package/dist/esm-node/hono.mjs +26 -0
  15. package/dist/esm-node/server.mjs +747 -0
  16. package/dist/runtime/mcp-app.dev.html +238 -0
  17. package/dist/runtime/mcp-app.html +238 -0
  18. package/dist/types/artifact.d.ts +11 -0
  19. package/dist/types/bff.d.ts +22 -0
  20. package/dist/types/build.d.ts +12 -0
  21. package/dist/types/config.d.ts +104 -0
  22. package/dist/types/definition.d.ts +214 -0
  23. package/dist/types/hono.d.ts +26 -0
  24. package/dist/types/loader.d.ts +5 -0
  25. package/dist/types/react.d.ts +108 -0
  26. package/dist/types/resources.d.ts +15 -0
  27. package/dist/types/runtime/components/error-boundary.d.ts +21 -0
  28. package/dist/types/runtime/components/remote-component-container.d.ts +65 -0
  29. package/dist/types/runtime/context/MFContext.d.ts +27 -0
  30. package/dist/types/runtime/context/MFProvider.d.ts +22 -0
  31. package/dist/types/runtime/hooks/useRemoteComponent.d.ts +53 -0
  32. package/dist/types/runtime/loaders/mf-loader.d.ts +37 -0
  33. package/dist/types/runtime/loaders/snapshot-loader.d.ts +19 -0
  34. package/dist/types/runtime/loaders/vmok-loader.d.ts +25 -0
  35. package/dist/types/runtime/loaders/vmok-manifest-plugin.d.ts +4 -0
  36. package/dist/types/runtime/mcp-app.d.ts +1 -0
  37. package/dist/types/runtime/styles/styles.d.ts +1 -0
  38. package/dist/types/runtime/utils/remote-types.d.ts +19 -0
  39. package/dist/types/runtime/utils/types.d.ts +10 -0
  40. package/dist/types/server.d.ts +30 -0
  41. 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.