skybridge 0.0.0-dev.f7aded3 → 0.0.0-dev.f7e85aa

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 (191) hide show
  1. package/README.md +153 -0
  2. package/bin/run.js +0 -4
  3. package/dist/cli/detect-port.d.ts +18 -0
  4. package/dist/cli/detect-port.js +61 -0
  5. package/dist/cli/detect-port.js.map +1 -0
  6. package/dist/cli/header.js +1 -1
  7. package/dist/cli/header.js.map +1 -1
  8. package/dist/cli/telemetry.d.ts +7 -0
  9. package/dist/cli/telemetry.js +123 -0
  10. package/dist/cli/telemetry.js.map +1 -0
  11. package/dist/cli/types.d.ts +5 -0
  12. package/dist/cli/types.js +2 -0
  13. package/dist/cli/types.js.map +1 -0
  14. package/dist/cli/use-execute-steps.d.ts +3 -2
  15. package/dist/cli/use-execute-steps.js +6 -1
  16. package/dist/cli/use-execute-steps.js.map +1 -1
  17. package/dist/cli/use-messages.d.ts +3 -0
  18. package/dist/cli/use-messages.js +11 -0
  19. package/dist/cli/use-messages.js.map +1 -0
  20. package/dist/cli/use-nodemon.d.ts +2 -0
  21. package/dist/cli/use-nodemon.js +64 -0
  22. package/dist/cli/use-nodemon.js.map +1 -0
  23. package/dist/cli/use-tunnel.d.ts +14 -0
  24. package/dist/cli/use-tunnel.js +97 -0
  25. package/dist/cli/use-tunnel.js.map +1 -0
  26. package/dist/cli/use-typescript-check.d.ts +8 -0
  27. package/dist/cli/use-typescript-check.js +59 -0
  28. package/dist/cli/use-typescript-check.js.map +1 -0
  29. package/dist/commands/build.js +8 -5
  30. package/dist/commands/build.js.map +1 -1
  31. package/dist/commands/dev.d.ts +5 -1
  32. package/dist/commands/dev.js +38 -9
  33. package/dist/commands/dev.js.map +1 -1
  34. package/dist/commands/start.d.ts +3 -1
  35. package/dist/commands/start.js +31 -15
  36. package/dist/commands/start.js.map +1 -1
  37. package/dist/commands/telemetry/disable.d.ts +5 -0
  38. package/dist/commands/telemetry/disable.js +14 -0
  39. package/dist/commands/telemetry/disable.js.map +1 -0
  40. package/dist/commands/telemetry/enable.d.ts +5 -0
  41. package/dist/commands/telemetry/enable.js +14 -0
  42. package/dist/commands/telemetry/enable.js.map +1 -0
  43. package/dist/commands/telemetry/status.d.ts +5 -0
  44. package/dist/commands/telemetry/status.js +14 -0
  45. package/dist/commands/telemetry/status.js.map +1 -0
  46. package/dist/server/asset-base-url-transform-plugin.d.ts +10 -0
  47. package/dist/server/asset-base-url-transform-plugin.js +33 -0
  48. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  49. package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
  50. package/dist/server/asset-base-url-transform-plugin.test.js +55 -0
  51. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  52. package/dist/server/content-helpers.d.ts +27 -0
  53. package/dist/server/content-helpers.js +46 -0
  54. package/dist/server/content-helpers.js.map +1 -0
  55. package/dist/server/content-helpers.test.d.ts +1 -0
  56. package/dist/server/content-helpers.test.js +70 -0
  57. package/dist/server/content-helpers.test.js.map +1 -0
  58. package/dist/server/express.d.ts +15 -0
  59. package/dist/server/express.js +77 -0
  60. package/dist/server/express.js.map +1 -0
  61. package/dist/server/express.test.d.ts +1 -0
  62. package/dist/server/express.test.js +252 -0
  63. package/dist/server/express.test.js.map +1 -0
  64. package/dist/server/index.d.ts +4 -2
  65. package/dist/server/index.js +2 -1
  66. package/dist/server/index.js.map +1 -1
  67. package/dist/server/metric.d.ts +14 -0
  68. package/dist/server/metric.js +62 -0
  69. package/dist/server/metric.js.map +1 -0
  70. package/dist/server/middleware.d.ts +124 -0
  71. package/dist/server/middleware.js +93 -0
  72. package/dist/server/middleware.js.map +1 -0
  73. package/dist/server/middleware.test-d.d.ts +1 -0
  74. package/dist/server/middleware.test-d.js +75 -0
  75. package/dist/server/middleware.test-d.js.map +1 -0
  76. package/dist/server/middleware.test.d.ts +1 -0
  77. package/dist/server/middleware.test.js +493 -0
  78. package/dist/server/middleware.test.js.map +1 -0
  79. package/dist/server/server.d.ts +136 -61
  80. package/dist/server/server.js +304 -55
  81. package/dist/server/server.js.map +1 -1
  82. package/dist/server/templates/development.hbs +2 -56
  83. package/dist/server/templates/production.hbs +1 -2
  84. package/dist/server/widgetsDevServer.d.ts +9 -7
  85. package/dist/server/widgetsDevServer.js +22 -23
  86. package/dist/server/widgetsDevServer.js.map +1 -1
  87. package/dist/test/utils.d.ts +6 -14
  88. package/dist/test/utils.js +35 -30
  89. package/dist/test/utils.js.map +1 -1
  90. package/dist/test/widget.test.js +309 -110
  91. package/dist/test/widget.test.js.map +1 -1
  92. package/dist/version.d.ts +1 -0
  93. package/dist/version.js +5 -0
  94. package/dist/version.js.map +1 -0
  95. package/dist/web/bridges/apps-sdk/adaptor.d.ts +14 -4
  96. package/dist/web/bridges/apps-sdk/adaptor.js +53 -5
  97. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
  98. package/dist/web/bridges/apps-sdk/bridge.d.ts +1 -1
  99. package/dist/web/bridges/apps-sdk/index.d.ts +1 -1
  100. package/dist/web/bridges/apps-sdk/types.d.ts +30 -25
  101. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  102. package/dist/web/bridges/mcp-app/adaptor.d.ts +33 -4
  103. package/dist/web/bridges/mcp-app/adaptor.js +161 -38
  104. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
  105. package/dist/web/bridges/mcp-app/bridge.d.ts +13 -30
  106. package/dist/web/bridges/mcp-app/bridge.js +43 -196
  107. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  108. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -3
  109. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +2 -2
  110. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  111. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -41
  112. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  113. package/dist/web/bridges/types.d.ts +38 -3
  114. package/dist/web/components/modal-provider.d.ts +4 -0
  115. package/dist/web/components/modal-provider.js +45 -0
  116. package/dist/web/components/modal-provider.js.map +1 -0
  117. package/dist/web/create-store.js +15 -1
  118. package/dist/web/create-store.js.map +1 -1
  119. package/dist/web/create-store.test.js +9 -4
  120. package/dist/web/create-store.test.js.map +1 -1
  121. package/dist/web/data-llm.test.js +11 -8
  122. package/dist/web/data-llm.test.js.map +1 -1
  123. package/dist/web/generate-helpers.d.ts +8 -6
  124. package/dist/web/generate-helpers.js +8 -6
  125. package/dist/web/generate-helpers.js.map +1 -1
  126. package/dist/web/hooks/index.d.ts +2 -1
  127. package/dist/web/hooks/index.js +1 -0
  128. package/dist/web/hooks/index.js.map +1 -1
  129. package/dist/web/hooks/test/utils.js +4 -0
  130. package/dist/web/hooks/test/utils.js.map +1 -1
  131. package/dist/web/hooks/use-display-mode.d.ts +3 -3
  132. package/dist/web/hooks/use-display-mode.js.map +1 -1
  133. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  134. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  135. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  136. package/dist/web/hooks/use-files.d.ts +3 -6
  137. package/dist/web/hooks/use-files.js +5 -2
  138. package/dist/web/hooks/use-files.js.map +1 -1
  139. package/dist/web/hooks/use-files.test.js +28 -3
  140. package/dist/web/hooks/use-files.test.js.map +1 -1
  141. package/dist/web/hooks/use-layout.test.js +3 -3
  142. package/dist/web/hooks/use-layout.test.js.map +1 -1
  143. package/dist/web/hooks/use-open-external.d.ts +3 -1
  144. package/dist/web/hooks/use-open-external.js +1 -1
  145. package/dist/web/hooks/use-open-external.js.map +1 -1
  146. package/dist/web/hooks/use-open-external.test.js +26 -11
  147. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  148. package/dist/web/hooks/use-request-modal.d.ts +2 -2
  149. package/dist/web/hooks/use-request-modal.js +9 -7
  150. package/dist/web/hooks/use-request-modal.js.map +1 -1
  151. package/dist/web/hooks/use-request-modal.test.js +5 -1
  152. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  153. package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
  154. package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
  155. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  156. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  157. package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
  158. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  159. package/dist/web/hooks/use-tool-info.test.js +1 -1
  160. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  161. package/dist/web/hooks/use-user.js +18 -2
  162. package/dist/web/hooks/use-user.js.map +1 -1
  163. package/dist/web/hooks/use-user.test.js +29 -1
  164. package/dist/web/hooks/use-user.test.js.map +1 -1
  165. package/dist/web/hooks/use-widget-state.test.js +123 -7
  166. package/dist/web/hooks/use-widget-state.test.js.map +1 -1
  167. package/dist/web/index.d.ts +1 -0
  168. package/dist/web/index.js.map +1 -1
  169. package/dist/web/mount-widget.js +9 -1
  170. package/dist/web/mount-widget.js.map +1 -1
  171. package/dist/web/plugin/plugin.d.ts +4 -1
  172. package/dist/web/plugin/plugin.js +89 -18
  173. package/dist/web/plugin/plugin.js.map +1 -1
  174. package/dist/web/plugin/scan-widgets.d.ts +8 -0
  175. package/dist/web/plugin/scan-widgets.js +68 -0
  176. package/dist/web/plugin/scan-widgets.js.map +1 -0
  177. package/dist/web/plugin/scan-widgets.test.d.ts +1 -0
  178. package/dist/web/plugin/scan-widgets.test.js +96 -0
  179. package/dist/web/plugin/scan-widgets.test.js.map +1 -0
  180. package/dist/web/plugin/transform-data-llm.js +1 -1
  181. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  182. package/dist/web/plugin/validate-widget.d.ts +1 -0
  183. package/dist/web/plugin/validate-widget.js +9 -0
  184. package/dist/web/plugin/validate-widget.js.map +1 -0
  185. package/dist/web/plugin/validate-widget.test.d.ts +1 -0
  186. package/dist/web/plugin/validate-widget.test.js +24 -0
  187. package/dist/web/plugin/validate-widget.test.js.map +1 -0
  188. package/dist/web/proxy.js +0 -1
  189. package/dist/web/proxy.js.map +1 -1
  190. package/package.json +40 -25
  191. package/tsconfig.base.json +33 -0
