skybridge 0.0.0-dev.e6b33a7 → 0.0.0-dev.e743e37

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 (179) hide show
  1. package/README.md +145 -0
  2. package/bin/run.js +0 -4
  3. package/dist/cli/telemetry.d.ts +7 -0
  4. package/dist/cli/telemetry.js +123 -0
  5. package/dist/cli/telemetry.js.map +1 -0
  6. package/dist/cli/use-execute-steps.d.ts +3 -2
  7. package/dist/cli/use-execute-steps.js +6 -1
  8. package/dist/cli/use-execute-steps.js.map +1 -1
  9. package/dist/cli/use-nodemon.d.ts +6 -0
  10. package/dist/cli/use-nodemon.js +69 -0
  11. package/dist/cli/use-nodemon.js.map +1 -0
  12. package/dist/cli/use-typescript-check.d.ts +8 -0
  13. package/dist/cli/use-typescript-check.js +59 -0
  14. package/dist/cli/use-typescript-check.js.map +1 -0
  15. package/dist/commands/build.js +4 -2
  16. package/dist/commands/build.js.map +1 -1
  17. package/dist/commands/dev.d.ts +3 -1
  18. package/dist/commands/dev.js +20 -9
  19. package/dist/commands/dev.js.map +1 -1
  20. package/dist/commands/start.js +12 -12
  21. package/dist/commands/start.js.map +1 -1
  22. package/dist/commands/telemetry/disable.d.ts +5 -0
  23. package/dist/commands/telemetry/disable.js +14 -0
  24. package/dist/commands/telemetry/disable.js.map +1 -0
  25. package/dist/commands/telemetry/enable.d.ts +5 -0
  26. package/dist/commands/telemetry/enable.js +14 -0
  27. package/dist/commands/telemetry/enable.js.map +1 -0
  28. package/dist/commands/telemetry/status.d.ts +5 -0
  29. package/dist/commands/telemetry/status.js +14 -0
  30. package/dist/commands/telemetry/status.js.map +1 -0
  31. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  32. package/dist/server/asset-base-url-transform-plugin.js +34 -0
  33. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  34. package/dist/server/asset-base-url-transform-plugin.test.js +56 -0
  35. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  36. package/dist/server/express.d.ts +9 -0
  37. package/dist/server/express.js +69 -0
  38. package/dist/server/express.js.map +1 -0
  39. package/dist/server/express.test.d.ts +1 -0
  40. package/dist/server/express.test.js +74 -0
  41. package/dist/server/express.test.js.map +1 -0
  42. package/dist/server/server.d.ts +6 -0
  43. package/dist/server/server.js +62 -6
  44. package/dist/server/server.js.map +1 -1
  45. package/dist/server/templateHelper.d.ts +1 -0
  46. package/dist/server/templateHelper.js.map +1 -1
  47. package/dist/server/templates/development.hbs +3 -2
  48. package/dist/server/templates/production.hbs +1 -2
  49. package/dist/server/widgetsDevServer.js +11 -1
  50. package/dist/server/widgetsDevServer.js.map +1 -1
  51. package/dist/test/widget.test.js +22 -16
  52. package/dist/test/widget.test.js.map +1 -1
  53. package/dist/web/bridges/{adaptors/apps-sdk-adaptor.d.ts → apps-sdk/adaptor.d.ts} +10 -2
  54. package/dist/web/bridges/apps-sdk/adaptor.js +80 -0
  55. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  56. package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
  57. package/dist/web/bridges/{apps-sdk-bridge.js → apps-sdk/bridge.js} +2 -2
  58. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  59. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  60. package/dist/web/bridges/apps-sdk/index.js +5 -0
  61. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  62. package/dist/web/bridges/apps-sdk/types.d.ts +118 -0
  63. package/dist/web/bridges/apps-sdk/types.js +10 -0
  64. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  65. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
  66. package/dist/web/bridges/{hooks/use-apps-sdk-bridge.js → apps-sdk/use-apps-sdk-context.js} +3 -3
  67. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  68. package/dist/web/bridges/{hooks/get-adaptor.d.ts → get-adaptor.d.ts} +1 -1
  69. package/dist/web/bridges/get-adaptor.js +8 -0
  70. package/dist/web/bridges/get-adaptor.js.map +1 -0
  71. package/dist/web/bridges/index.d.ts +5 -4
  72. package/dist/web/bridges/index.js +5 -4
  73. package/dist/web/bridges/index.js.map +1 -1
  74. package/dist/web/bridges/{adaptors/mcp-app-adaptor.d.ts → mcp-app/adaptor.d.ts} +20 -3
  75. package/dist/web/bridges/{adaptors/mcp-app-adaptor.js → mcp-app/adaptor.js} +64 -19
  76. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  77. package/dist/web/bridges/{mcp-app-bridge.d.ts → mcp-app/bridge.d.ts} +7 -13
  78. package/dist/web/bridges/{mcp-app-bridge.js → mcp-app/bridge.js} +22 -18
  79. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  80. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  81. package/dist/web/bridges/mcp-app/index.js +4 -0
  82. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  83. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  84. package/dist/web/bridges/mcp-app/types.js +2 -0
  85. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  86. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -0
  87. package/dist/web/bridges/{hooks/use-mcp-app-bridge.js → mcp-app/use-mcp-app-context.js} +3 -3
  88. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  89. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  90. package/dist/web/bridges/{hooks/use-mcp-app-bridge.test.js → mcp-app/use-mcp-app-context.test.js} +16 -7
  91. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  92. package/dist/web/bridges/types.d.ts +60 -23
  93. package/dist/web/bridges/use-host-context.d.ts +2 -0
  94. package/dist/web/bridges/use-host-context.js +8 -0
  95. package/dist/web/bridges/use-host-context.js.map +1 -0
  96. package/dist/web/components/modal-provider.d.ts +4 -0
  97. package/dist/web/components/modal-provider.js +47 -0
  98. package/dist/web/components/modal-provider.js.map +1 -0
  99. package/dist/web/create-store.test.js +12 -9
  100. package/dist/web/create-store.test.js.map +1 -1
  101. package/dist/web/data-llm.test.js +14 -13
  102. package/dist/web/data-llm.test.js.map +1 -1
  103. package/dist/web/generate-helpers.d.ts +3 -2
  104. package/dist/web/generate-helpers.js +1 -1
  105. package/dist/web/generate-helpers.js.map +1 -1
  106. package/dist/web/helpers/state.js +2 -2
  107. package/dist/web/helpers/state.js.map +1 -1
  108. package/dist/web/hooks/index.d.ts +1 -1
  109. package/dist/web/hooks/index.js +1 -1
  110. package/dist/web/hooks/index.js.map +1 -1
  111. package/dist/web/hooks/use-call-tool.d.ts +2 -1
  112. package/dist/web/hooks/use-call-tool.js +1 -1
  113. package/dist/web/hooks/use-call-tool.js.map +1 -1
  114. package/dist/web/hooks/use-display-mode.js +2 -3
  115. package/dist/web/hooks/use-display-mode.js.map +1 -1
  116. package/dist/web/hooks/use-files.d.ts +2 -6
  117. package/dist/web/hooks/use-files.js +4 -2
  118. package/dist/web/hooks/use-files.js.map +1 -1
  119. package/dist/web/hooks/use-files.test.js +6 -1
  120. package/dist/web/hooks/use-files.test.js.map +1 -1
  121. package/dist/web/hooks/use-layout.d.ts +2 -2
  122. package/dist/web/hooks/use-layout.js +4 -4
  123. package/dist/web/hooks/use-layout.js.map +1 -1
  124. package/dist/web/hooks/use-layout.test.js +4 -3
  125. package/dist/web/hooks/use-layout.test.js.map +1 -1
  126. package/dist/web/hooks/use-open-external.test.js +1 -1
  127. package/dist/web/hooks/use-request-modal.d.ts +2 -2
  128. package/dist/web/hooks/use-request-modal.js +9 -7
  129. package/dist/web/hooks/use-request-modal.js.map +1 -1
  130. package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
  131. package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
  132. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  133. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  134. package/dist/web/hooks/use-set-open-in-app-url.test.js +49 -0
  135. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  136. package/dist/web/hooks/use-tool-info.js +4 -4
  137. package/dist/web/hooks/use-tool-info.js.map +1 -1
  138. package/dist/web/hooks/use-tool-info.test.js +4 -4
  139. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  140. package/dist/web/hooks/use-user.d.ts +1 -1
  141. package/dist/web/hooks/use-user.js +3 -3
  142. package/dist/web/hooks/use-user.js.map +1 -1
  143. package/dist/web/hooks/use-user.test.js +4 -3
  144. package/dist/web/hooks/use-user.test.js.map +1 -1
  145. package/dist/web/hooks/use-widget-state.js +2 -2
  146. package/dist/web/hooks/use-widget-state.js.map +1 -1
  147. package/dist/web/hooks/use-widget-state.test.js +7 -6
  148. package/dist/web/hooks/use-widget-state.test.js.map +1 -1
  149. package/dist/web/mount-widget.js +9 -1
  150. package/dist/web/mount-widget.js.map +1 -1
  151. package/dist/web/plugin/plugin.js +16 -9
  152. package/dist/web/plugin/plugin.js.map +1 -1
  153. package/dist/web/proxy.js +0 -1
  154. package/dist/web/proxy.js.map +1 -1
  155. package/dist/web/types.d.ts +0 -133
  156. package/dist/web/types.js +0 -9
  157. package/dist/web/types.js.map +1 -1
  158. package/package.json +30 -19
  159. package/tsconfig.base.json +28 -0
  160. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js +0 -39
  161. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js.map +0 -1
  162. package/dist/web/bridges/adaptors/mcp-app-adaptor.js.map +0 -1
  163. package/dist/web/bridges/apps-sdk-bridge.d.ts +0 -10
  164. package/dist/web/bridges/apps-sdk-bridge.js.map +0 -1
  165. package/dist/web/bridges/hooks/get-adaptor.js +0 -8
  166. package/dist/web/bridges/hooks/get-adaptor.js.map +0 -1
  167. package/dist/web/bridges/hooks/use-apps-sdk-bridge.d.ts +0 -2
  168. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js.map +0 -1
  169. package/dist/web/bridges/hooks/use-bridge.d.ts +0 -2
  170. package/dist/web/bridges/hooks/use-bridge.js +0 -8
  171. package/dist/web/bridges/hooks/use-bridge.js.map +0 -1
  172. package/dist/web/bridges/hooks/use-mcp-app-bridge.d.ts +0 -5
  173. package/dist/web/bridges/hooks/use-mcp-app-bridge.js.map +0 -1
  174. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js.map +0 -1
  175. package/dist/web/bridges/mcp-app-bridge.js.map +0 -1
  176. package/dist/web/hooks/use-openai-global.d.ts +0 -3
  177. package/dist/web/hooks/use-openai-global.js +0 -6
  178. package/dist/web/hooks/use-openai-global.js.map +0 -1
  179. /package/dist/{web/bridges/hooks/use-mcp-app-bridge.test.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
@@ -1,19 +1,36 @@
1
1
  import type { McpUiRequestDisplayModeResult } from "@modelcontextprotocol/ext-apps";
2
- import type { Adaptor, BridgeInterface, CallToolResponse, DisplayMode, ExternalStore, SetWidgetStateAction } from "../types.js";
2
+ import type { Adaptor, CallToolResponse, DisplayMode, HostContext, HostContextStore, RequestModalOptions, SetWidgetStateAction } from "../types.js";
3
3
  export declare class McpAppAdaptor implements Adaptor {
4
4
  private static instance;
5
5
  private stores;
6
6
  private _widgetState;
7
7
  private widgetStateListeners;
8
+ private _viewState;
9
+ private viewListeners;
8
10
  private constructor();
9
11
  static getInstance(): McpAppAdaptor;
10
12
  static resetInstance(): void;
11
- getExternalStore<K extends keyof BridgeInterface>(key: K): ExternalStore<K>;
13
+ getHostContextStore<K extends keyof HostContext>(key: K): HostContextStore<K>;
12
14
  callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
13
15
  requestDisplayMode: (mode: DisplayMode) => Promise<McpUiRequestDisplayModeResult>;
14
16
  sendFollowUpMessage: (prompt: string) => Promise<void>;
15
17
  openExternal(href: string): void;
16
18
  private initializeStores;
17
19
  setWidgetState: (stateOrUpdater: SetWidgetStateAction) => Promise<void>;
18
- private createExternalStore;
20
+ /**
21
+ * @throws File upload is not supported in MCP App.
22
+ */
23
+ uploadFile(): Promise<{
24
+ fileId: string;
25
+ }>;
26
+ /**
27
+ * @throws File download is not supported in MCP App.
28
+ */
29
+ getFileDownloadUrl(): Promise<{
30
+ downloadUrl: string;
31
+ }>;
32
+ openModal(options: RequestModalOptions): void;
33
+ closeModal(): void;
34
+ setOpenInAppUrl(_href: string): Promise<void>;
35
+ private createHostContextStore;
19
36
  }
@@ -1,10 +1,14 @@
1
1
  import { dequal } from "dequal/lite";
2
- import { McpAppBridge, } from "../mcp-app-bridge.js";
2
+ import { McpAppBridge } from "./bridge.js";
3
3
  export class McpAppAdaptor {
4
4
  static instance = null;
5
5
  stores;
6
6
  _widgetState = null;
7
7
  widgetStateListeners = new Set();
8
+ _viewState = {
9
+ mode: "inline",
10
+ };
11
+ viewListeners = new Set();
8
12
  constructor() {
9
13
  this.stores = this.initializeStores();
10
14
  }
@@ -17,7 +21,7 @@ export class McpAppAdaptor {
17
21
  static resetInstance() {
18
22
  McpAppAdaptor.instance = null;
19
23
  }
20
- getExternalStore(key) {
24
+ getHostContextStore(key) {
21
25
  return this.stores[key];
22
26
  }
23
27
  callTool = async (name, args) => {
@@ -75,19 +79,19 @@ export class McpAppAdaptor {
75
79
  }
76
80
  initializeStores() {
77
81
  return {
78
- theme: this.createExternalStore(["theme"], ({ theme }) => theme ?? "light"),
79
- locale: this.createExternalStore(["locale"], ({ locale }) => locale ?? "en-US"),
80
- safeArea: this.createExternalStore(["safeAreaInsets"], ({ safeAreaInsets }) => ({
82
+ theme: this.createHostContextStore(["theme"], ({ theme }) => theme ?? "light"),
83
+ locale: this.createHostContextStore(["locale"], ({ locale }) => locale ?? "en-US"),
84
+ safeArea: this.createHostContextStore(["safeAreaInsets"], ({ safeAreaInsets }) => ({
81
85
  insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },
82
86
  })),
83
- displayMode: this.createExternalStore(["displayMode"], ({ displayMode }) => displayMode ?? "inline"),
84
- maxHeight: this.createExternalStore(["containerDimensions"], ({ containerDimensions }) => {
87
+ displayMode: this.createHostContextStore(["displayMode"], ({ displayMode }) => displayMode ?? "inline"),
88
+ maxHeight: this.createHostContextStore(["containerDimensions"], ({ containerDimensions }) => {
85
89
  if (containerDimensions && "maxHeight" in containerDimensions) {
86
- return containerDimensions.maxHeight ?? window.innerHeight;
90
+ return containerDimensions.maxHeight;
87
91
  }
88
- return window.innerHeight;
92
+ return undefined;
89
93
  }),
90
- userAgent: this.createExternalStore(["platform", "deviceCapabilities"], ({ platform, deviceCapabilities }) => ({
94
+ userAgent: this.createHostContextStore(["platform", "deviceCapabilities"], ({ platform, deviceCapabilities }) => ({
91
95
  device: {
92
96
  type: platform === "web" ? "desktop" : (platform ?? "unknown"),
93
97
  },
@@ -97,9 +101,18 @@ export class McpAppAdaptor {
97
101
  ...deviceCapabilities,
98
102
  },
99
103
  })),
100
- toolInput: this.createExternalStore(["toolInput"], ({ toolInput }) => toolInput ?? null),
101
- toolOutput: this.createExternalStore(["toolResult"], ({ toolResult }) => toolResult?.structuredContent ?? null),
102
- toolResponseMetadata: this.createExternalStore(["toolResult"], ({ toolResult }) => toolResult?._meta ?? null),
104
+ toolInput: this.createHostContextStore(["toolInput"], ({ toolInput }) => toolInput ?? null),
105
+ toolOutput: this.createHostContextStore(["toolResult"], ({ toolResult }) => toolResult?.structuredContent ?? null),
106
+ toolResponseMetadata: this.createHostContextStore(["toolResult"], ({ toolResult }) => toolResult?._meta ?? null),
107
+ view: {
108
+ subscribe: (onChange) => {
109
+ this.viewListeners.add(onChange);
110
+ return () => {
111
+ this.viewListeners.delete(onChange);
112
+ };
113
+ },
114
+ getSnapshot: () => this._viewState,
115
+ },
103
116
  widgetState: {
104
117
  subscribe: (onChange) => {
105
118
  this.widgetStateListeners.add(onChange);
@@ -115,17 +128,49 @@ export class McpAppAdaptor {
115
128
  const newState = typeof stateOrUpdater === "function"
116
129
  ? stateOrUpdater(this._widgetState)
117
130
  : stateOrUpdater;
131
+ // must happen before the async bridge call to ensure the state is updated immediately for the UI,
132
+ // otherwise successive calls to setWidgetState may have stale state
133
+ this._widgetState = newState;
134
+ this.widgetStateListeners.forEach((listener) => {
135
+ listener();
136
+ });
118
137
  const bridge = McpAppBridge.getInstance();
119
138
  await bridge.request({
120
139
  method: "ui/update-model-context",
121
- params: { structuredContent: newState },
140
+ params: {
141
+ structuredContent: newState,
142
+ content: [{ type: "text", text: JSON.stringify(newState) }],
143
+ },
122
144
  });
123
- this._widgetState = newState;
124
- this.widgetStateListeners.forEach((listener) => {
145
+ };
146
+ /**
147
+ * @throws File upload is not supported in MCP App.
148
+ */
149
+ uploadFile() {
150
+ throw new Error("File upload is not supported in MCP App.");
151
+ }
152
+ /**
153
+ * @throws File download is not supported in MCP App.
154
+ */
155
+ getFileDownloadUrl() {
156
+ throw new Error("File download is not supported in MCP App.");
157
+ }
158
+ openModal(options) {
159
+ this._viewState = { mode: "modal", params: options.params };
160
+ this.viewListeners.forEach((listener) => {
125
161
  listener();
126
162
  });
127
- };
128
- createExternalStore(keys, computeSnapshot) {
163
+ }
164
+ closeModal() {
165
+ this._viewState = { mode: "inline" };
166
+ this.viewListeners.forEach((listener) => {
167
+ listener();
168
+ });
169
+ }
170
+ setOpenInAppUrl(_href) {
171
+ throw new Error("setOpenInAppUrl is not implemented in MCP App.");
172
+ }
173
+ createHostContextStore(keys, computeSnapshot) {
129
174
  const bridge = McpAppBridge.getInstance();
130
175
  let cachedValue;
131
176
  return {
@@ -142,4 +187,4 @@ export class McpAppAdaptor {
142
187
  };
143
188
  }
144
189
  }
145
- //# sourceMappingURL=mcp-app-adaptor.js.map
190
+ //# sourceMappingURL=adaptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adaptor.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/adaptor.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,10 @@
1
- import type { McpUiHostContext, McpUiInitializeRequest, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
2
- import type { Bridge, Subscribe } from "./types.js";
1
+ import type { McpUiHostContext, McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
2
+ import type { Bridge, Subscribe } from "../types.js";
3
+ import type { McpAppContext, McpAppContextKey } from "./types.js";
3
4
  type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
4
- export type McpToolState = {
5
- toolInput: NonNullable<McpUiToolInputNotification["params"]["arguments"]> | null;
6
- toolResult: McpUiToolResultNotification["params"] | null;
7
- toolCancelled: McpUiToolCancelledNotification["params"] | null;
8
- };
9
- export type McpAppBridgeContext = McpUiHostContext & McpToolState;
10
- export type McpAppBridgeKey = keyof McpAppBridgeContext;
11
5
  export declare class McpAppBridge implements Bridge<McpUiHostContext> {
12
6
  private static instance;
13
- context: McpAppBridgeContext;
7
+ context: McpAppContext;
14
8
  private listeners;
15
9
  private pendingRequests;
16
10
  private nextId;
@@ -20,9 +14,9 @@ export declare class McpAppBridge implements Bridge<McpUiHostContext> {
20
14
  private cleanupSizeObserver;
21
15
  constructor(options: McpAppInitializationOptions, requestTimeout?: number);
22
16
  static getInstance(options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppBridge;
23
- subscribe(key: McpAppBridgeKey): Subscribe;
24
- subscribe(keys: readonly McpAppBridgeKey[]): Subscribe;
25
- getSnapshot<K extends keyof McpAppBridgeContext>(key: K): McpAppBridgeContext[K];
17
+ subscribe(key: McpAppContextKey): Subscribe;
18
+ subscribe(keys: readonly McpAppContextKey[]): Subscribe;
19
+ getSnapshot<K extends keyof McpAppContext>(key: K): McpAppContext[K];
26
20
  cleanup: () => void;
27
21
  static resetInstance(): void;
28
22
  request<R extends {
@@ -146,6 +146,11 @@ export class McpAppBridge {
146
146
  case "ui/notifications/host-context-changed":
147
147
  this.updateContext(notification.params);
148
148
  return;
149
+ case "ui/notifications/tool-input-partial":
150
+ this.updateContext({
151
+ toolInput: notification.params.arguments ?? {},
152
+ });
153
+ return;
149
154
  case "ui/notifications/tool-input":
150
155
  this.updateContext({
151
156
  toolInput: notification.params.arguments ?? {},
@@ -220,23 +225,22 @@ export class McpAppBridge {
220
225
  scheduled = true;
221
226
  requestAnimationFrame(() => {
222
227
  scheduled = false;
223
- const html = document.documentElement;
224
- // Measure actual content size by temporarily setting html to fit-content.
225
- // This shrinks html to fit body (including body margins), giving us the
226
- // true minimum size needed by the content.
227
- const originalWidth = html.style.width;
228
- const originalHeight = html.style.height;
229
- html.style.width = "fit-content";
230
- html.style.height = "fit-content";
231
- const rect = html.getBoundingClientRect();
232
- html.style.width = originalWidth;
233
- html.style.height = originalHeight;
234
- // Compensate for scrollbar width on Linux/Windows where scrollbars
235
- // consume space. On systems with overlay scrollbars (macOS), this
236
- // will be 0.
237
- const scrollbarWidth = window.innerWidth - html.clientWidth;
238
- const width = Math.ceil(rect.width + scrollbarWidth);
239
- const height = Math.ceil(rect.height);
228
+ let width;
229
+ let height;
230
+ // In fullscreen mode, use viewport size since the widget should fill
231
+ // the entire available space provided by the host.
232
+ if (this.context.displayMode === "fullscreen") {
233
+ width = window.innerWidth;
234
+ height = window.innerHeight;
235
+ }
236
+ else {
237
+ // Use scrollWidth/scrollHeight to measure actual rendered content size.
238
+ // This works better than fit-content for viewport-based layouts (vw/vh)
239
+ // and fluid elements like maps that want to fill available space.
240
+ const body = document.body;
241
+ width = Math.ceil(body.scrollWidth);
242
+ height = Math.ceil(body.scrollHeight);
243
+ }
240
244
  // Only send if size actually changed (prevents feedback loops from
241
245
  // style changes)
242
246
  if (width !== lastWidth || height !== lastHeight) {
@@ -253,4 +257,4 @@ export class McpAppBridge {
253
257
  return () => resizeObserver.disconnect();
254
258
  }
255
259
  }
256
- //# sourceMappingURL=mcp-app-bridge.js.map
260
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { McpAppAdaptor } from "./adaptor.js";
2
+ export { McpAppBridge } from "./bridge.js";
3
+ export type { McpAppContext, McpAppContextKey, McpToolState, } from "./types.js";
4
+ export { useMcpAppContext } from "./use-mcp-app-context.js";
@@ -0,0 +1,4 @@
1
+ export { McpAppAdaptor } from "./adaptor.js";
2
+ export { McpAppBridge } from "./bridge.js";
3
+ export { useMcpAppContext } from "./use-mcp-app-context.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { McpUiHostContext, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
2
+ export type McpToolState = {
3
+ toolInput: NonNullable<McpUiToolInputNotification["params"]["arguments"]> | null;
4
+ toolResult: McpUiToolResultNotification["params"] | null;
5
+ toolCancelled: McpUiToolCancelledNotification["params"] | null;
6
+ };
7
+ export type McpAppContext = McpUiHostContext & McpToolState;
8
+ export type McpAppContextKey = keyof McpAppContext;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
2
+ import type { McpAppContext } from "./types.js";
3
+ type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
4
+ export declare function useMcpAppContext<K extends keyof McpAppContext>(key: K, options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppContext[K];
5
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { useSyncExternalStore } from "react";
2
- import { McpAppBridge } from "../mcp-app-bridge.js";
3
- export function useMcpAppBridge(key, options, requestTimeout) {
2
+ import { McpAppBridge } from "./bridge.js";
3
+ export function useMcpAppContext(key, options, requestTimeout) {
4
4
  const bridge = McpAppBridge.getInstance(options, requestTimeout);
5
5
  return useSyncExternalStore(bridge.subscribe(key), () => bridge.getSnapshot(key));
6
6
  }
7
- //# sourceMappingURL=use-mcp-app-bridge.js.map
7
+ //# sourceMappingURL=use-mcp-app-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mcp-app-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,OAA8C,EAC9C,cAAuB;IAEvB,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACjE,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import { act, renderHook, waitFor } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { getMcpAppHostPostMessageMock, MockResizeObserver, } from "../../hooks/test/utils.js";
4
- import { McpAppBridge } from "../mcp-app-bridge.js";
5
- import { useMcpAppBridge } from "./use-mcp-app-bridge.js";
6
- describe("useMcpAppBridge", () => {
4
+ import { McpAppBridge } from "./bridge.js";
5
+ import { useMcpAppContext } from "./use-mcp-app-context.js";
6
+ describe("useMcpAppContext", () => {
7
7
  beforeEach(async () => {
8
8
  vi.stubGlobal("skybridge", { hostType: "mcp-app" });
9
9
  vi.stubGlobal("ResizeObserver", MockResizeObserver);
@@ -17,7 +17,7 @@ describe("useMcpAppBridge", () => {
17
17
  vi.stubGlobal("parent", {
18
18
  postMessage: getMcpAppHostPostMessageMock({ theme: "light" }),
19
19
  });
20
- const { result } = renderHook(() => useMcpAppBridge("theme"));
20
+ const { result } = renderHook(() => useMcpAppContext("theme"));
21
21
  await waitFor(() => {
22
22
  expect(result.current).toBe("light");
23
23
  });
@@ -29,7 +29,7 @@ describe("useMcpAppBridge", () => {
29
29
  .mockImplementation(() => { });
30
30
  const nonRespondingMock = vi.fn();
31
31
  vi.stubGlobal("parent", { postMessage: nonRespondingMock });
32
- renderHook(() => useMcpAppBridge("theme", undefined, 100));
32
+ renderHook(() => useMcpAppContext("theme", undefined, 100));
33
33
  expect(nonRespondingMock).toHaveBeenCalledWith(expect.objectContaining({ method: "ui/initialize" }), "*");
34
34
  await act(async () => {
35
35
  await vi.advanceTimersByTimeAsync(100);
@@ -39,9 +39,18 @@ describe("useMcpAppBridge", () => {
39
39
  vi.useRealTimers();
40
40
  });
41
41
  it("should send size-changed notification after successful initialization", async () => {
42
+ // Mock body dimensions to non-zero (size-changed only sends when dimensions change)
43
+ Object.defineProperty(document.body, "scrollWidth", {
44
+ value: 800,
45
+ configurable: true,
46
+ });
47
+ Object.defineProperty(document.body, "scrollHeight", {
48
+ value: 600,
49
+ configurable: true,
50
+ });
42
51
  const postMessageMock = getMcpAppHostPostMessageMock({ theme: "light" });
43
52
  vi.stubGlobal("parent", { postMessage: postMessageMock });
44
- renderHook(() => useMcpAppBridge("theme"));
53
+ renderHook(() => useMcpAppContext("theme"));
45
54
  await waitFor(() => {
46
55
  expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
47
56
  jsonrpc: "2.0",
@@ -54,4 +63,4 @@ describe("useMcpAppBridge", () => {
54
63
  });
55
64
  });
56
65
  });
57
- //# sourceMappingURL=use-mcp-app-bridge.test.js.map
66
+ //# sourceMappingURL=use-mcp-app-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mcp-app-context.test.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,15 @@
1
1
  import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
2
  import type { useSyncExternalStore } from "react";
3
+ import type { WidgetHostType } from "../../server/index.js";
4
+ export type SkybridgeProperties = {
5
+ hostType: WidgetHostType;
6
+ serverUrl: string;
7
+ };
8
+ declare global {
9
+ interface Window {
10
+ skybridge: SkybridgeProperties;
11
+ }
12
+ }
3
13
  export type CallToolArgs = Record<string, unknown> | null;
4
14
  export type CallToolResponse = {
5
15
  content: CallToolResult["content"];
@@ -9,32 +19,40 @@ export type CallToolResponse = {
9
19
  meta?: CallToolResult["_meta"];
10
20
  };
11
21
  export type DisplayMode = "pip" | "inline" | "fullscreen" | "modal";
22
+ export type Theme = "light" | "dark";
12
23
  export type DeviceType = "mobile" | "tablet" | "desktop" | "unknown";
13
- export interface BridgeInterface {
14
- theme: "light" | "dark";
15
- locale: string;
16
- displayMode: DisplayMode;
17
- safeArea: {
18
- insets: {
19
- top: number;
20
- right: number;
21
- bottom: number;
22
- left: number;
23
- };
24
+ export type SafeAreaInsets = {
25
+ top: number;
26
+ right: number;
27
+ bottom: number;
28
+ left: number;
29
+ };
30
+ export type SafeArea = {
31
+ insets: SafeAreaInsets;
32
+ };
33
+ export type UserAgent = {
34
+ device: {
35
+ type: DeviceType;
24
36
  };
25
- maxHeight: number;
26
- userAgent: {
27
- device: {
28
- type: DeviceType;
29
- };
30
- capabilities: {
31
- hover: boolean;
32
- touch: boolean;
33
- };
37
+ capabilities: {
38
+ hover: boolean;
39
+ touch: boolean;
34
40
  };
41
+ };
42
+ export interface HostContext {
43
+ theme: Theme;
44
+ locale: string;
45
+ displayMode: DisplayMode;
46
+ safeArea: SafeArea;
47
+ maxHeight: number | undefined;
48
+ userAgent: UserAgent;
35
49
  toolInput: Record<string, unknown> | null;
36
50
  toolOutput: Record<string, unknown> | null;
37
51
  toolResponseMetadata: Record<string, unknown> | null;
52
+ view: {
53
+ mode: DisplayMode;
54
+ params?: Record<string, unknown>;
55
+ };
38
56
  widgetState: Record<string, unknown> | null;
39
57
  }
40
58
  export type Subscribe = Parameters<typeof useSyncExternalStore>[0];
@@ -43,14 +61,27 @@ export interface Bridge<Context> {
43
61
  subscribe(keys: readonly (keyof Context)[]): Subscribe;
44
62
  getSnapshot<K extends keyof Context>(key: K): Context[K] | undefined;
45
63
  }
46
- export type ExternalStore<K extends keyof BridgeInterface> = {
64
+ export type HostContextStore<K extends keyof HostContext> = {
47
65
  subscribe: Subscribe;
48
- getSnapshot: () => BridgeInterface[K];
66
+ getSnapshot: () => HostContext[K];
49
67
  };
50
68
  export type WidgetState = Record<string, unknown>;
51
69
  export type SetWidgetStateAction = WidgetState | ((prevState: WidgetState | null) => WidgetState);
70
+ export type FileMetadata = {
71
+ fileId: string;
72
+ };
73
+ export type RequestModalOptions = {
74
+ title?: string;
75
+ params?: Record<string, unknown>;
76
+ anchor?: {
77
+ top?: number;
78
+ left?: number;
79
+ width?: number;
80
+ height?: number;
81
+ };
82
+ };
52
83
  export interface Adaptor {
53
- getExternalStore<K extends keyof BridgeInterface>(key: K): ExternalStore<K>;
84
+ getHostContextStore<K extends keyof HostContext>(key: K): HostContextStore<K>;
54
85
  callTool<ToolArgs extends CallToolArgs = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs): Promise<ToolResponse>;
55
86
  requestDisplayMode(mode: DisplayMode): Promise<{
56
87
  mode: DisplayMode;
@@ -58,4 +89,10 @@ export interface Adaptor {
58
89
  sendFollowUpMessage(prompt: string): Promise<void>;
59
90
  openExternal(href: string): void;
60
91
  setWidgetState(stateOrUpdater: SetWidgetStateAction): Promise<void>;
92
+ uploadFile(file: File): Promise<FileMetadata>;
93
+ getFileDownloadUrl(file: FileMetadata): Promise<{
94
+ downloadUrl: string;
95
+ }>;
96
+ openModal(options: RequestModalOptions): void;
97
+ setOpenInAppUrl(href: string): Promise<void>;
61
98
  }
@@ -0,0 +1,2 @@
1
+ import type { HostContext } from "./types.js";
2
+ export declare const useHostContext: <K extends keyof HostContext>(key: K) => HostContext[K];
@@ -0,0 +1,8 @@
1
+ import { useSyncExternalStore } from "react";
2
+ import { getAdaptor } from "./get-adaptor.js";
3
+ export const useHostContext = (key) => {
4
+ const adaptor = getAdaptor();
5
+ const store = adaptor.getHostContextStore(key);
6
+ return useSyncExternalStore(store.subscribe, store.getSnapshot);
7
+ };
8
+ //# sourceMappingURL=use-host-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-host-context.js","sourceRoot":"","sources":["../../../src/web/bridges/use-host-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,GAAM,EACU,EAAE;IAClB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAE/C,OAAO,oBAAoB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;AAClE,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ReactNode } from "react";
2
+ export declare function ModalProvider({ children }: {
3
+ children: ReactNode;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useSyncExternalStore } from "react";
3
+ import { McpAppAdaptor } from "../bridges";
4
+ const modalStyles = `
5
+ .sb-modal-backdrop {
6
+ position: fixed;
7
+ inset: 0;
8
+ background: rgba(0, 0, 0, 0.5);
9
+ z-index: 9998;
10
+ }
11
+ .sb-modal-container {
12
+ border-radius: 12px;
13
+ position: fixed;
14
+ inset: 0;
15
+ margin: auto;
16
+ width: fit-content;
17
+ height: fit-content;
18
+ background: white;
19
+ z-index: 9999;
20
+ }
21
+ `;
22
+ export function ModalProvider({ children }) {
23
+ const adaptor = McpAppAdaptor.getInstance();
24
+ const { mode } = useSyncExternalStore(adaptor.getHostContextStore("view").subscribe, adaptor.getHostContextStore("view").getSnapshot);
25
+ const isOpen = mode === "modal";
26
+ const handleBackdropClick = (e) => {
27
+ if (e.target === e.currentTarget) {
28
+ adaptor.closeModal();
29
+ }
30
+ };
31
+ useEffect(() => {
32
+ if (!isOpen) {
33
+ return;
34
+ }
35
+ const handler = (e) => {
36
+ if (e.key === "Escape") {
37
+ adaptor.closeModal();
38
+ }
39
+ };
40
+ document.addEventListener("keydown", handler);
41
+ return () => document.removeEventListener("keydown", handler);
42
+ }, [isOpen, adaptor]);
43
+ return (_jsxs(_Fragment, { children: [_jsx("style", { children: modalStyles }), isOpen && (
44
+ // biome-ignore lint/a11y/useKeyWithClickEvents: backdrop isn't focusable
45
+ _jsx("div", { role: "dialog", className: "sb-modal-backdrop", onClick: handleBackdropClick })), _jsx("div", { className: isOpen ? "sb-modal-container" : undefined, children: children })] }));
46
+ }
47
+ //# sourceMappingURL=modal-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-provider.js","sourceRoot":"","sources":["../../../src/web/components/modal-provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,SAAS,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;CAiBnB,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAAE,QAAQ,EAA2B;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAE5C,MAAM,EAAE,IAAI,EAAE,GAAG,oBAAoB,CACnC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,SAAS,EAC7C,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,WAAW,CAChD,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC;IAEhC,MAAM,mBAAmB,GAAG,CAAC,CAAmB,EAAE,EAAE;QAClD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAgB,EAAE,EAAE;YACnC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACvB,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAEtB,OAAO,CACL,8BACE,0BAAQ,WAAW,GAAS,EAC3B,MAAM,IAAI;YACT,yEAAyE;YACzE,cACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,mBAAmB,EAC7B,OAAO,EAAE,mBAAmB,GAC5B,CACH,EACD,cAAK,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,YACtD,QAAQ,GACL,IACL,CACJ,CAAC;AACJ,CAAC"}