skybridge 0.0.0-dev.cb16b5e → 0.0.0-dev.cbadf52

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 (64) hide show
  1. package/dist/src/server/templates/development.hbs +1 -1
  2. package/dist/src/server/templates/production.hbs +1 -1
  3. package/dist/src/web/bridges/apps-sdk-adapter.d.ts +13 -2
  4. package/dist/src/web/bridges/apps-sdk-adapter.js +32 -3
  5. package/dist/src/web/bridges/apps-sdk-adapter.js.map +1 -1
  6. package/dist/src/web/bridges/apps-sdk-bridge.d.ts +4 -2
  7. package/dist/src/web/bridges/apps-sdk-bridge.js +19 -14
  8. package/dist/src/web/bridges/apps-sdk-bridge.js.map +1 -1
  9. package/dist/src/web/bridges/get-bridge-method.d.ts +2 -0
  10. package/dist/src/web/bridges/get-bridge-method.js +9 -0
  11. package/dist/src/web/bridges/get-bridge-method.js.map +1 -0
  12. package/dist/src/web/bridges/hooks/use-bridge.d.ts +2 -2
  13. package/dist/src/web/bridges/hooks/use-bridge.js +7 -85
  14. package/dist/src/web/bridges/hooks/use-bridge.js.map +1 -1
  15. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.d.ts +3 -2
  16. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js +1 -1
  17. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js.map +1 -1
  18. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js +10 -26
  19. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js.map +1 -1
  20. package/dist/src/web/bridges/index.d.ts +1 -1
  21. package/dist/src/web/bridges/index.js +1 -1
  22. package/dist/src/web/bridges/index.js.map +1 -1
  23. package/dist/src/web/bridges/mcp-app-adapter.d.ts +16 -2
  24. package/dist/src/web/bridges/mcp-app-adapter.js +108 -9
  25. package/dist/src/web/bridges/mcp-app-adapter.js.map +1 -1
  26. package/dist/src/web/bridges/mcp-app-bridge.d.ts +15 -6
  27. package/dist/src/web/bridges/mcp-app-bridge.js +58 -26
  28. package/dist/src/web/bridges/mcp-app-bridge.js.map +1 -1
  29. package/dist/src/web/bridges/types.d.ts +30 -3
  30. package/dist/src/web/data-llm.js +4 -2
  31. package/dist/src/web/data-llm.js.map +1 -1
  32. package/dist/src/web/generate-helpers.test-d.js +4 -1
  33. package/dist/src/web/generate-helpers.test-d.js.map +1 -1
  34. package/dist/src/web/hooks/test/utils.d.ts +11 -0
  35. package/dist/src/web/hooks/test/utils.js +48 -0
  36. package/dist/src/web/hooks/test/utils.js.map +1 -0
  37. package/dist/src/web/hooks/use-call-tool.js +12 -4
  38. package/dist/src/web/hooks/use-call-tool.js.map +1 -1
  39. package/dist/src/web/hooks/use-call-tool.test.js +26 -0
  40. package/dist/src/web/hooks/use-call-tool.test.js.map +1 -1
  41. package/dist/src/web/hooks/use-display-mode.d.ts +1 -2
  42. package/dist/src/web/hooks/use-display-mode.js +2 -4
  43. package/dist/src/web/hooks/use-display-mode.js.map +1 -1
  44. package/dist/src/web/hooks/use-layout.test.js +84 -38
  45. package/dist/src/web/hooks/use-layout.test.js.map +1 -1
  46. package/dist/src/web/hooks/use-send-follow-up-message.js +2 -8
  47. package/dist/src/web/hooks/use-send-follow-up-message.js.map +1 -1
  48. package/dist/src/web/hooks/use-tool-info.d.ts +12 -1
  49. package/dist/src/web/hooks/use-tool-info.js +15 -9
  50. package/dist/src/web/hooks/use-tool-info.js.map +1 -1
  51. package/dist/src/web/hooks/use-tool-info.test-d.js +40 -4
  52. package/dist/src/web/hooks/use-tool-info.test-d.js.map +1 -1
  53. package/dist/src/web/hooks/use-tool-info.test.js +118 -47
  54. package/dist/src/web/hooks/use-tool-info.test.js.map +1 -1
  55. package/dist/src/web/hooks/use-user.test.js +84 -34
  56. package/dist/src/web/hooks/use-user.test.js.map +1 -1
  57. package/dist/src/web/plugin/transform-data-llm.js +6 -3
  58. package/dist/src/web/plugin/transform-data-llm.js.map +1 -1
  59. package/dist/src/web/types.d.ts +2 -4
  60. package/dist/src/web/types.js.map +1 -1
  61. package/package.json +6 -1
  62. package/dist/src/web/bridges/get-bridge-methods.d.ts +0 -2
  63. package/dist/src/web/bridges/get-bridge-methods.js +0 -8
  64. package/dist/src/web/bridges/get-bridge-methods.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  <base href="{{serverUrl}}" />