@@ -1,7 +1,12 @@
1
+ import crypto from "node:crypto";
1
2
  import { readFileSync } from "node:fs";
3
+ import http from "node:http";
2
4
  import path from "node:path";
3
- import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { McpServer as McpServerBase } from "@modelcontextprotocol/sdk/server/mcp.js";
4
6
  import { mergeWith, union } from "es-toolkit";
7
+ import { createApp } from "./express.js";
8
+ import { createMiddlewareEntry } from "./metric.js";
9
+ import { buildMiddlewareChain, getHandlerMaps } from "./middleware.js";
5
10
  import { templateHelper } from "./templateHelper.js";
6
11
  const mergeWithUnion = (target, source) => {
7
12
  return mergeWith(target, source, (targetVal, sourceVal) => {
@@ -10,110 +15,311 @@ const mergeWithUnion = (target, source) => {
10
15
  }
11
16
  });
12
17
  };
13
- export class McpServer extends McpServerBase {
14
- registerWidget(name, resourceConfig, toolConfig, toolCallback) {
15
- const userMeta = resourceConfig._meta;
16
- const toolMeta = {
17
- ...toolConfig._meta,
18
+ // ---------------------------------------------------------------------------
19
+ // Content normalization
20
+ // ---------------------------------------------------------------------------
21
+ export function normalizeContent(content) {
22
+ if (typeof content === "string") {
23
+ return [{ type: "text", text: content }];
24
+ }
25
+ if (Array.isArray(content)) {
26
+ return content;
27
+ }
28
+ return [content];
29
+ }
30
+ const McpServerBaseOmitted = McpServerBase;
31
+ export class McpServer extends McpServerBaseOmitted {
32
+ express;
33
+ customMiddleware = [];
34
+ customErrorMiddleware = [];
35
+ mcpMiddlewareEntries = [];
36
+ mcpMiddlewareApplied = false;
37
+ claimedWidgets = new Map();
38
+ use(pathOrHandler, ...handlers) {
39
+ if (typeof pathOrHandler === "string") {
40
+ this.customMiddleware.push({
41
+ path: pathOrHandler,
42
+ handlers,
43
+ });
44
+ }
45
+ else {
46
+ this.customMiddleware.push({
47
+ handlers: [pathOrHandler, ...handlers],
48
+ });
49
+ }
50
+ return this;
51
+ }
52
+ useOnError(pathOrHandler, ...handlers) {
53
+ if (typeof pathOrHandler === "string") {
54
+ this.customErrorMiddleware.push({ path: pathOrHandler, handlers });
55
+ }
56
+ else {
57
+ this.customErrorMiddleware.push({
58
+ handlers: [pathOrHandler, ...handlers],
59
+ });
60
+ }
61
+ return this;
62
+ }
63
+ mcpMiddleware(filterOrHandler,
64
+ // biome-ignore lint/suspicious/noExplicitAny: overloads narrow the handler type at call sites; implementation must accept all variants
65
+ maybeHandler) {
66
+ if (this.mcpMiddlewareApplied) {
67
+ throw new Error("Cannot register MCP middleware after run() or connect() has been called");
68
+ }
69
+ const handler = maybeHandler;
70
+ if (typeof filterOrHandler === "function") {
71
+ this.mcpMiddlewareEntries.push({
72
+ filter: null,
73
+ handler: filterOrHandler,
74
+ });
75
+ }
76
+ else if (handler) {
77
+ this.mcpMiddlewareEntries.push({
78
+ filter: filterOrHandler,
79
+ handler,
80
+ });
81
+ }
82
+ else {
83
+ throw new Error("mcpMiddleware requires a handler function when a filter is provided");
84
+ }
85
+ return this;
86
+ }
87
+ applyMcpMiddleware() {
88
+ if (this.mcpMiddlewareApplied) {
89
+ return;
90
+ }
91
+ this.mcpMiddlewareApplied = true;
92
+ const monitoringEntry = createMiddlewareEntry();
93
+ const entries = monitoringEntry
94
+ ? [monitoringEntry, ...this.mcpMiddlewareEntries]
95
+ : this.mcpMiddlewareEntries;
96
+ if (entries.length === 0) {
97
+ return;
98
+ }
99
+ const { requestHandlers, notificationHandlers } = getHandlerMaps(this.server);
100
+ const instrumentMap = (map, isNotification) => {
101
+ for (const [method, handler] of map) {
102
+ map.set(method, buildMiddlewareChain(method, isNotification, handler, entries));
103
+ }
104
+ const originalSet = map.set.bind(map);
105
+ map.set = (method, handler) => originalSet(method, buildMiddlewareChain(method, isNotification, handler, entries));
18
106
  };
19
- if (!resourceConfig.hosts || resourceConfig.hosts.includes("apps-sdk")) {
107
+ instrumentMap(requestHandlers, false);
108
+ instrumentMap(notificationHandlers, true);
109
+ }
110
+ async connect(transport) {
111
+ this.applyMcpMiddleware();
112
+ return McpServerBase.prototype.connect.call(this, transport);
113
+ }
114
+ async run() {
115
+ this.applyMcpMiddleware();
116
+ const httpServer = http.createServer();
117
+ if (!this.express) {
118
+ this.express = await createApp({
119
+ mcpServer: this,
120
+ httpServer,
121
+ customMiddleware: this.customMiddleware,
122
+ errorMiddleware: this.customErrorMiddleware,
123
+ });
124
+ }
125
+ httpServer.on("request", this.express);
126
+ return new Promise((resolve, reject) => {
127
+ httpServer.on("error", (error) => {
128
+ console.error("Failed to start server:", error);
129
+ reject(error);
130
+ });
131
+ const port = parseInt(process.env.__PORT ?? "3000", 10);
132
+ httpServer.listen(port, () => {
133
+ resolve();
134
+ });
135
+ });
136
+ }
137
+ // registerTool is defined via interface merging + prototype assignment below
138
+ // to avoid TypeScript override signature incompatibility with the base class.
139
+ // -------------------------------------------------------------------------
140
+ // View (widget) resource registration
141
+ // -------------------------------------------------------------------------
142
+ /** @internal */
143
+ enforceOneToolPerWidget(component, toolName) {
144
+ const existingTool = this.claimedWidgets.get(component);
145
+ if (existingTool) {
146
+ throw new Error(`skybridge: widget "${component}" is already used by tool "${existingTool}". Tool "${toolName}" cannot also reference it — each widget backs exactly one tool.`);
147
+ }
148
+ this.claimedWidgets.set(component, toolName);
149
+ }
150
+ /** @internal */
151
+ registerViewResources(toolName, view, toolMeta) {
152
+ const hosts = view.hosts ?? ["apps-sdk", "mcp-app"];
153
+ if (hosts.includes("apps-sdk")) {
20
154
  const widgetConfig = {
21
155
  hostType: "apps-sdk",
22
- uri: `ui://widgets/apps-sdk/${name}.html`,
156
+ uri: `ui://widgets/apps-sdk/${view.component}.html`,
23
157
  mimeType: "text/html+skybridge",
24
- buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
25
- const userUi = userMeta?.ui;
26
- const userCsp = userUi?.csp;
158
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
27
159
  const defaults = {
28
160
  "openai/widgetCSP": {
29
161
  resource_domains: resourceDomains,
30
162
  connect_domains: connectDomains,
31
163
  },
32
164
  "openai/widgetDomain": domain,
33
- "openai/widgetDescription": toolConfig.description,
165
+ "openai/widgetDescription": view.description,
34
166
  };
35
- const fromUi = {
167
+ const fromView = {
36
168
  "openai/widgetCSP": {
37
- resource_domains: userCsp?.resourceDomains,
38
- connect_domains: userCsp?.connectDomains,
39
- frame_domains: userCsp?.frameDomains,
40
- redirect_domains: userCsp?.redirectDomains,
169
+ resource_domains: view.csp?.resourceDomains,
170
+ connect_domains: view.csp?.connectDomains,
171
+ frame_domains: view.csp?.frameDomains,
172
+ redirect_domains: view.csp?.redirectDomains,
41
173
  },
42
- "openai/widgetDomain": userUi?.domain,
43
- "openai/widgetPrefersBorder": userUi?.prefersBorder,
174
+ "openai/widgetDomain": view.domain,
175
+ "openai/widgetPrefersBorder": view.prefersBorder,
44
176
  };
45
- const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
46
- return mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys);
177
+ const base = mergeWithUnion(mergeWithUnion(defaults, fromView), {
178
+ "openai/widgetDomain": overrides.domain,
179
+ });
180
+ if (view._meta) {
181
+ return { ...base, ...view._meta };
182
+ }
183
+ return base;
47
184
  },
48
185
  };
49
186
  this.registerWidgetResource({
50
- name,
187
+ name: toolName,
51
188
  widgetConfig,
52
- resourceConfig,
189
+ view,
53
190
  });
54
191
  toolMeta["openai/outputTemplate"] = widgetConfig.uri;
55
192
  }
56
- if (!resourceConfig.hosts || resourceConfig.hosts.includes("mcp-app")) {
193
+ if (hosts.includes("mcp-app")) {
57
194
  const widgetConfig = {
58
195
  hostType: "mcp-app",
59
- uri: `ui://widgets/ext-apps/${name}.html`,
196
+ uri: `ui://widgets/ext-apps/${view.component}.html`,
60
197
  mimeType: "text/html;profile=mcp-app",
61
- buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
198
+ buildContentMeta: ({ resourceDomains, connectDomains, domain, baseUriDomains }, overrides) => {
62
199
  const defaults = {
63
200
  ui: {
64
201
  csp: {
65
202
  resourceDomains,
66
203
  connectDomains,
204
+ baseUriDomains,
67
205
  },
68
206
  domain,
69
207
  },
70
208
  };
71
- return mergeWithUnion(defaults, { ui: userMeta?.ui });
209
+ const fromView = {
210
+ ui: {
211
+ ...(view.description && { description: view.description }),
212
+ ...(view.prefersBorder !== undefined && {
213
+ prefersBorder: view.prefersBorder,
214
+ }),
215
+ ...(view.domain && { domain: view.domain }),
216
+ csp: {
217
+ ...(view.csp?.resourceDomains && {
218
+ resourceDomains: view.csp.resourceDomains,
219
+ }),
220
+ ...(view.csp?.connectDomains && {
221
+ connectDomains: view.csp.connectDomains,
222
+ }),
223
+ ...(view.csp?.frameDomains && {
224
+ frameDomains: view.csp.frameDomains,
225
+ }),
226
+ ...(view.csp?.baseUriDomains && {
227
+ baseUriDomains: view.csp.baseUriDomains,
228
+ }),
229
+ ...(view.csp?.redirectDomains && {
230
+ redirectDomains: view.csp.redirectDomains,
231
+ }),
232
+ },
233
+ },
234
+ };
235
+ const base = mergeWithUnion(mergeWithUnion(defaults, fromView), {
236
+ ui: overrides,
237
+ });
238
+ if (view._meta) {
239
+ return { ...base, ...view._meta };
240
+ }
241
+ return base;
72
242
  },
73
243
  };
74
244
  this.registerWidgetResource({
75
- name,
245
+ name: toolName,
76
246
  widgetConfig,
77
- resourceConfig,
247
+ view,
78
248
  });
249
+ // @ts-expect-error - For backwards compatibility with Claude current implementation of the specs
250
+ toolMeta["ui/resourceUri"] = widgetConfig.uri;
79
251
  toolMeta.ui = { resourceUri: widgetConfig.uri };
80
252
  }
81
- this.registerTool(name, {
82
- ...toolConfig,
83
- _meta: toolMeta,
84
- }, toolCallback);
85
- return this;
86
253
  }
87
- registerTool(name, config, cb) {
88
- super.registerTool(name, config, cb);
89
- return this;
90
- }
91
- registerWidgetResource({ name, widgetConfig, resourceConfig, }) {
254
+ registerWidgetResource({ name, widgetConfig, view, }) {
92
255
  const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
93
- this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
256
+ this.registerResource(name, widgetUri, { description: view.description }, async (uri, extra) => {
94
257
  const isProduction = process.env.NODE_ENV === "production";
95
- const serverUrl = isProduction
96
- ? `https://${extra?.requestInfo?.headers?.["x-forwarded-host"] ?? extra?.requestInfo?.headers?.host}`
97
- : "http://localhost:3000";
258
+ const isClaude = extra?.requestInfo?.headers?.["user-agent"] === "Claude-User";
259
+ const headers = extra?.requestInfo?.headers || {};
260
+ const header = (key) => {
261
+ const val = headers[key];
262
+ return Array.isArray(val) ? val[0] : val;
263
+ };
264
+ let serverUrl;
265
+ const forwardedHost = header("x-forwarded-host");
266
+ const origin = header("origin");
267
+ const host = header("host");
268
+ if (forwardedHost) {
269
+ const proto = header("x-forwarded-proto") || "https";
270
+ serverUrl = `${proto}://${forwardedHost}`;
271
+ }
272
+ else if (origin) {
273
+ serverUrl = origin;
274
+ }
275
+ else if (host) {
276
+ const proto = ["127.0.0.1:", "localhost:"].some((p) => host.startsWith(p))
277
+ ? "http"
278
+ : "https";
279
+ serverUrl = `${proto}://${host}`;
280
+ }
281
+ else {
282
+ const devPort = process.env.__PORT || "3000";
283
+ serverUrl = `http://localhost:${devPort}`;
284
+ }
98
285
  const html = isProduction
99
286
  ? templateHelper.renderProduction({
100
287
  hostType,
101
288
  serverUrl,
102
- widgetFile: this.lookupDistFileWithIndexFallback(`src/widgets/${name}`),
103
- styleFile: this.lookupDistFile("style.css"),
289
+ widgetFile: this.lookupWidgetFile(view.component),
290
+ styleFile: this.lookupDistFile("style.css") ?? "",
104
291
  })
105
292
  : templateHelper.renderDevelopment({
106
293
  hostType,
107
294
  serverUrl,
108
- widgetName: name,
295
+ widgetName: view.component,
109
296
  });
110
- const VITE_HMR_WEBSOCKET_DEFAULT_URL = "ws://localhost:24678";
297
+ const connectDomains = [serverUrl];
298
+ if (!isProduction) {
299
+ const wsUrl = new URL(serverUrl);
300
+ wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
301
+ connectDomains.push(wsUrl.origin);
302
+ }
303
+ let contentMetaOverrides = {};
304
+ if (isClaude) {
305
+ const pathname = extra?.requestInfo?.url?.pathname ?? "";
306
+ const rawUrl = header("x-alpic-forwarded-url") ?? `${serverUrl}${pathname}`;
307
+ // Strip a lone trailing slash so the hash matches the connector URL
308
+ // as registered with Claude (which has no trailing slash on bare origins).
309
+ const url = rawUrl.endsWith("/") ? rawUrl.slice(0, -1) : rawUrl;
310
+ const hash = crypto
311
+ .createHash("sha256")
312
+ .update(url)
313
+ .digest("hex")
314
+ .slice(0, 32);
315
+ contentMetaOverrides = { domain: `${hash}.claudemcpcontent.com` };
316
+ }
111
317
  const contentMeta = buildContentMeta({
112
318
  resourceDomains: [serverUrl],
113
- connectDomains: !isProduction ? [VITE_HMR_WEBSOCKET_DEFAULT_URL] : [],
319
+ connectDomains,
114
320
  domain: serverUrl,
115
321
  baseUriDomains: [serverUrl],
116
- });
322
+ }, contentMetaOverrides);
117
323
  return {
118
324
  contents: [
119
325
  { uri: uri.href, mimeType, text: html, _meta: contentMeta },
@@ -121,18 +327,61 @@ export class McpServer extends McpServerBase {
121
327
  };
122
328
  });
123
329
  }
124
- lookupDistFile(key) {
330
+ // -------------------------------------------------------------------------
331
+ // Handler wrapping
332
+ // -------------------------------------------------------------------------
333
+ /** @internal */
334
+ wrapHandler(cb, { attachViewUUID }) {
335
+ return async (args, extra) => {
336
+ const result = await cb(args, extra);
337
+ return {
338
+ ...result,
339
+ content: normalizeContent(result.content),
340
+ ...(attachViewUUID && {
341
+ _meta: {
342
+ ...result._meta,
343
+ viewUUID: crypto.randomUUID(),
344
+ },
345
+ }),
346
+ };
347
+ };
348
+ }
349
+ // -------------------------------------------------------------------------
350
+ // Manifest helpers
351
+ // -------------------------------------------------------------------------
352
+ lookupWidgetFile(widgetName) {
125
353
  const manifest = this.readManifest();
126
- return manifest[key]?.file;
354
+ for (const entry of Object.values(manifest)) {
355
+ if (entry?.isEntry && entry.name === widgetName && entry.file) {
356
+ return entry.file;
357
+ }
358
+ }
359
+ throw new Error(`Widget "${widgetName}" not found in Vite manifest. Did the build complete successfully? Look for an entry with name "${widgetName}" in dist/assets/.vite/manifest.json.`);
127
360
  }
128
- lookupDistFileWithIndexFallback(basePath) {
361
+ lookupDistFile(key) {
129
362
  const manifest = this.readManifest();
130
- const flatFileKey = `${basePath}.tsx`;
131
- const indexFileKey = `${basePath}/index.tsx`;
132
- return manifest[flatFileKey]?.file ?? manifest[indexFileKey]?.file;
363
+ return manifest[key]?.file;
133
364
  }
134
365
  readManifest() {
135
366
  return JSON.parse(readFileSync(path.join(process.cwd(), "dist", "assets", ".vite", "manifest.json"), "utf-8"));
136
367
  }
368
+ registerTool(...args) {
369
+ const baseFn = McpServerBase.prototype.registerTool;
370
+ if (typeof args[0] === "string") {
371
+ baseFn.call(this, args[0], args[1], args[2]);
372
+ return this;
373
+ }
374
+ const config = args[0];
375
+ const cb = args[1];
376
+ const { name, view, _meta: userToolMeta, ...toolFields } = config;
377
+ const toolMeta = { ...userToolMeta };
378
+ if (view) {
379
+ this.enforceOneToolPerWidget(view.component, name);
380
+ this.registerViewResources(name, view, toolMeta);
381
+ }
382
+ const wrappedCb = this.wrapHandler(cb, { attachViewUUID: Boolean(view) });
383
+ baseFn.call(this, name, { ...toolFields, _meta: toolMeta }, wrappedCb);
384
+ return this;
385
+ }
137
386
  }
138
387
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- <base href="{{serverUrl}}" />
2
- <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
1
+ <script type="module">window.skybridge = { hostType: "{{hostType}}", serverUrl: "{{serverUrl}}" };</script>
3
2
  <script type="module">
4
3
  import { injectIntoGlobalHook } from "{{serverUrl}}/assets/@react-refresh";
5
4
  injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};
@@ -7,60 +6,7 @@
7
6
  window.__vite_plugin_react_preamble_installed__ = true;
8
7
  </script>
9
8
  <script type="module" src="{{serverUrl}}/@vite/client"></script>
10
- <script type="module">
11
- // Checks for browser support and shows error if local network access is denied
12
- (async () => {
13
- if (!navigator.permissions?.query) {
14
- return;
15
- }
16
-
17
- // Skip for non-http(s) protocols (file://, custom protocols in Electron, etc.)
18
- const protocol = window.location.protocol;
19
- const isNonHttpProtocol = protocol !== 'http:' && protocol !== 'https:'
20
- if (isNonHttpProtocol) {
21
- return;
22
- }
23
-
24
- const host = window.location.hostname;
25
- const isLoopback = host === 'localhost'
26
- || /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.test(host)
27
- || host === '::1';
28
- if (isLoopback) {
29
- return;
30
- }
31
-
32
- try {
33
- const status = await navigator.permissions.query({ name: "local-network-access" });
34
- if (status.state === "denied") {
35
- const errorDiv = document.createElement("div");
36
- errorDiv.style.cssText = "background: #fef2f2; border: 2px solid #ef4444; border-radius: 8px; padding: 16px; text-align: center; z-index: 10000; font-family: system-ui, sans-serif;";
37
-
38
- const errorTitle = document.createElement("div");
39
- errorTitle.style.cssText = "color: #ef4444; font-size: 18px; font-weight: 600; margin-bottom: 8px;";
40
- errorTitle.textContent = "Error: Local network access permission is denied.";
41
-
42
- const errorMessage = document.createElement("div");
43
- errorMessage.style.cssText = "color: #ef4444; font-size: 14px;";
44
- errorMessage.textContent = "Local network access is required for your widget to connect to the local dev server. Please enable it in your browser settings. ";
45
-
46
- const link = document.createElement("a");
47
- link.href = "https://developer.chrome.com/blog/local-network-access";
48
- link.target = "_blank";
49
- link.rel = "noopener noreferrer";
50
- link.style.cssText = "color: #ef4444; text-decoration: underline;";
51
- link.textContent = "Learn more";
52
- errorMessage.appendChild(link);
53
-
54
- errorDiv.appendChild(errorTitle);
55
- errorDiv.appendChild(errorMessage);
56
- document.body.appendChild(errorDiv);
57
- }
58
- } catch (e) {
59
- // Permission API doesn't support local-network-access, ignore silently
60
- }
61
- })();
62
- </script>
63
9
  <div id="root"></div>
64
10
  <script type="module" id="dev-widget-entry">
65
- import('{{serverUrl}}/src/widgets/{{widgetName}}');
11
+ import('{{serverUrl}}/_skybridge/widget/{{widgetName}}');
66
12
  </script>
@@ -1,5 +1,4 @@
1
- <base href="{{serverUrl}}" />
2
- <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
1
+ <script type="module">window.skybridge = { hostType: "{{hostType}}", serverUrl: "{{serverUrl}}" };</script>
3
2
  <div id="root"></div>
4
3
  <script type="module">
5
4
  import('{{serverUrl}}/assets/{{widgetFile}}');
@@ -1,12 +1,14 @@
1
+ import type http from "node:http";
1
2
  import { type Router } from "express";
2
3
  /**
3
- * Install Vite dev server
4
- * This router MUST be installed at the application root, like so:
4
+ * Vite dev-server middleware for widget assets.
5
5
  *
6
- * const app = express();
6
+ * MUST be mounted at the Express app root so Vite can intercept
7
+ * `/@vite/client`, `/@react-refresh`, and `/_skybridge/widget/...` imports:
7
8
  *
8
- * if (env.NODE_ENV !== "production") {
9
- * app.use(await widgetsRouter());
10
- * }
9
+ * const app = express();
10
+ * if (env.NODE_ENV !== "production") {
11
+ * app.use(await widgetsDevServer(httpServer));
12
+ * }
11
13
  */
12
- export declare const widgetsDevServer: () => Promise<Router>;
14
+ export declare const widgetsDevServer: (httpServer: http.Server) => Promise<Router>;
@@ -1,44 +1,43 @@
1
- import { existsSync } from "node:fs";
2
1
  import path from "node:path";
3
2
  import cors from "cors";
4
3
  import express, {} from "express";
4
+ import { assetBaseUrlTransformPlugin } from "./asset-base-url-transform-plugin.js";
5
5
  /**
6
- * Install Vite dev server
7
- * This router MUST be installed at the application root, like so:
6
+ * Vite dev-server middleware for widget assets.
8
7
  *
9
- * const app = express();
8
+ * MUST be mounted at the Express app root so Vite can intercept
9
+ * `/@vite/client`, `/@react-refresh`, and `/_skybridge/widget/...` imports:
10
10
  *
11
- * if (env.NODE_ENV !== "production") {
12
- * app.use(await widgetsRouter());
13
- * }
11
+ * const app = express();
12
+ * if (env.NODE_ENV !== "production") {
13
+ * app.use(await widgetsDevServer(httpServer));
14
+ * }
14
15
  */
15
- export const widgetsDevServer = async () => {
16
+ export const widgetsDevServer = async (httpServer) => {
16
17
  const router = express.Router();
17
- const { createServer, searchForWorkspaceRoot, loadConfigFromFile } = await import("vite");
18
- // Since 0.16.0, the template is a single package that does not rely on workspace.
19
- // It means that, when starting the server, the working dir is the template root
20
- // hence we don't need to walk up the tree to find the workspace, which does not exist anymore.
21
- let webAppRoot = path.join(process.cwd(), "web");
22
- // fallback to the old behavior for backward compatibility
23
- const hasWebAppRoot = existsSync(webAppRoot);
24
- if (!hasWebAppRoot) {
25
- const workspaceRoot = searchForWorkspaceRoot(process.cwd());
26
- webAppRoot = path.join(workspaceRoot, "web");
27
- }
28
- const configResult = await loadConfigFromFile({ command: "serve", mode: "development" }, path.join(webAppRoot, "vite.config.ts"), webAppRoot);
29
- const { build, preview, ...devConfig } = configResult?.config || {};
18
+ const { createServer, loadConfigFromFile } = await import("vite");
19
+ const root = process.cwd();
20
+ const configFile = path.join(root, "vite.config.ts");
21
+ const configResult = await loadConfigFromFile({ command: "serve", mode: "development" }, configFile, root);
22
+ const { build, preview, plugins: userPlugins = [], ...devConfig } = configResult?.config || {};
30
23
  const vite = await createServer({
31
24
  ...devConfig,
32
- configFile: false, // Keep this to prevent vite from trying to resolve path in the target config file
25
+ // Pass `false` so Vite skips re-resolving a config file we already
26
+ // loaded and spread the user's config above.
27
+ configFile: false,
33
28
  appType: "custom",
34
29
  server: {
35
30
  allowedHosts: true,
36
31
  middlewareMode: true,
32
+ hmr: {
33
+ server: httpServer,
34
+ },
37
35
  },
38
- root: webAppRoot,
36
+ root,
39
37
  optimizeDeps: {
40
38
  include: ["react", "react-dom/client"],
41
39
  },
40
+ plugins: [...userPlugins, assetBaseUrlTransformPlugin()],
42
41
  });
43
42
  router.use(cors());
44
43
  router.use("/", vite.middlewares);