2
- <script> window.skybridge = { hostType: "{{hostType}}" }; </script>
2
+ <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
3
3
  <script type="module">
4
4
  import { injectIntoGlobalHook } from "{{serverUrl}}/@react-refresh";
5
5
  injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};
@@ -1,5 +1,5 @@
1
1
  <base href="{{serverUrl}}" />
2
- <script> window.skybridge = { hostType: "{{hostType}}" }; </script>
2
+ <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
3
3
  <div id="root"></div>
4
4
  <script type="module">
5
5
  import('{{serverUrl}}/assets/{{widgetFile}}');
@@ -1,2 +1,13 @@
1
- import type { Methods } from "./types";
2
- export declare const requestDisplayMode: Methods["requestDisplayMode"];
1
+ import type { Adapter, BridgeInterface, CallToolResponse, DisplayMode, ExternalStore, Methods } from "./types.js";
2
+ export declare class AppsSdkAdapter implements Adapter {
3
+ private static instance;
4
+ static getInstance(): AppsSdkAdapter;
5
+ static resetInstance(): void;
6
+ getExternalStore<K extends keyof BridgeInterface>(key: K): ExternalStore<K>;
7
+ callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
8
+ requestDisplayMode: (mode: DisplayMode) => Promise<{
9
+ mode: DisplayMode;
10
+ }>;
11
+ sendFollowUpMessage: (prompt: string) => Promise<void>;
12
+ getMethod<K extends keyof Methods>(key: K): this[K];
13
+ }
@@ -1,4 +1,33 @@
1
- export const requestDisplayMode = ({ mode }) => {
2
- return window.openai.requestDisplayMode({ mode });
3
- };
1
+ import { AppsSdkBridge } from "./apps-sdk-bridge.js";
2
+ export class AppsSdkAdapter {
3
+ static instance = null;
4
+ static getInstance() {
5
+ if (!AppsSdkAdapter.instance) {
6
+ AppsSdkAdapter.instance = new AppsSdkAdapter();
7
+ }
8
+ return AppsSdkAdapter.instance;
9
+ }
10
+ static resetInstance() {
11
+ AppsSdkAdapter.instance = null;
12
+ }
13
+ getExternalStore(key) {
14
+ const bridge = AppsSdkBridge.getInstance();
15
+ return {
16
+ subscribe: bridge.subscribe(key),
17
+ getSnapshot: () => bridge.getSnapshot(key),
18
+ };
19
+ }
20
+ callTool = async (name, args) => {
21
+ return window.openai.callTool(name, args);
22
+ };
23
+ requestDisplayMode = (mode) => {
24
+ return window.openai.requestDisplayMode({ mode });
25
+ };
26
+ sendFollowUpMessage = (prompt) => {
27
+ return window.openai.sendFollowUpMessage({ prompt });
28
+ };
29
+ getMethod(key) {
30
+ return this[key];
31
+ }
32
+ }
4
33
  //# sourceMappingURL=apps-sdk-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apps-sdk-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-adapter.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAkC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;IAC5E,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC"}
1
+ {"version":3,"file":"apps-sdk-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAUrD,MAAM,OAAO,cAAc;IACjB,MAAM,CAAC,QAAQ,GAA0B,IAAI,CAAC;IAE/C,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,cAAc,CAAC,QAAQ,CAAC;IACjC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,cAAc,CAAC,QAAQ,GAAG,IAAI,CAAC;IACjC,CAAC;IAEM,gBAAgB,CACrB,GAAM;QAEN,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;YAChC,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;SAC3C,CAAC;IACJ,CAAC;IAEM,QAAQ,GAAG,KAAK,EAIrB,IAAY,EACZ,IAAc,EACS,EAAE;QACzB,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAyB,IAAI,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC;IAEK,kBAAkB,GAAG,CAC1B,IAAiB,EACe,EAAE;QAClC,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;IAEK,mBAAmB,GAAG,CAAC,MAAc,EAAiB,EAAE;QAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC;IAEK,SAAS,CAA0B,GAAM;QAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { type OpenAiProperties } from "../types.js";
2
- export declare class AppsSdkBridge {
2
+ import type { Bridge, Subscribe } from "./types.js";
3
+ export declare class AppsSdkBridge implements Bridge<OpenAiProperties> {
3
4
  private static instance;
4
5
  static getInstance(): AppsSdkBridge;
5
6
  static resetInstance(): void;
6
- subscribe: (key: keyof OpenAiProperties) => (onChange: () => void) => () => void;
7
+ subscribe(key: keyof OpenAiProperties): Subscribe;
8
+ subscribe(keys: readonly (keyof OpenAiProperties)[]): Subscribe;
7
9
  getSnapshot: <K extends keyof OpenAiProperties>(key: K) => (import("../types.js").OpenAiMethods<import("../types.js").UnknownObject> & OpenAiProperties<Record<never, unknown>, import("../types.js").UnknownObject, import("../types.js").UnknownObject, import("../types.js").UnknownObject>)[K];
8
10
  }
@@ -16,21 +16,26 @@ export class AppsSdkBridge {
16
16
  AppsSdkBridge.instance = null;
17
17
  }
18
18
  }
19
- subscribe = (key) => (onChange) => {
20
- const handleSetGlobal = (event) => {
21
- const value = event.detail.globals[key];
22
- if (value === undefined) {
23
- return;
24
- }
25
- onChange();
19
+ subscribe(keyOrKeys) {
20
+ const keys = Array.isArray(keyOrKeys)
21
+ ? keyOrKeys
22
+ : [keyOrKeys];
23
+ return (onChange) => {
24
+ const handleSetGlobal = (event) => {
25
+ const hasRelevantChange = keys.some((key) => event.detail.globals[key] !== undefined);
26
+ if (!hasRelevantChange) {
27
+ return;
28
+ }
29
+ onChange();
30
+ };
31
+ window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal, {
32
+ passive: true,
33
+ });
34
+ return () => {
35
+ window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);
36
+ };
26
37
  };
27
- window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal, {
28
- passive: true,
29
- });
30
- return () => {
31
- window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);
32
- };
33
- };
38
+ }
34
39
  getSnapshot = (key) => {
35
40
  if (window.openai === undefined) {
36
41
  throw new Error(`window.openai is not available. Make sure you're calling the hook requiring ${key} within the OpenAI iFrame skybridge runtime.`);
@@ -1 +1 @@
1
- {"version":3,"file":"apps-sdk-bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,GAEvB,MAAM,aAAa,CAAC;AAErB,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAE9C,MAAM,CAAC,WAAW;QACvB,IACE,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU;YACxC,MAAM,CAAC,MAAM,KAAK,SAAS,EAC3B,CAAC;YACD,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;QACJ,CAAC;QACD,IAAI,aAAa,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpC,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAEM,SAAS,GACd,CAAC,GAA2B,EAAE,EAAE,CAAC,CAAC,QAAoB,EAAE,EAAE;QACxD,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAE,EAAE;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YAED,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,eAAe,EAAE;YAC/D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;QACtE,CAAC,CAAC;IACJ,CAAC,CAAC;IACG,WAAW,GAAG,CAAmC,GAAM,EAAE,EAAE;QAChE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,+EAA+E,GAAG,8CAA8C,CACjI,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC"}
1
+ {"version":3,"file":"apps-sdk-bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,GAEvB,MAAM,aAAa,CAAC;AAGrB,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAE9C,MAAM,CAAC,WAAW;QACvB,IACE,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU;YACxC,MAAM,CAAC,MAAM,KAAK,SAAS,EAC3B,CAAC;YACD,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;QACJ,CAAC;QACD,IAAI,aAAa,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpC,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAIM,SAAS,CACd,SAAuE;QAEvE,MAAM,IAAI,GAAwC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YACxE,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChB,OAAO,CAAC,QAAoB,EAAE,EAAE;YAC9B,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACjC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CACjD,CAAC;gBACF,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACvB,OAAO;gBACT,CAAC;gBACD,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,eAAe,EAAE;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YAEH,OAAO,GAAG,EAAE;gBACV,MAAM,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;YACtE,CAAC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAEM,WAAW,GAAG,CAAmC,GAAM,EAAE,EAAE;QAChE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,+EAA+E,GAAG,8CAA8C,CACjI,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Methods } from "./types.js";
2
+ export declare const getBridgeMethod: <K extends keyof Methods>(key: K) => Methods[K];
@@ -0,0 +1,9 @@
1
+ import { AppsSdkAdapter } from "./apps-sdk-adapter.js";
2
+ import { McpAppAdapter } from "./mcp-app-adapter.js";
3
+ export const getBridgeMethod = (key) => {
4
+ const adapter = window.skybridge.hostType === "apps-sdk"
5
+ ? AppsSdkAdapter.getInstance()
6
+ : McpAppAdapter.getInstance();
7
+ return adapter.getMethod(key);
8
+ };
9
+ //# sourceMappingURL=get-bridge-method.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-bridge-method.js","sourceRoot":"","sources":["../../../../src/web/bridges/get-bridge-method.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,GAAM,EACM,EAAE;IACd,MAAM,OAAO,GACX,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU;QACtC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE;QAC9B,CAAC,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;IAElC,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
- import type { BridgeInterface } from "../types";
2
- export declare const useBridge: <K extends keyof BridgeInterface>(key: K, defaultValue?: BridgeInterface[K]) => BridgeInterface[K];
1
+ import type { BridgeInterface } from "../types.js";
2
+ export declare const useBridge: <K extends keyof BridgeInterface>(key: K) => BridgeInterface[K];
@@ -1,93 +1,15 @@
1
1
  import { useSyncExternalStore } from "react";
2
- import { AppsSdkBridge } from "../apps-sdk-bridge";
3
- import { McpAppBridge } from "../mcp-app-bridge";
4
- const DEFAULT_VALUE_FOR_MCP_APP_BRIDGE = {
5
- theme: "light",
6
- locale: "en-US",
7
- displayMode: "inline",
8
- safeArea: {
9
- insets: {
10
- top: 0,
11
- right: 0,
12
- bottom: 0,
13
- left: 0,
14
- },
15
- },
16
- maxHeight: window.innerHeight,
17
- userAgent: {
18
- device: {
19
- type: "unknown",
20
- },
21
- capabilities: {
22
- hover: false,
23
- touch: false,
24
- },
25
- },
26
- };
27
- const getExternalStore = (key, defaultValue = DEFAULT_VALUE_FOR_MCP_APP_BRIDGE[key]) => {
2
+ import { AppsSdkAdapter } from "../apps-sdk-adapter.js";
3
+ import { McpAppAdapter } from "../mcp-app-adapter.js";
4
+ const getExternalStore = (key) => {
28
5
  const hostType = window.skybridge.hostType;
29
6
  if (hostType === "apps-sdk") {
30
- const bridge = AppsSdkBridge.getInstance();
31
- return {
32
- subscribe: bridge.subscribe(key),
33
- getSnapshot: () => bridge.getSnapshot(key),
34
- };
35
- }
36
- const bridge = McpAppBridge.getInstance();
37
- if (key === "safeArea") {
38
- return {
39
- subscribe: bridge.subscribe("safeAreaInsets"),
40
- getSnapshot: () => {
41
- const safeArea = bridge.getSnapshot("safeAreaInsets");
42
- return safeArea
43
- ? { insets: safeArea }
44
- : defaultValue;
45
- },
46
- };
47
- }
48
- if (key === "maxHeight") {
49
- return {
50
- subscribe: bridge.subscribe("viewport"),
51
- getSnapshot: () => {
52
- const viewport = bridge.getSnapshot("viewport");
53
- return (viewport?.maxHeight ?? defaultValue);
54
- },
55
- };
56
- }
57
- if (key === "userAgent") {
58
- return {
59
- subscribe: (onChange) => () => {
60
- bridge.subscribe("deviceCapabilities")(onChange);
61
- bridge.subscribe("platform")(onChange);
62
- },
63
- getSnapshot: () => {
64
- const userAgentDefaultValue = defaultValue;
65
- const capabilities = {
66
- ...userAgentDefaultValue.capabilities,
67
- ...(bridge.getSnapshot("deviceCapabilities") ?? {}),
68
- };
69
- const mcpAppPlatform = bridge.getSnapshot("platform");
70
- const deviceType = mcpAppPlatform
71
- ? mcpAppPlatform === "web"
72
- ? "desktop"
73
- : mcpAppPlatform
74
- : userAgentDefaultValue.device.type;
75
- return {
76
- device: {
77
- type: deviceType,
78
- },
79
- capabilities,
80
- };
81
- },
82
- };
7
+ return AppsSdkAdapter.getInstance().getExternalStore(key);
83
8
  }
84
- return {
85
- subscribe: bridge.subscribe(key),
86
- getSnapshot: () => (bridge.getSnapshot(key) ?? defaultValue),
87
- };
9
+ return McpAppAdapter.getInstance().getExternalStore(key);
88
10
  };
89
- export const useBridge = (key, defaultValue = DEFAULT_VALUE_FOR_MCP_APP_BRIDGE[key]) => {
90
- const externalStore = getExternalStore(key, defaultValue);
11
+ export const useBridge = (key) => {
12
+ const externalStore = getExternalStore(key);
91
13
  return useSyncExternalStore(externalStore.subscribe, externalStore.getSnapshot);
92
14
  };
93
15
  //# sourceMappingURL=use-bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,MAAM,gBAAgB,GAAG,CACvB,GAAM,EACY,EAAE;IACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;IAC3C,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,aAAa,CAAC,WAAW,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,GAAM,EACc,EAAE;IACtB,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,OAAO,oBAAoB,CACzB,aAAa,CAAC,SAAS,EACvB,aAAa,CAAC,WAAW,CAC1B,CAAC;AACJ,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
- import type { McpUiHostContext, McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
1
+ import type { McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
2
+ import { type McpAppBridgeContext } from "../mcp-app-bridge.js";
2
3
  type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
3
- export declare function useMcpAppBridge<K extends keyof McpUiHostContext>(key: K, options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpUiHostContext[K];
4
+ export declare function useMcpAppBridge<K extends keyof McpAppBridgeContext>(key: K, options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppBridgeContext[K];
4
5
  export {};
@@ -1,5 +1,5 @@
1
1
  import { useSyncExternalStore } from "react";
2
- import { McpAppBridge } from "../mcp-app-bridge";
2
+ import { McpAppBridge } from "../mcp-app-bridge.js";
3
3
  export function useMcpAppBridge(key, options, requestTimeout) {
4
4
  const bridge = McpAppBridge.getInstance(options, requestTimeout);
5
5
  return useSyncExternalStore(bridge.subscribe(key), () => bridge.getSnapshot(key));
@@ -1 +1 @@
1
- {"version":3,"file":"use-mcp-app-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOjD,MAAM,UAAU,eAAe,CAC7B,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
+ {"version":3,"file":"use-mcp-app-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAA4B,MAAM,sBAAsB,CAAC;AAO9E,MAAM,UAAU,eAAe,CAC7B,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,52 +1,36 @@
1
1
  import { act, renderHook, waitFor } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { fireHostContextChangedNotification, MCPAppHostPostMessageMock, } from "../../hooks/test/utils.js";
3
4
  import { McpAppBridge } from "../mcp-app-bridge.js";
4
5
  import { useMcpAppBridge } from "./use-mcp-app-bridge.js";
5
6
  describe("useMcpAppBridge", () => {
6
- let mockPostMessage;
7
7
  beforeEach(async () => {
8
- mockPostMessage = vi.fn();
9
- Object.defineProperty(window, "parent", {
10
- value: { postMessage: mockPostMessage },
11
- writable: true,
12
- configurable: true,
13
- });
8
+ vi.stubGlobal("parent", { postMessage: MCPAppHostPostMessageMock });
14
9
  vi.stubGlobal("skybridge", { hostType: "mcp-app" });
15
10
  McpAppBridge.resetInstance();
16
11
  });
17
12
  afterEach(() => {
18
13
  vi.clearAllMocks();
19
14
  });
20
- it("should return the theme value from host context", async () => {
15
+ it("should return the theme value from host context and update on notification", async () => {
21
16
  const { result } = renderHook(() => useMcpAppBridge("theme"));
22
- const initCall = mockPostMessage.mock.calls.find((call) => call[0].method === "ui/initialize");
23
- if (initCall) {
24
- act(() => {
25
- window.dispatchEvent(new MessageEvent("message", {
26
- data: {
27
- jsonrpc: "2.0",
28
- id: initCall[0].id,
29
- result: {
30
- protocolVersion: "2025-06-18",
31
- hostInfo: { name: "test-host", version: "1.0.0" },
32
- hostCapabilities: {},
33
- hostContext: { theme: "light" },
34
- },
35
- },
36
- }));
37
- });
38
- }
39
17
  await waitFor(() => {
40
18
  expect(result.current).toBe("light");
41
19
  });
20
+ fireHostContextChangedNotification({ theme: "dark" });
21
+ await waitFor(() => {
22
+ expect(result.current).toBe("dark");
23
+ });
42
24
  });
43
25
  it("should reject the request after timeout", async () => {
44
26
  vi.useFakeTimers();
45
27
  const consoleErrorSpy = vi
46
28
  .spyOn(console, "error")
47
29
  .mockImplementation(() => { });
30
+ const nonRespondingMock = vi.fn();
31
+ vi.stubGlobal("parent", { postMessage: nonRespondingMock });
48
32
  renderHook(() => useMcpAppBridge("theme", undefined, 100));
49
- expect(mockPostMessage).toHaveBeenCalledWith(expect.objectContaining({ method: "ui/initialize" }), "*");
33
+ expect(nonRespondingMock).toHaveBeenCalledWith(expect.objectContaining({ method: "ui/initialize" }), "*");
50
34
  await act(async () => {
51
35
  await vi.advanceTimersByTimeAsync(100);
52
36
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-mcp-app-bridge.test.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,eAAyC,CAAC;IAE9C,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,eAAe,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE;YACtC,KAAK,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE;YACvC,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAC9C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,CAC7C,CAAC;QAEF,IAAI,QAAQ,EAAE,CAAC;YACb,GAAG,CAAC,GAAG,EAAE;gBACP,MAAM,CAAC,aAAa,CAClB,IAAI,YAAY,CAAC,SAAS,EAAE;oBAC1B,IAAI,EAAE;wBACJ,OAAO,EAAE,KAAK;wBACd,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;wBAClB,MAAM,EAAE;4BACN,eAAe,EAAE,YAAY;4BAC7B,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;4BACjD,gBAAgB,EAAE,EAAE;4BACpB,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;yBAChC;qBACF;iBACF,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,eAAe,GAAG,EAAE;aACvB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;aACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEhC,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3D,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EACpD,GAAG,CACJ,CAAC;QAEF,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAC/B,CAAC;QAEF,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9B,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"use-mcp-app-bridge.test.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,kCAAkC,EAClC,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACpE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAE9D,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,kCAAkC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEtD,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,eAAe,GAAG,EAAE;aACvB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;aACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEhC,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE5D,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3D,MAAM,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAC5C,MAAM,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EACpD,GAAG,CACJ,CAAC;QAEF,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAC/B,CAAC;QAEF,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9B,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- export { getBridgeMethods } from "./get-bridge-methods.js";
1
+ export { getBridgeMethod } from "./get-bridge-method.js";
2
2
  export { useAppsSdkBridge } from "./hooks/use-apps-sdk-bridge.js";
3
3
  export { useBridge } from "./hooks/use-bridge.js";
4
4
  export { useMcpAppBridge } from "./hooks/use-mcp-app-bridge.js";
@@ -1,4 +1,4 @@
1
- export { getBridgeMethods } from "./get-bridge-methods.js";
1
+ export { getBridgeMethod } from "./get-bridge-method.js";
2
2
  export { useAppsSdkBridge } from "./hooks/use-apps-sdk-bridge.js";
3
3
  export { useBridge } from "./hooks/use-bridge.js";
4
4
  export { useMcpAppBridge } from "./hooks/use-mcp-app-bridge.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC"}
@@ -1,2 +1,16 @@
1
- import type { Methods } from "./types";
2
- export declare const requestDisplayMode: Methods["requestDisplayMode"];
1
+ import type { McpUiRequestDisplayModeResult } from "@modelcontextprotocol/ext-apps";
2
+ import type { Adapter, BridgeInterface, CallToolResponse, DisplayMode, ExternalStore, Methods } from "./types.js";
3
+ export declare class McpAppAdapter implements Adapter {
4
+ private static instance;
5
+ private stores;
6
+ private constructor();
7
+ static getInstance(): McpAppAdapter;
8
+ static resetInstance(): void;
9
+ getExternalStore<K extends keyof BridgeInterface>(key: K): ExternalStore<K>;
10
+ getMethod<K extends keyof Methods>(key: K): this[K];
11
+ callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
12
+ requestDisplayMode: (mode: DisplayMode) => Promise<McpUiRequestDisplayModeResult>;
13
+ sendFollowUpMessage: (prompt: string) => Promise<void>;
14
+ private initializeStores;
15
+ private createExternalStore;
16
+ }
@@ -1,12 +1,111 @@
1
- import { McpAppBridge } from "./mcp-app-bridge";
2
- export const requestDisplayMode = ({ mode }) => {
3
- const bridge = McpAppBridge.getInstance();
4
- if (mode !== "modal") {
5
- return bridge.request({
6
- method: "ui/request-display-mode",
7
- params: { mode },
1
+ import { dequal } from "dequal/lite";
2
+ import { McpAppBridge, } from "./mcp-app-bridge.js";
3
+ export class McpAppAdapter {
4
+ static instance = null;
5
+ stores;
6
+ constructor() {
7
+ this.stores = this.initializeStores();
8
+ }
9
+ static getInstance() {
10
+ if (!McpAppAdapter.instance) {
11
+ McpAppAdapter.instance = new McpAppAdapter();
12
+ }
13
+ return McpAppAdapter.instance;
14
+ }
15
+ static resetInstance() {
16
+ McpAppAdapter.instance = null;
17
+ }
18
+ getExternalStore(key) {
19
+ return this.stores[key];
20
+ }
21
+ getMethod(key) {
22
+ return this[key];
23
+ }
24
+ callTool = async (name, args) => {
25
+ const bridge = McpAppBridge.getInstance();
26
+ const response = await bridge.request({
27
+ method: "tools/call",
28
+ params: {
29
+ name,
30
+ arguments: args ?? undefined,
31
+ },
32
+ });
33
+ const result = response.content
34
+ .filter((content) => content.type === "text")
35
+ .map(({ text }) => text)
36
+ .join("\n");
37
+ return {
38
+ content: response.content,
39
+ structuredContent: response.structuredContent ?? {},
40
+ isError: response.isError ?? false,
41
+ result,
42
+ meta: response._meta ?? {},
43
+ };
44
+ };
45
+ requestDisplayMode = (mode) => {
46
+ const bridge = McpAppBridge.getInstance();
47
+ if (mode !== "modal") {
48
+ return bridge.request({
49
+ method: "ui/request-display-mode",
50
+ params: { mode },
51
+ });
52
+ }
53
+ throw new Error("Modal display mode is not accessible in MCP App.");
54
+ };
55
+ sendFollowUpMessage = async (prompt) => {
56
+ const bridge = McpAppBridge.getInstance();
57
+ await bridge.request({
58
+ method: "ui/message",
59
+ params: {
60
+ role: "user",
61
+ content: [
62
+ {
63
+ type: "text",
64
+ text: prompt,
65
+ },
66
+ ],
67
+ },
8
68
  });
69
+ };
70
+ initializeStores() {
71
+ return {
72
+ theme: this.createExternalStore(["theme"], ({ theme }) => theme ?? "light"),
73
+ locale: this.createExternalStore(["locale"], ({ locale }) => locale ?? "en-US"),
74
+ safeArea: this.createExternalStore(["safeAreaInsets"], ({ safeAreaInsets }) => ({
75
+ insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },
76
+ })),
77
+ displayMode: this.createExternalStore(["displayMode"], ({ displayMode }) => displayMode ?? "inline"),
78
+ maxHeight: this.createExternalStore(["viewport"], ({ viewport }) => viewport?.maxHeight ?? window.innerHeight),
79
+ userAgent: this.createExternalStore(["platform", "deviceCapabilities"], ({ platform, deviceCapabilities }) => ({
80
+ device: {
81
+ type: platform === "web" ? "desktop" : (platform ?? "unknown"),
82
+ },
83
+ capabilities: {
84
+ hover: true,
85
+ touch: true,
86
+ ...deviceCapabilities,
87
+ },
88
+ })),
89
+ toolInput: this.createExternalStore(["toolInput"], ({ toolInput }) => toolInput ?? null),
90
+ toolOutput: this.createExternalStore(["toolResult"], ({ toolResult }) => toolResult?.structuredContent ?? null),
91
+ toolResponseMetadata: this.createExternalStore(["toolResult"], ({ toolResult }) => toolResult?._meta ?? null),
92
+ };
93
+ }
94
+ createExternalStore(keys, computeSnapshot) {
95
+ const bridge = McpAppBridge.getInstance();
96
+ let cachedValue;
97
+ return {
98
+ subscribe: bridge.subscribe(keys),
99
+ getSnapshot: () => {
100
+ const context = Object.fromEntries(keys.map((k) => [k, bridge.getSnapshot(k)]));
101
+ const newValue = computeSnapshot(context);
102
+ if (cachedValue !== undefined && dequal(cachedValue, newValue)) {
103
+ return cachedValue;
104
+ }
105
+ cachedValue = newValue;
106
+ return newValue;
107
+ },
108
+ };
9
109
  }
10
- throw new Error("Modal display mode is not accessible in MCP App.");
11
- };
110
+ }
12
111
  //# sourceMappingURL=mcp-app-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-app-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,MAAM,CAAC,MAAM,kBAAkB,GAAkC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;IAC5E,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,OAAO,CAGnB;YACA,MAAM,EAAE,yBAAyB;YACjC,MAAM,EAAE,EAAE,IAAI,EAAE;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACtE,CAAC,CAAC"}
1
+ {"version":3,"file":"mcp-app-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,YAAY,GAGb,MAAM,qBAAqB,CAAC;AAc7B,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAC7C,MAAM,CAEZ;IACF;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAEM,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC5B,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;IAChC,CAAC;IAEM,gBAAgB,CACrB,GAAM;QAEN,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAEM,SAAS,CAA0B,GAAM;QAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,QAAQ,GAAG,KAAK,EAIrB,IAAY,EACZ,IAAc,EACS,EAAE;QACzB,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAkC;YACrE,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE;gBACN,IAAI;gBACJ,SAAS,EAAE,IAAI,IAAI,SAAS;aAC7B;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO;aAC5B,MAAM,CACL,CAAC,OAAO,EAA6C,EAAE,CACrD,OAAO,CAAC,IAAI,KAAK,MAAM,CAC1B;aACA,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC;aACvB,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,IAAI,EAAE;YACnD,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,KAAK;YAClC,MAAM;YACN,IAAI,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE;SACX,CAAC;IACpB,CAAC,CAAC;IAEK,kBAAkB,GAAG,CAAC,IAAiB,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,OAAO,MAAM,CAAC,OAAO,CAGnB;gBACA,MAAM,EAAE,yBAAyB;gBACjC,MAAM,EAAE,EAAE,IAAI,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC,CAAC;IAEK,mBAAmB,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACpD,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,MAAM,CAAC,OAAO,CAA0C;YAC5D,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE;gBACN,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM;qBACb;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEM,gBAAgB;QAGtB,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAC7B,CAAC,OAAO,CAAC,EACT,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,OAAO,CAChC;YACD,MAAM,EAAE,IAAI,CAAC,mBAAmB,CAC9B,CAAC,QAAQ,CAAC,EACV,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,OAAO,CAClC;YACD,QAAQ,EAAE,IAAI,CAAC,mBAAmB,CAChC,CAAC,gBAAgB,CAAC,EAClB,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;gBACvB,MAAM,EAAE,cAAc,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;aACnE,CAAC,CACH;YACD,WAAW,EAAE,IAAI,CAAC,mBAAmB,CACnC,CAAC,aAAa,CAAC,EACf,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,IAAI,QAAQ,CAC7C;YACD,SAAS,EAAE,IAAI,CAAC,mBAAmB,CACjC,CAAC,UAAU,CAAC,EACZ,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,MAAM,CAAC,WAAW,CAC5D;YACD,SAAS,EAAE,IAAI,CAAC,mBAAmB,CACjC,CAAC,UAAU,EAAE,oBAAoB,CAAC,EAClC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC;iBAC/D;gBACD,YAAY,EAAE;oBACZ,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,IAAI;oBACX,GAAG,kBAAkB;iBACtB;aACF,CAAC,CACH;YACD,SAAS,EAAE,IAAI,CAAC,mBAAmB,CACjC,CAAC,WAAW,CAAC,EACb,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI,CACrC;YACD,UAAU,EAAE,IAAI,CAAC,mBAAmB,CAClC,CAAC,YAAY,CAAC,EACd,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,iBAAiB,IAAI,IAAI,CAC1D;YACD,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAC5C,CAAC,YAAY,CAAC,EACd,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI,CAC9C;SACF,CAAC;IACJ,CAAC;IAEO,mBAAmB,CACzB,IAAU,EACV,eAAkD;QAElD,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,WAA0B,CAAC;QAE/B,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;YACjC,WAAW,EAAE,GAAG,EAAE;gBAChB,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC;gBACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;gBAE1C,IAAI,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC;oBAC/D,OAAO,WAAW,CAAC;gBACrB,CAAC;gBAED,WAAW,GAAG,QAAQ,CAAC;gBACvB,OAAO,QAAQ,CAAC;YAClB,CAAC;SACF,CAAC;IACJ,CAAC"}
@@ -1,8 +1,16 @@
1
- import type { McpUiHostContext, McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
1
+ import type { McpUiHostContext, McpUiInitializeRequest, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
2
+ import type { Bridge, Subscribe } from "./types.js";
2
3
  type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
3
- export declare class McpAppBridge {
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
+ export declare class McpAppBridge implements Bridge<McpUiHostContext> {
4
12
  private static instance;
5
- context: McpUiHostContext | null;
13
+ context: McpAppBridgeContext;
6
14
  private listeners;
7
15
  private pendingRequests;
8
16
  private nextId;
@@ -11,8 +19,9 @@ export declare class McpAppBridge {
11
19
  private requestTimeout;
12
20
  constructor(options: McpAppInitializationOptions, requestTimeout?: number);
13
21
  static getInstance(options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppBridge;
14
- subscribe: (key: keyof McpUiHostContext) => (onChange: () => void) => () => boolean | undefined;
15
- getSnapshot: <K extends keyof McpUiHostContext>(key: K) => McpUiHostContext[K] | undefined;
22
+ subscribe(key: McpAppBridgeKey): Subscribe;
23
+ subscribe(keys: readonly McpAppBridgeKey[]): Subscribe;
24
+ getSnapshot<K extends keyof McpAppBridgeContext>(key: K): McpAppBridgeContext[K];
16
25
  cleanup: () => void;
17
26
  static resetInstance(): void;
18
27
  request<R extends {
@@ -20,7 +29,7 @@ export declare class McpAppBridge {
20
29
  params?: unknown;
21
30
  }, T>({ method, params, }: R): Promise<T>;
22
31
  private emit;
23
- private setContext;
32
+ private updateContext;
24
33
  private init;
25
34
  private handleMessage;
26
35
  private connect;