@assistant-ui/react-mcp 0.1.20 → 0.1.22

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 (85) hide show
  1. package/LICENSE +1 -1
  2. package/dist/auth/createOAuthProvider.d.ts.map +1 -1
  3. package/dist/auth/createOAuthProvider.js +7 -1
  4. package/dist/auth/createOAuthProvider.js.map +1 -1
  5. package/dist/context/McpConnectorByIndexProvider.js.map +1 -1
  6. package/dist/context/McpCustomServerByIndexProvider.js.map +1 -1
  7. package/dist/context/McpServerByIdProvider.js.map +1 -1
  8. package/dist/hooks/useMcpOAuthCallback.js.map +1 -1
  9. package/dist/primitives/addForm/McpAddFormAuthFields.js.map +1 -1
  10. package/dist/primitives/addForm/McpAddFormAuthSelect.js.map +1 -1
  11. package/dist/primitives/addForm/McpAddFormBearerTokenField.js.map +1 -1
  12. package/dist/primitives/addForm/McpAddFormCancel.js.map +1 -1
  13. package/dist/primitives/addForm/McpAddFormError.js.map +1 -1
  14. package/dist/primitives/addForm/McpAddFormNameField.js.map +1 -1
  15. package/dist/primitives/addForm/McpAddFormRoot.d.ts.map +1 -1
  16. package/dist/primitives/addForm/McpAddFormRoot.js +14 -5
  17. package/dist/primitives/addForm/McpAddFormRoot.js.map +1 -1
  18. package/dist/primitives/addForm/McpAddFormScopesField.js.map +1 -1
  19. package/dist/primitives/addForm/McpAddFormSubmit.js.map +1 -1
  20. package/dist/primitives/addForm/McpAddFormUrlField.js.map +1 -1
  21. package/dist/primitives/elicitation/McpElicitationPrimitiveAccept.js.map +1 -1
  22. package/dist/primitives/elicitation/McpElicitationPrimitiveCancel.js.map +1 -1
  23. package/dist/primitives/elicitation/McpElicitationPrimitiveDecline.js.map +1 -1
  24. package/dist/primitives/elicitation/McpElicitationPrimitiveError.js.map +1 -1
  25. package/dist/primitives/elicitation/McpElicitationPrimitiveFields.js.map +1 -1
  26. package/dist/primitives/elicitation/McpElicitationPrimitiveItems.js.map +1 -1
  27. package/dist/primitives/elicitation/McpElicitationPrimitiveMessage.js.map +1 -1
  28. package/dist/primitives/elicitation/McpElicitationPrimitiveRoot.js.map +1 -1
  29. package/dist/primitives/manager/McpManagerAddCustomTrigger.js.map +1 -1
  30. package/dist/primitives/manager/McpManagerRoot.js.map +1 -1
  31. package/dist/primitives/server/McpServerConnectButton.js.map +1 -1
  32. package/dist/primitives/server/McpServerDisconnectButton.js.map +1 -1
  33. package/dist/primitives/server/McpServerError.js.map +1 -1
  34. package/dist/primitives/server/McpServerIcon.js.map +1 -1
  35. package/dist/primitives/server/McpServerName.js.map +1 -1
  36. package/dist/primitives/server/McpServerOAuthLink.js.map +1 -1
  37. package/dist/primitives/server/McpServerRemoveButton.js.map +1 -1
  38. package/dist/primitives/server/McpServerRoot.js.map +1 -1
  39. package/dist/primitives/server/McpServerStatus.js.map +1 -1
  40. package/dist/primitives/server/McpServerToolName.js.map +1 -1
  41. package/dist/primitives/server/McpServerTools.js.map +1 -1
  42. package/dist/resources/McpCustomServerPersistence.d.ts +17 -0
  43. package/dist/resources/McpCustomServerPersistence.d.ts.map +1 -0
  44. package/dist/resources/McpCustomServerPersistence.js +192 -0
  45. package/dist/resources/McpCustomServerPersistence.js.map +1 -0
  46. package/dist/resources/McpElicitationLifecycle.d.ts +12 -0
  47. package/dist/resources/McpElicitationLifecycle.d.ts.map +1 -0
  48. package/dist/resources/McpElicitationLifecycle.js +144 -0
  49. package/dist/resources/McpElicitationLifecycle.js.map +1 -0
  50. package/dist/resources/McpManagerResource.d.ts.map +1 -1
  51. package/dist/resources/McpManagerResource.js +28 -205
  52. package/dist/resources/McpManagerResource.js.map +1 -1
  53. package/dist/resources/McpServerResource.d.ts.map +1 -1
  54. package/dist/resources/McpServerResource.js +24 -101
  55. package/dist/resources/McpServerResource.js.map +1 -1
  56. package/dist/resources/storage/McpLocalStorage.d.ts +1 -4
  57. package/dist/resources/storage/McpLocalStorage.d.ts.map +1 -1
  58. package/dist/resources/storage/McpLocalStorage.js +1 -100
  59. package/dist/resources/storage/McpLocalStorage.js.map +1 -1
  60. package/dist/resources/storage/McpStoredDataNormalization.d.ts +5 -0
  61. package/dist/resources/storage/McpStoredDataNormalization.d.ts.map +1 -0
  62. package/dist/resources/storage/McpStoredDataNormalization.js +95 -0
  63. package/dist/resources/storage/McpStoredDataNormalization.js.map +1 -0
  64. package/dist/utils/serverUrl.d.ts +1 -0
  65. package/dist/utils/serverUrl.d.ts.map +1 -1
  66. package/dist/utils/serverUrl.js +15 -1
  67. package/dist/utils/serverUrl.js.map +1 -1
  68. package/package.json +15 -11
  69. package/src/auth/createOAuthProvider.test.ts +30 -1
  70. package/src/auth/createOAuthProvider.ts +12 -4
  71. package/src/primitives/addForm/McpAddFormRoot.test.tsx +66 -0
  72. package/src/primitives/addForm/McpAddFormRoot.tsx +11 -1
  73. package/src/resources/McpCustomServerPersistence.test.ts +56 -0
  74. package/src/resources/McpCustomServerPersistence.ts +233 -0
  75. package/src/resources/McpElicitationLifecycle.test.ts +83 -0
  76. package/src/resources/McpElicitationLifecycle.ts +156 -0
  77. package/src/resources/McpManagerResource.test.ts +36 -0
  78. package/src/resources/McpManagerResource.ts +25 -248
  79. package/src/resources/McpServerResource.test.ts +123 -10
  80. package/src/resources/McpServerResource.ts +29 -149
  81. package/src/resources/storage/McpLocalStorage.ts +9 -209
  82. package/src/resources/storage/McpStoredDataNormalization.test.ts +24 -0
  83. package/src/resources/storage/McpStoredDataNormalization.ts +201 -0
  84. package/src/utils/serverUrl.test.ts +30 -0
  85. package/src/utils/serverUrl.ts +26 -0
@@ -0,0 +1,144 @@
1
+ import { createMcpId } from "../utils/createMcpId.js";
2
+ import { validateElicitationContent } from "./validateElicitationContent.js";
3
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
+ import { useRef, useState } from "@assistant-ui/tap/react-shim";
5
+ //#region src/resources/McpElicitationLifecycle.ts
6
+ const useMcpElicitationLifecycle = () => {
7
+ const $ = c(9);
8
+ let t0;
9
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
10
+ t0 = [];
11
+ $[0] = t0;
12
+ } else t0 = $[0];
13
+ const [pendingElicitations, setPendingElicitations] = useState(t0);
14
+ let t1;
15
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
16
+ t1 = /* @__PURE__ */ new Map();
17
+ $[1] = t1;
18
+ } else t1 = $[1];
19
+ const elicitationResolversRef = useRef(t1);
20
+ let t2;
21
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
22
+ t2 = (id, result) => {
23
+ const entry = elicitationResolversRef.current.get(id);
24
+ if (!entry) return false;
25
+ elicitationResolversRef.current.delete(id);
26
+ entry.signal.removeEventListener("abort", entry.onAbort);
27
+ setPendingElicitations((current) => current.filter((elicitation) => elicitation.id !== id));
28
+ entry.resolve(result);
29
+ return true;
30
+ };
31
+ $[2] = t2;
32
+ } else t2 = $[2];
33
+ const resolvePendingElicitation = t2;
34
+ let t3;
35
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
36
+ t3 = (id_0, error) => {
37
+ if (!elicitationResolversRef.current.has(id_0)) return false;
38
+ setPendingElicitations((current_0) => current_0.map((elicitation_0) => elicitation_0.id === id_0 ? {
39
+ ...elicitation_0,
40
+ error
41
+ } : elicitation_0));
42
+ return true;
43
+ };
44
+ $[3] = t3;
45
+ } else t3 = $[3];
46
+ const setPendingElicitationError = t3;
47
+ let t4;
48
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
49
+ t4 = () => {
50
+ for (const [id_1] of elicitationResolversRef.current) resolvePendingElicitation(id_1, { action: "cancel" });
51
+ };
52
+ $[4] = t4;
53
+ } else t4 = $[4];
54
+ const cancelPendingElicitations = t4;
55
+ let t5;
56
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
57
+ t5 = (request, signal, isCurrentConnection) => {
58
+ if (!isCurrentConnection()) return Promise.resolve({ action: "cancel" });
59
+ if (!("requestedSchema" in request.params)) return Promise.resolve({ action: "cancel" });
60
+ const { message, requestedSchema } = request.params;
61
+ const id_2 = createMcpId();
62
+ const promise = new Promise((resolve) => {
63
+ const onAbort = () => {
64
+ resolvePendingElicitation(id_2, { action: "cancel" });
65
+ };
66
+ elicitationResolversRef.current.set(id_2, {
67
+ resolve,
68
+ signal,
69
+ onAbort,
70
+ requestedSchema
71
+ });
72
+ });
73
+ setPendingElicitations((current_1) => [...current_1, {
74
+ id: id_2,
75
+ message,
76
+ requestedSchema
77
+ }]);
78
+ const entry_0 = elicitationResolversRef.current.get(id_2);
79
+ if (entry_0) {
80
+ if (signal.aborted) entry_0.onAbort();
81
+ else signal.addEventListener("abort", entry_0.onAbort, { once: true });
82
+ }
83
+ return promise;
84
+ };
85
+ $[5] = t5;
86
+ } else t5 = $[5];
87
+ const requestElicitation = t5;
88
+ let t6;
89
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
90
+ t6 = (id_3, response) => {
91
+ if (response.action === "accept") {
92
+ const entry_1 = elicitationResolversRef.current.get(id_3);
93
+ if (!entry_1) return;
94
+ if (typeof response.content !== "object" || response.content === null || Array.isArray(response.content)) {
95
+ const errors = [{
96
+ property: "content",
97
+ message: "Response content must be an object."
98
+ }];
99
+ setPendingElicitationError(id_3, {
100
+ message: "Invalid elicitation content: content.",
101
+ properties: ["content"]
102
+ });
103
+ return errors;
104
+ }
105
+ const errors_0 = validateElicitationContent(entry_1.requestedSchema, response.content);
106
+ if (errors_0.length > 0) {
107
+ const properties = [...new Set(errors_0.map(_temp))];
108
+ setPendingElicitationError(id_3, {
109
+ message: `Invalid elicitation content: ${properties.join(", ")}.`,
110
+ properties
111
+ });
112
+ return errors_0;
113
+ }
114
+ const result_0 = {
115
+ action: "accept",
116
+ content: response.content
117
+ };
118
+ resolvePendingElicitation(id_3, result_0);
119
+ return;
120
+ }
121
+ resolvePendingElicitation(id_3, { action: response.action });
122
+ };
123
+ $[6] = t6;
124
+ } else t6 = $[6];
125
+ let t7;
126
+ if ($[7] !== pendingElicitations) {
127
+ t7 = {
128
+ pendingElicitations,
129
+ cancelPendingElicitations,
130
+ requestElicitation,
131
+ answerElicitation: t6
132
+ };
133
+ $[7] = pendingElicitations;
134
+ $[8] = t7;
135
+ } else t7 = $[8];
136
+ return t7;
137
+ };
138
+ function _temp(error_0) {
139
+ return error_0.property;
140
+ }
141
+ //#endregion
142
+ export { useMcpElicitationLifecycle };
143
+
144
+ //# sourceMappingURL=McpElicitationLifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpElicitationLifecycle.js","names":["useRef","useState","ElicitRequest","ElicitResult","MCPElicitation","MCPElicitationResponse","createMcpId","validateElicitationContent","useMcpElicitationLifecycle","$","_c","t0","Symbol","for","pendingElicitations","setPendingElicitations","t1","Map","elicitationResolversRef","t2","id","result","entry","current","get","delete","signal","removeEventListener","onAbort","filter","elicitation","resolve","resolvePendingElicitation","t3","id_0","error","has","current_0","map","elicitation_0","setPendingElicitationError","t4","id_1","action","cancelPendingElicitations","t5","request","isCurrentConnection","Promise","params","message","requestedSchema","id_2","promise","set","current_1","entry_0","aborted","addEventListener","once","requestElicitation","t6","id_3","response","entry_1","content","Array","isArray","errors","property","properties","errors_0","length","Set","_temp","join","result_0","t7","answerElicitation","error_0","_c"],"sources":["../../src/resources/McpElicitationLifecycle.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport type { ElicitRequest, ElicitResult } from \"@modelcontextprotocol/client\";\nimport type { MCPElicitation, MCPElicitationResponse } from \"../mcp-scope\";\nimport { createMcpId } from \"../utils/createMcpId\";\nimport { validateElicitationContent } from \"./validateElicitationContent\";\n\nexport const useMcpElicitationLifecycle = () => {\n const [pendingElicitations, setPendingElicitations] = useState<\n MCPElicitation[]\n >([]);\n const elicitationResolversRef = useRef(\n new Map<\n string,\n {\n resolve: (result: ElicitResult) => void;\n signal: AbortSignal;\n onAbort: () => void;\n requestedSchema: unknown;\n }\n >(),\n );\n const resolvePendingElicitation = (id: string, result: ElicitResult) => {\n const entry = elicitationResolversRef.current.get(id);\n if (!entry) return false;\n elicitationResolversRef.current.delete(id);\n entry.signal.removeEventListener(\"abort\", entry.onAbort);\n setPendingElicitations((current) =>\n current.filter((elicitation) => elicitation.id !== id),\n );\n entry.resolve(result);\n return true;\n };\n\n const setPendingElicitationError = (\n id: string,\n error: NonNullable<MCPElicitation[\"error\"]>,\n ) => {\n if (!elicitationResolversRef.current.has(id)) return false;\n setPendingElicitations((current) =>\n current.map((elicitation) =>\n elicitation.id === id ? { ...elicitation, error } : elicitation,\n ),\n );\n return true;\n };\n\n const cancelPendingElicitations = () => {\n for (const [id] of elicitationResolversRef.current) {\n resolvePendingElicitation(id, { action: \"cancel\" });\n }\n };\n\n const requestElicitation = (\n request: ElicitRequest,\n signal: AbortSignal,\n isCurrentConnection: () => boolean,\n ): Promise<ElicitResult> => {\n if (!isCurrentConnection()) {\n return Promise.resolve({ action: \"cancel\" });\n }\n if (!(\"requestedSchema\" in request.params)) {\n return Promise.resolve({ action: \"cancel\" });\n }\n const { message, requestedSchema } = request.params;\n\n const id = createMcpId();\n const promise = new Promise<ElicitResult>((resolve) => {\n const onAbort = () => {\n resolvePendingElicitation(id, { action: \"cancel\" });\n };\n elicitationResolversRef.current.set(id, {\n resolve,\n signal,\n onAbort,\n requestedSchema,\n });\n });\n setPendingElicitations((current) => [\n ...current,\n {\n id,\n message,\n requestedSchema,\n },\n ]);\n const entry = elicitationResolversRef.current.get(id);\n if (entry) {\n if (signal.aborted) {\n entry.onAbort();\n } else {\n signal.addEventListener(\"abort\", entry.onAbort, {\n once: true,\n });\n }\n }\n return promise;\n };\n\n return {\n pendingElicitations,\n cancelPendingElicitations,\n requestElicitation,\n answerElicitation: (\n id: string,\n response: MCPElicitationResponse,\n ): readonly { property: string; message: string }[] | undefined => {\n if (response.action === \"accept\") {\n const entry = elicitationResolversRef.current.get(id);\n if (!entry) return undefined;\n\n if (\n typeof response.content !== \"object\" ||\n response.content === null ||\n Array.isArray(response.content)\n ) {\n const errors = [\n {\n property: \"content\",\n message: \"Response content must be an object.\",\n },\n ];\n setPendingElicitationError(id, {\n message: \"Invalid elicitation content: content.\",\n properties: [\"content\"],\n });\n return errors;\n }\n\n const errors = validateElicitationContent(\n entry.requestedSchema,\n response.content,\n );\n if (errors.length > 0) {\n const properties = [\n ...new Set(errors.map((error) => error.property)),\n ];\n setPendingElicitationError(id, {\n message: `Invalid elicitation content: ${properties.join(\", \")}.`,\n properties,\n });\n return errors;\n }\n\n const result: ElicitResult = {\n action: \"accept\",\n content: response.content as ElicitResult[\"content\"],\n };\n resolvePendingElicitation(id, result);\n return undefined;\n }\n\n resolvePendingElicitation(id, { action: response.action });\n return undefined;\n },\n };\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"McpManagerResource.d.ts","sourceRoot":"","sources":["../../src/resources/McpManagerResource.ts"],"names":[],"mappings":"AASA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,KAAK,EAAc,iBAAiB,EAAE,2BAAwB;AAErE,OAAO,KAAK,EAEV,YAAY,EAGb,wBAAqB;AAEtB,MAAM,MAAM,uBAAuB,GAAG;IACpC,UAAU,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC,CAAC;AAycF,eAAO,MAAM,kBAAkB,6FAAkC,CAAC"}
1
+ {"version":3,"file":"McpManagerResource.d.ts","sourceRoot":"","sources":["../../src/resources/McpManagerResource.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAc7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,2BAAwB;AAEzD,OAAO,KAAK,EAEV,YAAY,EAGb,wBAAqB;AAEtB,MAAM,MAAM,uBAAuB,GAAG;IACpC,UAAU,CAAC,EAAE,YAAY,EAAE,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC,CAAC;AA4OF,eAAO,MAAM,kBAAkB,6FAAkC,CAAC"}
@@ -3,10 +3,11 @@ import { assertUniqueServerIds } from "../utils/serverId.js";
3
3
  import { createMcpId } from "../utils/createMcpId.js";
4
4
  import { withMcpServerRemovalFence } from "./McpServerRemovalFence.js";
5
5
  import { McpServerResource } from "./McpServerResource.js";
6
+ import { McpCustomServersResource, holdCustomServerPersistence } from "./McpCustomServerPersistence.js";
6
7
  import { McpLocalStorage } from "./storage/McpLocalStorage.js";
7
8
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
8
9
  import { attachTransformScopes, useAssistantClientRef, useClientLookup } from "@assistant-ui/store";
9
- import { useEffect, useEffectEvent, useRef, useState } from "@assistant-ui/tap/react-shim";
10
+ import { useState } from "@assistant-ui/tap/react-shim";
10
11
  import { resource, useResource, withKey } from "@assistant-ui/tap";
11
12
  import { useAssistantScopeEffect } from "@assistant-ui/store/client";
12
13
  import { ModelContext } from "@assistant-ui/core/store";
@@ -16,184 +17,6 @@ function defaultRedirectUri() {
16
17
  return `${window.location.origin}/mcp/callback`;
17
18
  }
18
19
  const NO_CONNECTORS = [];
19
- const reportCustomStorageFailure = (operation, error) => {
20
- console.error(`[assistant-ui/react-mcp] failed to ${operation} custom servers:`, error);
21
- };
22
- const reportBlockedCustomServerPersistence = () => {
23
- console.error("[assistant-ui/react-mcp] custom server changes remain in memory because loading the persisted list failed; remount the manager to retry");
24
- };
25
- const persistCustomServers = async (storage, records) => {
26
- try {
27
- await storage.saveCustomServers(records);
28
- } catch (error) {
29
- reportCustomStorageFailure("save", error);
30
- }
31
- };
32
- const enqueueCustomServerTask = (persistenceQueues, scopeKey, task) => {
33
- const next = (persistenceQueues.get(scopeKey) ?? Promise.resolve()).then(task);
34
- persistenceQueues.set(scopeKey, next);
35
- next.then(() => {
36
- if (persistenceQueues.get(scopeKey) === next) persistenceQueues.delete(scopeKey);
37
- });
38
- };
39
- const enqueueCustomServerPersistence = (persistenceQueues, scopeKey, storage, records) => enqueueCustomServerTask(persistenceQueues, scopeKey, () => persistCustomServers(storage, records));
40
- const holdCustomServerPersistence = (persistenceQueues, scopeKey) => {
41
- let release = () => {};
42
- const gate = new Promise((resolve) => {
43
- release = resolve;
44
- });
45
- enqueueCustomServerTask(persistenceQueues, scopeKey, () => gate);
46
- return release;
47
- };
48
- const deduplicateCustomServers = (records) => {
49
- const seen = /* @__PURE__ */ new Set();
50
- return records.filter((record) => {
51
- if (seen.has(record.id)) {
52
- console.error(`[assistant-ui/react-mcp] ignored duplicate custom server id "${record.id}" loaded from storage`);
53
- return false;
54
- }
55
- seen.add(record.id);
56
- return true;
57
- });
58
- };
59
- const useMcpCustomServersResource = (t0) => {
60
- const $ = c(22);
61
- const { storage, scopeKey, persistenceQueues } = t0;
62
- let t1;
63
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
64
- t1 = [];
65
- $[0] = t1;
66
- } else t1 = $[0];
67
- const [customServers, setCustomServers] = useState(t1);
68
- const [isHydrated, setIsHydrated] = useState(false);
69
- let t2;
70
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
71
- t2 = [];
72
- $[1] = t2;
73
- } else t2 = $[1];
74
- const customServersRef = useRef(t2);
75
- const hydrationStateRef = useRef("pending");
76
- const hasPendingMutationRef = useRef(false);
77
- const [removedBeforeHydration] = useState(_temp);
78
- const reportedBlockedPersistenceRef = useRef(false);
79
- let t3;
80
- if ($[2] !== persistenceQueues || $[3] !== removedBeforeHydration || $[4] !== scopeKey || $[5] !== storage) {
81
- t3 = async (signal) => {
82
- while (true) {
83
- const pendingPersistence = persistenceQueues.get(scopeKey);
84
- if (!pendingPersistence) break;
85
- await pendingPersistence;
86
- if (signal.cancelled) return;
87
- if (persistenceQueues.get(scopeKey) === pendingPersistence) break;
88
- }
89
- let records;
90
- try {
91
- const loadedRecords = await storage.loadCustomServers();
92
- records = deduplicateCustomServers(loadedRecords);
93
- } catch (t4) {
94
- const error = t4;
95
- if (!signal.cancelled) {
96
- reportCustomStorageFailure("load", error);
97
- hydrationStateRef.current = "failed";
98
- if (hasPendingMutationRef.current) {
99
- reportBlockedCustomServerPersistence();
100
- reportedBlockedPersistenceRef.current = true;
101
- }
102
- setIsHydrated(true);
103
- }
104
- return;
105
- }
106
- const hadPendingMutation = hasPendingMutationRef.current;
107
- const hydratedRecords = records.filter((record) => !removedBeforeHydration.has(record.id));
108
- const mergedRecords = (() => {
109
- const prev = customServersRef.current;
110
- if (prev.length === 0) return hydratedRecords;
111
- const persistedIds = new Set(hydratedRecords.map(_temp2));
112
- return [...hydratedRecords, ...prev.filter((r_0) => !persistedIds.has(r_0.id))];
113
- })();
114
- customServersRef.current = mergedRecords;
115
- hydrationStateRef.current = "succeeded";
116
- hasPendingMutationRef.current = false;
117
- if (hadPendingMutation) enqueueCustomServerPersistence(persistenceQueues, scopeKey, storage, mergedRecords);
118
- if (signal.cancelled) return;
119
- setCustomServers(mergedRecords);
120
- setIsHydrated(true);
121
- };
122
- $[2] = persistenceQueues;
123
- $[3] = removedBeforeHydration;
124
- $[4] = scopeKey;
125
- $[5] = storage;
126
- $[6] = t3;
127
- } else t3 = $[6];
128
- const hydrate = useEffectEvent(t3);
129
- let t4;
130
- if ($[7] !== hydrate) {
131
- t4 = () => {
132
- const signal_0 = { cancelled: false };
133
- hydrate(signal_0);
134
- return () => {
135
- signal_0.cancelled = true;
136
- };
137
- };
138
- $[7] = hydrate;
139
- $[8] = t4;
140
- } else t4 = $[8];
141
- let t5;
142
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
143
- t5 = [];
144
- $[9] = t5;
145
- } else t5 = $[9];
146
- useEffect(t4, t5);
147
- let t6;
148
- if ($[10] !== persistenceQueues || $[11] !== scopeKey || $[12] !== storage) {
149
- t6 = (updater) => {
150
- const next = updater(customServersRef.current);
151
- customServersRef.current = next;
152
- setCustomServers(next);
153
- if (hydrationStateRef.current === "succeeded") {
154
- enqueueCustomServerPersistence(persistenceQueues, scopeKey, storage, next);
155
- return;
156
- }
157
- hasPendingMutationRef.current = true;
158
- if (hydrationStateRef.current === "failed" && !reportedBlockedPersistenceRef.current) {
159
- reportBlockedCustomServerPersistence();
160
- reportedBlockedPersistenceRef.current = true;
161
- }
162
- };
163
- $[10] = persistenceQueues;
164
- $[11] = scopeKey;
165
- $[12] = storage;
166
- $[13] = t6;
167
- } else t6 = $[13];
168
- const updateCustomServers = t6;
169
- let t7;
170
- if ($[14] !== removedBeforeHydration || $[15] !== updateCustomServers) {
171
- t7 = (id) => {
172
- if (hydrationStateRef.current === "pending") removedBeforeHydration.add(id);
173
- updateCustomServers((prev_0) => prev_0.filter((record_0) => record_0.id !== id));
174
- };
175
- $[14] = removedBeforeHydration;
176
- $[15] = updateCustomServers;
177
- $[16] = t7;
178
- } else t7 = $[16];
179
- const removeCustomServer = t7;
180
- let t8;
181
- if ($[17] !== customServers || $[18] !== isHydrated || $[19] !== removeCustomServer || $[20] !== updateCustomServers) {
182
- t8 = {
183
- customServers,
184
- isHydrated,
185
- updateCustomServers,
186
- removeCustomServer
187
- };
188
- $[17] = customServers;
189
- $[18] = isHydrated;
190
- $[19] = removeCustomServer;
191
- $[20] = updateCustomServers;
192
- $[21] = t8;
193
- } else t8 = $[21];
194
- return t8;
195
- };
196
- const McpCustomServersResource = resource(useMcpCustomServersResource);
197
20
  const useMcpManagerResource = (props) => {
198
21
  const $ = c(75);
199
22
  const connectors = props.connectors ?? NO_CONNECTORS;
@@ -213,7 +36,7 @@ const useMcpManagerResource = (props) => {
213
36
  $[3] = t1;
214
37
  } else t1 = $[3];
215
38
  const storage = useResource(t1);
216
- const [persistenceQueues] = useState(_temp3);
39
+ const [persistenceQueues] = useState(_temp);
217
40
  const storageScopeKey = storage.scopeId === void 0 ? "unscoped" : `scoped:${storage.scopeId}`;
218
41
  let t2;
219
42
  if ($[4] !== persistenceQueues || $[5] !== storage || $[6] !== storageScopeKey) {
@@ -228,7 +51,7 @@ const useMcpManagerResource = (props) => {
228
51
  $[7] = t2;
229
52
  } else t2 = $[7];
230
53
  const { customServers, isHydrated, updateCustomServers, removeCustomServer } = useResource(t2);
231
- assertUniqueServerIds([...connectors.map(_temp4), ...customServers.map(_temp5)]);
54
+ assertUniqueServerIds([...connectors.map(_temp2), ...customServers.map(_temp3)]);
232
55
  let t3;
233
56
  if ($[8] !== autoConnect || $[9] !== connectionTimeout || $[10] !== connectors || $[11] !== customServers || $[12] !== persistenceQueues || $[13] !== redirectUri || $[14] !== removeCustomServer || $[15] !== storage || $[16] !== storageScopeKey) {
234
57
  let t4;
@@ -246,7 +69,7 @@ const useMcpManagerResource = (props) => {
246
69
  connectionTimeout: c_0.connectionTimeout ?? connectionTimeout,
247
70
  ...c_0.cache !== void 0 ? { cache: c_0.cache } : {},
248
71
  ...c_0.elicitation !== void 0 ? { elicitation: c_0.elicitation } : {},
249
- onRemove: _temp6
72
+ onRemove: _temp4
250
73
  }));
251
74
  $[18] = autoConnect;
252
75
  $[19] = connectionTimeout;
@@ -299,13 +122,13 @@ const useMcpManagerResource = (props) => {
299
122
  const all = lookup.state;
300
123
  let t4;
301
124
  if ($[31] !== all) {
302
- t4 = all.filter(_temp7);
125
+ t4 = all.filter(_temp5);
303
126
  $[31] = all;
304
127
  $[32] = t4;
305
128
  } else t4 = $[32];
306
129
  let t5;
307
130
  if ($[33] !== all) {
308
- t5 = all.filter(_temp8);
131
+ t5 = all.filter(_temp6);
309
132
  $[33] = all;
310
133
  $[34] = t5;
311
134
  } else t5 = $[34];
@@ -434,20 +257,26 @@ const useMcpManagerResource = (props) => {
434
257
  if ($[61] !== lookup || $[62] !== persistenceQueues || $[63] !== removeCustomServer || $[64] !== state || $[65] !== storage || $[66] !== storageScopeKey) {
435
258
  t15 = async (id) => {
436
259
  if (state.connectors.some((c_1) => c_1.id === id)) throw new Error(`Cannot remove connector "${id}" — connectors are app-defined and not removable. Use a custom server id instead.`);
260
+ let server_0;
437
261
  try {
438
- await lookup.get({ key: id }).remove();
262
+ server_0 = lookup.get({ key: id });
439
263
  } catch {
440
- const releasePersistence = holdCustomServerPersistence(persistenceQueues, storageScopeKey);
441
- try {
442
- await clearOAuthProviderAuthState(storage, id);
443
- removeCustomServer(id);
444
- } catch (t16) {
445
- const error = t16;
446
- releasePersistence();
447
- throw error;
448
- }
264
+ server_0 = void 0;
265
+ }
266
+ if (server_0) {
267
+ await server_0.remove();
268
+ return;
269
+ }
270
+ const releasePersistence = holdCustomServerPersistence(persistenceQueues, storageScopeKey);
271
+ try {
272
+ await clearOAuthProviderAuthState(storage, id);
273
+ removeCustomServer(id);
274
+ } catch (t16) {
275
+ const error = t16;
449
276
  releasePersistence();
277
+ throw error;
450
278
  }
279
+ releasePersistence();
451
280
  };
452
281
  $[61] = lookup;
453
282
  $[62] = persistenceQueues;
@@ -482,25 +311,19 @@ attachTransformScopes(useMcpManagerResource, (scopes, parent) => {
482
311
  if (!scopes.modelContext && parent.modelContext.source === null) scopes.modelContext = ModelContext();
483
312
  });
484
313
  function _temp() {
485
- return /* @__PURE__ */ new Set();
486
- }
487
- function _temp2(r) {
488
- return r.id;
489
- }
490
- function _temp3() {
491
314
  return /* @__PURE__ */ new Map();
492
315
  }
493
- function _temp4(c) {
316
+ function _temp2(c) {
494
317
  return c.id;
495
318
  }
496
- function _temp5(s) {
319
+ function _temp3(s) {
497
320
  return s.id;
498
321
  }
499
- async function _temp6() {}
500
- function _temp7(s_1) {
322
+ async function _temp4() {}
323
+ function _temp5(s_1) {
501
324
  return s_1.kind === "connector";
502
325
  }
503
- function _temp8(s_2) {
326
+ function _temp6(s_2) {
504
327
  return s_2.kind === "custom";
505
328
  }
506
329
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"McpManagerResource.js","names":["useState","useEffect","useMemo","useEffectEvent","useRef","useCallback","useResource","resource","withKey","useClientLookup","useAssistantClientRef","attachTransformScopes","ClientOutput","useAssistantScopeEffect","ModelContext","createMcpId","clearOAuthProviderAuthState","Tool","McpServerResource","withMcpServerRemovalFence","McpLocalStorage","MCPStorage","MCPStorageElement","assertUniqueServerIds","MCPAuthConfig","MCPConnector","MCPCustomServerRecord","MCPManagerState","McpManagerResourceProps","connectors","storage","oauthRedirectUri","autoConnect","connectionTimeout","defaultRedirectUri","window","location","origin","NO_CONNECTORS","reportCustomStorageFailure","operation","error","console","reportBlockedCustomServerPersistence","persistCustomServers","records","saveCustomServers","CustomServerPersistenceQueues","Map","Promise","enqueueCustomServerTask","persistenceQueues","scopeKey","task","previous","get","next","resolve","then","set","delete","enqueueCustomServerPersistence","holdCustomServerPersistence","release","gate","deduplicateCustomServers","seen","Set","filter","record","has","id","add","McpCustomServersResourceProps","useMcpCustomServersResource","t0","$","_c","t1","Symbol","for","customServers","setCustomServers","isHydrated","setIsHydrated","t2","customServersRef","hydrationStateRef","hasPendingMutationRef","removedBeforeHydration","_temp","reportedBlockedPersistenceRef","t3","signal","pendingPersistence","cancelled","loadedRecords","loadCustomServers","t4","current","hadPendingMutation","hydratedRecords","mergedRecords","prev","length","persistedIds","map","_temp2","r_0","r","hydrate","signal_0","t5","t6","updater","updateCustomServers","t7","prev_0","record_0","removeCustomServer","t8","McpCustomServersResource","useMcpManagerResource","props","redirectUri","storageElement","_temp3","storageScopeKey","scopeId","undefined","_temp4","_temp5","c_0","c","kind","name","url","icon","auth","cache","elicitation","onRemove","_temp6","connectorElements","s_0","s","customElements","serverElements","lookup","all","state","_temp7","_temp8","servers","out","server","connectionState","tool","tools","fullName","type","description","parameters","inputSchema","execute","args","key","callTool","toolkit","clientRef","client","modelContext","register","getModelContext","t9","index","list","entry","Error","serverByKind","t10","t11","query","t12","t13","t14","index_0","t15","index_1","connectionTimeout_0","createdAt","Date","now","some","c_1","remove","releasePersistence","t16","getState","connector","customServer","addCustomServer","removeServer","McpManagerResource","scopes","parent","source","s_1","s_2"],"sources":["../../src/resources/McpManagerResource.ts"],"sourcesContent":["import {\n useState,\n useEffect,\n useMemo,\n useEffectEvent,\n useRef,\n useCallback,\n} from \"react\";\nimport { useResource, resource, withKey } from \"@assistant-ui/tap\";\nimport {\n useClientLookup,\n useAssistantClientRef,\n attachTransformScopes,\n type ClientOutput,\n} from \"@assistant-ui/store\";\nimport { useAssistantScopeEffect } from \"@assistant-ui/store/client\";\nimport { ModelContext } from \"@assistant-ui/core/store\";\nimport { createMcpId } from \"../utils/createMcpId\";\nimport { clearOAuthProviderAuthState } from \"../auth/createOAuthProvider\";\nimport type { Tool } from \"assistant-stream\";\nimport { McpServerResource } from \"./McpServerResource\";\nimport { withMcpServerRemovalFence } from \"./McpServerRemovalFence\";\nimport { McpLocalStorage } from \"./storage/McpLocalStorage\";\nimport type { MCPStorage, MCPStorageElement } from \"./storage/types\";\nimport { assertUniqueServerIds } from \"../utils/serverId\";\nimport type {\n MCPAuthConfig,\n MCPConnector,\n MCPCustomServerRecord,\n MCPManagerState,\n} from \"../mcp-scope\";\n\nexport type McpManagerResourceProps = {\n connectors?: MCPConnector[] | undefined;\n storage?: MCPStorageElement | undefined;\n /** OAuth redirect target. Defaults to `${origin}/mcp/callback`. */\n oauthRedirectUri?: string | undefined;\n /** Connect on mount when usable auth exists. Default true. */\n autoConnect?: boolean | undefined;\n /** Optional timeout in milliseconds for connect/listTools calls. Disabled by default. */\n connectionTimeout?: number | undefined;\n};\n\nfunction defaultRedirectUri(): string {\n if (typeof window === \"undefined\") return \"\";\n return `${window.location.origin}/mcp/callback`;\n}\n\n// Stable empty fallback so an absent `connectors` prop doesn't produce a fresh\n// array each render (which would invalidate the serverElements memo below).\nconst NO_CONNECTORS: MCPConnector[] = [];\n\nconst reportCustomStorageFailure = (\n operation: \"load\" | \"save\",\n error: unknown,\n) => {\n console.error(\n `[assistant-ui/react-mcp] failed to ${operation} custom servers:`,\n error,\n );\n};\n\nconst reportBlockedCustomServerPersistence = () => {\n console.error(\n \"[assistant-ui/react-mcp] custom server changes remain in memory because loading the persisted list failed; remount the manager to retry\",\n );\n};\n\nconst persistCustomServers = async (\n storage: MCPStorage,\n records: MCPCustomServerRecord[],\n) => {\n try {\n await storage.saveCustomServers(records);\n } catch (error) {\n reportCustomStorageFailure(\"save\", error);\n }\n};\n\ntype CustomServerPersistenceQueues = Map<string, Promise<void>>;\n\nconst enqueueCustomServerTask = (\n persistenceQueues: CustomServerPersistenceQueues,\n scopeKey: string,\n task: () => Promise<void>,\n) => {\n const previous = persistenceQueues.get(scopeKey);\n const next = (previous ?? Promise.resolve()).then(task);\n persistenceQueues.set(scopeKey, next);\n void next.then(() => {\n if (persistenceQueues.get(scopeKey) === next) {\n persistenceQueues.delete(scopeKey);\n }\n });\n};\n\nconst enqueueCustomServerPersistence = (\n persistenceQueues: CustomServerPersistenceQueues,\n scopeKey: string,\n storage: MCPStorage,\n records: MCPCustomServerRecord[],\n) =>\n enqueueCustomServerTask(persistenceQueues, scopeKey, () =>\n persistCustomServers(storage, records),\n );\n\nconst holdCustomServerPersistence = (\n persistenceQueues: CustomServerPersistenceQueues,\n scopeKey: string,\n) => {\n let release = () => {};\n const gate = new Promise<void>((resolve) => {\n release = resolve;\n });\n enqueueCustomServerTask(persistenceQueues, scopeKey, () => gate);\n return release;\n};\n\nconst deduplicateCustomServers = (records: MCPCustomServerRecord[]) => {\n const seen = new Set<string>();\n return records.filter((record) => {\n if (seen.has(record.id)) {\n console.error(\n `[assistant-ui/react-mcp] ignored duplicate custom server id \"${record.id}\" loaded from storage`,\n );\n return false;\n }\n seen.add(record.id);\n return true;\n });\n};\n\ntype McpCustomServersResourceProps = {\n storage: MCPStorage;\n scopeKey: string;\n persistenceQueues: CustomServerPersistenceQueues;\n};\n\nconst useMcpCustomServersResource = ({\n storage,\n scopeKey,\n persistenceQueues,\n}: McpCustomServersResourceProps) => {\n const [customServers, setCustomServers] = useState<MCPCustomServerRecord[]>(\n [],\n );\n const [isHydrated, setIsHydrated] = useState(false);\n\n const customServersRef = useRef<MCPCustomServerRecord[]>([]);\n const hydrationStateRef = useRef<\"pending\" | \"succeeded\" | \"failed\">(\n \"pending\",\n );\n const hasPendingMutationRef = useRef(false);\n const [removedBeforeHydration] = useState(() => new Set<string>());\n const reportedBlockedPersistenceRef = useRef(false);\n\n const hydrate = useEffectEvent(async (signal: { cancelled: boolean }) => {\n // A revisited scope must not read behind writes still queued against it.\n while (true) {\n const pendingPersistence = persistenceQueues.get(scopeKey);\n if (!pendingPersistence) break;\n await pendingPersistence;\n if (signal.cancelled) return;\n if (persistenceQueues.get(scopeKey) === pendingPersistence) break;\n }\n\n let records: Awaited<ReturnType<typeof storage.loadCustomServers>>;\n try {\n const loadedRecords = await storage.loadCustomServers();\n records = deduplicateCustomServers(loadedRecords);\n } catch (error) {\n if (!signal.cancelled) {\n reportCustomStorageFailure(\"load\", error);\n hydrationStateRef.current = \"failed\";\n if (hasPendingMutationRef.current) {\n reportBlockedCustomServerPersistence();\n reportedBlockedPersistenceRef.current = true;\n }\n setIsHydrated(true);\n }\n return;\n }\n // Merge rather than replace so any addCustomServer calls that\n // happened before hydration resolved aren't silently overwritten.\n // Persisted order wins; pre-hydration locals append.\n const hadPendingMutation = hasPendingMutationRef.current;\n const hydratedRecords = records.filter(\n (record) => !removedBeforeHydration.has(record.id),\n );\n const mergedRecords = (() => {\n const prev = customServersRef.current;\n if (prev.length === 0) return hydratedRecords;\n const persistedIds = new Set(hydratedRecords.map((r) => r.id));\n return [\n ...hydratedRecords,\n ...prev.filter((r) => !persistedIds.has(r.id)),\n ];\n })();\n customServersRef.current = mergedRecords;\n hydrationStateRef.current = \"succeeded\";\n hasPendingMutationRef.current = false;\n if (hadPendingMutation) {\n enqueueCustomServerPersistence(\n persistenceQueues,\n scopeKey,\n storage,\n mergedRecords,\n );\n }\n if (signal.cancelled) return;\n setCustomServers(mergedRecords);\n setIsHydrated(true);\n });\n\n useEffect(() => {\n const signal = { cancelled: false };\n // Hydration reads persisted records asynchronously; there is no earlier\n // point than mount at which to start it.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n void hydrate(signal);\n return () => {\n signal.cancelled = true;\n };\n }, []);\n\n const updateCustomServers = useCallback(\n (\n updater: (records: MCPCustomServerRecord[]) => MCPCustomServerRecord[],\n ) => {\n const next = updater(customServersRef.current);\n customServersRef.current = next;\n setCustomServers(next);\n\n if (hydrationStateRef.current === \"succeeded\") {\n enqueueCustomServerPersistence(\n persistenceQueues,\n scopeKey,\n storage,\n next,\n );\n return;\n }\n\n hasPendingMutationRef.current = true;\n if (\n hydrationStateRef.current === \"failed\" &&\n !reportedBlockedPersistenceRef.current\n ) {\n reportBlockedCustomServerPersistence();\n reportedBlockedPersistenceRef.current = true;\n }\n },\n [persistenceQueues, scopeKey, storage],\n );\n\n const removeCustomServer = useCallback(\n (id: string) => {\n if (hydrationStateRef.current === \"pending\") {\n removedBeforeHydration.add(id);\n }\n updateCustomServers((prev) => prev.filter((record) => record.id !== id));\n },\n [removedBeforeHydration, updateCustomServers],\n );\n\n return {\n customServers,\n isHydrated,\n updateCustomServers,\n removeCustomServer,\n };\n};\n\nconst McpCustomServersResource = resource(useMcpCustomServersResource);\n\nconst useMcpManagerResource = (\n props: McpManagerResourceProps,\n): ClientOutput<\"mcp\"> => {\n const connectors = props.connectors ?? NO_CONNECTORS;\n const autoConnect = props.autoConnect ?? true;\n const redirectUri = props.oauthRedirectUri ?? defaultRedirectUri();\n const connectionTimeout = props.connectionTimeout;\n\n const storageElement = props.storage ?? McpLocalStorage();\n const storage = useResource(storageElement);\n const [persistenceQueues] = useState<CustomServerPersistenceQueues>(\n () => new Map(),\n );\n const storageScopeKey =\n storage.scopeId === undefined ? \"unscoped\" : `scoped:${storage.scopeId}`;\n const { customServers, isHydrated, updateCustomServers, removeCustomServer } =\n useResource(\n withKey(\n storageScopeKey,\n McpCustomServersResource({\n storage,\n scopeKey: storageScopeKey,\n persistenceQueues,\n }),\n ),\n );\n\n const serverElements = useMemo(() => {\n assertUniqueServerIds([\n ...connectors.map((c) => c.id),\n ...customServers.map((s) => s.id),\n ]);\n\n const connectorElements = connectors.map((c) =>\n withKey(\n c.id,\n McpServerResource({\n id: c.id,\n kind: \"connector\",\n name: c.name,\n url: c.url,\n icon: c.icon,\n auth: c.auth,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout: c.connectionTimeout ?? connectionTimeout,\n ...(c.cache !== undefined ? { cache: c.cache } : {}),\n ...(c.elicitation !== undefined\n ? { elicitation: c.elicitation }\n : {}),\n onRemove: async () => {\n // connectors cannot be removed\n },\n }),\n ),\n );\n const customElements = customServers.map((s) =>\n withKey(\n s.id,\n McpServerResource(\n withMcpServerRemovalFence(\n {\n id: s.id,\n kind: \"custom\",\n name: s.name,\n url: s.url,\n auth: s.auth,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout: s.connectionTimeout ?? connectionTimeout,\n ...(s.cache !== undefined ? { cache: s.cache } : {}),\n ...(s.elicitation !== undefined\n ? { elicitation: s.elicitation }\n : {}),\n onRemove: async () => {\n removeCustomServer(s.id);\n },\n },\n () =>\n holdCustomServerPersistence(persistenceQueues, storageScopeKey),\n ),\n ),\n ),\n );\n return [...connectorElements, ...customElements];\n }, [\n connectors,\n customServers,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout,\n removeCustomServer,\n persistenceQueues,\n storageScopeKey,\n ]);\n\n const lookup = useClientLookup(serverElements);\n\n const state = useMemo<MCPManagerState>(() => {\n const all = lookup.state;\n return {\n servers: all,\n connectors: all.filter((s) => s.kind === \"connector\"),\n customServers: all.filter((s) => s.kind === \"custom\"),\n isHydrated,\n };\n }, [lookup.state, isHydrated]);\n\n // ─── Auto-register MCP tools as frontend tools in modelContext ─────\n // Build the toolkit from connected servers; re-register when the visible\n // tool surface changes. Tool names are prefixed with the server id to\n // avoid collisions across connected servers — connector ids must not\n // contain `__` (enforced by `defineConnector`); `addCustomServer`\n // generates UUIDs that satisfy the constraint by construction.\n const toolkit = useMemo<Record<string, Tool<any, any>>>(() => {\n const out: Record<string, Tool<any, any>> = {};\n for (const server of state.servers) {\n if (server.connectionState !== \"connected\") continue;\n for (const tool of server.tools) {\n const fullName = `${server.id}__${tool.name}`;\n out[fullName] = {\n type: \"frontend\",\n ...(tool.description !== undefined\n ? { description: tool.description }\n : {}),\n parameters: tool.inputSchema as never,\n execute: (args) =>\n lookup.get({ key: server.id }).callTool(tool.name, args as unknown),\n };\n }\n }\n return out;\n }, [state, lookup]);\n\n const clientRef = useAssistantClientRef();\n\n useAssistantScopeEffect(\n \"modelContext\",\n () => {\n const client = clientRef.current;\n if (!client) return;\n return client.modelContext.register({\n getModelContext: () => ({ tools: toolkit }),\n });\n },\n [toolkit],\n );\n\n const serverByKind = (kind: \"connector\" | \"custom\", index: number) => {\n const list = kind === \"connector\" ? state.connectors : state.customServers;\n const entry = list[index];\n if (!entry) {\n throw new Error(\n `McpManagerResource: no ${kind} at index ${index} (length ${list.length})`,\n );\n }\n return lookup.get({ key: entry.id });\n };\n\n return {\n getState: () => state,\n server: (query) => {\n if (\"id\" in query) return lookup.get({ key: query.id });\n return serverByKind(query.kind, query.index);\n },\n connector: ({ index }) => serverByKind(\"connector\", index),\n customServer: ({ index }) => serverByKind(\"custom\", index),\n addCustomServer: async ({\n name,\n url,\n auth,\n connectionTimeout,\n cache,\n elicitation,\n }) => {\n const record: MCPCustomServerRecord = {\n id: createMcpId(),\n name,\n url,\n auth: auth as MCPAuthConfig,\n connectionTimeout,\n ...(cache !== undefined ? { cache } : {}),\n ...(elicitation !== undefined ? { elicitation } : {}),\n createdAt: Date.now(),\n };\n updateCustomServers((prev) => [...prev, record]);\n return record.id;\n },\n removeServer: async (id) => {\n // removeServer is custom-server only — connectors are app-defined\n // and not user-removable. Refuse rather than silently no-op.\n if (state.connectors.some((c) => c.id === id)) {\n throw new Error(\n `Cannot remove connector \"${id}\" — connectors are app-defined and not removable. Use a custom server id instead.`,\n );\n }\n // Delegate to McpServerResource.remove() which disconnects,\n // clears auth state, and unregisters from customServers in one\n // place. Fallback to manual cleanup if the lookup is empty\n // (server already gone).\n try {\n await lookup.get({ key: id }).remove();\n } catch {\n const releasePersistence = holdCustomServerPersistence(\n persistenceQueues,\n storageScopeKey,\n );\n try {\n await clearOAuthProviderAuthState(storage, id);\n removeCustomServer(id);\n } catch (error) {\n releasePersistence();\n throw error;\n }\n releasePersistence();\n }\n },\n };\n};\n\nexport const McpManagerResource = resource(useMcpManagerResource);\n\n// Ensure modelContext exists as a sibling when the manager mounts. If an\n// ancestor (e.g. a chat runtime) already provides modelContext, this is a\n// no-op; otherwise it's auto-mounted alongside `mcp`.\nattachTransformScopes(useMcpManagerResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"McpManagerResource.js","names":["useState","useMemo","useResource","resource","withKey","useClientLookup","useAssistantClientRef","attachTransformScopes","ClientOutput","useAssistantScopeEffect","ModelContext","createMcpId","clearOAuthProviderAuthState","Tool","McpServerResource","McpCustomServersResource","holdCustomServerPersistence","CustomServerPersistenceQueues","withMcpServerRemovalFence","McpLocalStorage","MCPStorageElement","assertUniqueServerIds","MCPAuthConfig","MCPConnector","MCPCustomServerRecord","MCPManagerState","McpManagerResourceProps","connectors","storage","oauthRedirectUri","autoConnect","connectionTimeout","defaultRedirectUri","window","location","origin","NO_CONNECTORS","useMcpManagerResource","props","$","_c","t0","redirectUri","t1","storageElement","persistenceQueues","_temp","storageScopeKey","scopeId","undefined","t2","scopeKey","customServers","isHydrated","updateCustomServers","removeCustomServer","map","_temp2","_temp3","t3","t4","c_0","c","id","kind","name","url","icon","auth","cache","elicitation","onRemove","_temp4","connectorElements","t5","s_0","s","customElements","serverElements","lookup","all","state","filter","_temp5","_temp6","t6","servers","out","server","connectionState","tool","tools","fullName","type","description","parameters","inputSchema","execute","args","get","key","callTool","toolkit","clientRef","t7","client","current","modelContext","register","getModelContext","t8","t9","index","list","entry","Error","length","serverByKind","t10","t11","query","t12","t13","t14","index_0","t15","index_1","connectionTimeout_0","record","createdAt","Date","now","prev","some","c_1","remove","releasePersistence","t16","error","getState","connector","customServer","addCustomServer","removeServer","McpManagerResource","scopes","parent","source","Map","s_1","s_2","_c","storageElement","serverElements"],"sources":["../../src/resources/McpManagerResource.ts"],"sourcesContent":["import { useState, useMemo } from \"react\";\nimport { useResource, resource, withKey } from \"@assistant-ui/tap\";\nimport {\n useClientLookup,\n useAssistantClientRef,\n attachTransformScopes,\n type ClientOutput,\n} from \"@assistant-ui/store\";\nimport { useAssistantScopeEffect } from \"@assistant-ui/store/client\";\nimport { ModelContext } from \"@assistant-ui/core/store\";\nimport { createMcpId } from \"../utils/createMcpId\";\nimport { clearOAuthProviderAuthState } from \"../auth/createOAuthProvider\";\nimport type { Tool } from \"assistant-stream\";\nimport { McpServerResource } from \"./McpServerResource\";\nimport {\n McpCustomServersResource,\n holdCustomServerPersistence,\n type CustomServerPersistenceQueues,\n} from \"./McpCustomServerPersistence\";\nimport { withMcpServerRemovalFence } from \"./McpServerRemovalFence\";\nimport { McpLocalStorage } from \"./storage/McpLocalStorage\";\nimport type { MCPStorageElement } from \"./storage/types\";\nimport { assertUniqueServerIds } from \"../utils/serverId\";\nimport type {\n MCPAuthConfig,\n MCPConnector,\n MCPCustomServerRecord,\n MCPManagerState,\n} from \"../mcp-scope\";\n\nexport type McpManagerResourceProps = {\n connectors?: MCPConnector[] | undefined;\n storage?: MCPStorageElement | undefined;\n /** OAuth redirect target. Defaults to `${origin}/mcp/callback`. */\n oauthRedirectUri?: string | undefined;\n /** Connect on mount when usable auth exists. Default true. */\n autoConnect?: boolean | undefined;\n /** Optional timeout in milliseconds for connect/listTools calls. Disabled by default. */\n connectionTimeout?: number | undefined;\n};\n\nfunction defaultRedirectUri(): string {\n if (typeof window === \"undefined\") return \"\";\n return `${window.location.origin}/mcp/callback`;\n}\n\n// Stable empty fallback so an absent `connectors` prop doesn't produce a fresh\n// array each render (which would invalidate the serverElements memo below).\nconst NO_CONNECTORS: MCPConnector[] = [];\n\nconst useMcpManagerResource = (\n props: McpManagerResourceProps,\n): ClientOutput<\"mcp\"> => {\n const connectors = props.connectors ?? NO_CONNECTORS;\n const autoConnect = props.autoConnect ?? true;\n const redirectUri = props.oauthRedirectUri ?? defaultRedirectUri();\n const connectionTimeout = props.connectionTimeout;\n\n const storageElement = props.storage ?? McpLocalStorage();\n const storage = useResource(storageElement);\n const [persistenceQueues] = useState<CustomServerPersistenceQueues>(\n () => new Map(),\n );\n const storageScopeKey =\n storage.scopeId === undefined ? \"unscoped\" : `scoped:${storage.scopeId}`;\n const { customServers, isHydrated, updateCustomServers, removeCustomServer } =\n useResource(\n withKey(\n storageScopeKey,\n McpCustomServersResource({\n storage,\n scopeKey: storageScopeKey,\n persistenceQueues,\n }),\n ),\n );\n\n const serverElements = useMemo(() => {\n assertUniqueServerIds([\n ...connectors.map((c) => c.id),\n ...customServers.map((s) => s.id),\n ]);\n\n const connectorElements = connectors.map((c) =>\n withKey(\n c.id,\n McpServerResource({\n id: c.id,\n kind: \"connector\",\n name: c.name,\n url: c.url,\n icon: c.icon,\n auth: c.auth,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout: c.connectionTimeout ?? connectionTimeout,\n ...(c.cache !== undefined ? { cache: c.cache } : {}),\n ...(c.elicitation !== undefined\n ? { elicitation: c.elicitation }\n : {}),\n onRemove: async () => {\n // connectors cannot be removed\n },\n }),\n ),\n );\n const customElements = customServers.map((s) =>\n withKey(\n s.id,\n McpServerResource(\n withMcpServerRemovalFence(\n {\n id: s.id,\n kind: \"custom\",\n name: s.name,\n url: s.url,\n auth: s.auth,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout: s.connectionTimeout ?? connectionTimeout,\n ...(s.cache !== undefined ? { cache: s.cache } : {}),\n ...(s.elicitation !== undefined\n ? { elicitation: s.elicitation }\n : {}),\n onRemove: async () => {\n removeCustomServer(s.id);\n },\n },\n () =>\n holdCustomServerPersistence(persistenceQueues, storageScopeKey),\n ),\n ),\n ),\n );\n return [...connectorElements, ...customElements];\n }, [\n connectors,\n customServers,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout,\n removeCustomServer,\n persistenceQueues,\n storageScopeKey,\n ]);\n\n const lookup = useClientLookup(serverElements);\n\n const state = useMemo<MCPManagerState>(() => {\n const all = lookup.state;\n return {\n servers: all,\n connectors: all.filter((s) => s.kind === \"connector\"),\n customServers: all.filter((s) => s.kind === \"custom\"),\n isHydrated,\n };\n }, [lookup.state, isHydrated]);\n\n // ─── Auto-register MCP tools as frontend tools in modelContext ─────\n // Build the toolkit from connected servers; re-register when the visible\n // tool surface changes. Tool names are prefixed with the server id to\n // avoid collisions across connected servers — connector ids must not\n // contain `__` (enforced by `defineConnector`); `addCustomServer`\n // generates UUIDs that satisfy the constraint by construction.\n const toolkit = useMemo<Record<string, Tool<any, any>>>(() => {\n const out: Record<string, Tool<any, any>> = {};\n for (const server of state.servers) {\n if (server.connectionState !== \"connected\") continue;\n for (const tool of server.tools) {\n const fullName = `${server.id}__${tool.name}`;\n out[fullName] = {\n type: \"frontend\",\n ...(tool.description !== undefined\n ? { description: tool.description }\n : {}),\n parameters: tool.inputSchema as never,\n execute: (args) =>\n lookup.get({ key: server.id }).callTool(tool.name, args as unknown),\n };\n }\n }\n return out;\n }, [state, lookup]);\n\n const clientRef = useAssistantClientRef();\n\n useAssistantScopeEffect(\n \"modelContext\",\n () => {\n const client = clientRef.current;\n if (!client) return;\n return client.modelContext.register({\n getModelContext: () => ({ tools: toolkit }),\n });\n },\n [toolkit],\n );\n\n const serverByKind = (kind: \"connector\" | \"custom\", index: number) => {\n const list = kind === \"connector\" ? state.connectors : state.customServers;\n const entry = list[index];\n if (!entry) {\n throw new Error(\n `McpManagerResource: no ${kind} at index ${index} (length ${list.length})`,\n );\n }\n return lookup.get({ key: entry.id });\n };\n\n return {\n getState: () => state,\n server: (query) => {\n if (\"id\" in query) return lookup.get({ key: query.id });\n return serverByKind(query.kind, query.index);\n },\n connector: ({ index }) => serverByKind(\"connector\", index),\n customServer: ({ index }) => serverByKind(\"custom\", index),\n addCustomServer: async ({\n name,\n url,\n auth,\n connectionTimeout,\n cache,\n elicitation,\n }) => {\n const record: MCPCustomServerRecord = {\n id: createMcpId(),\n name,\n url,\n auth: auth as MCPAuthConfig,\n connectionTimeout,\n ...(cache !== undefined ? { cache } : {}),\n ...(elicitation !== undefined ? { elicitation } : {}),\n createdAt: Date.now(),\n };\n updateCustomServers((prev) => [...prev, record]);\n return record.id;\n },\n removeServer: async (id) => {\n // removeServer is custom-server only — connectors are app-defined\n // and not user-removable. Refuse rather than silently no-op.\n if (state.connectors.some((c) => c.id === id)) {\n throw new Error(\n `Cannot remove connector \"${id}\" — connectors are app-defined and not removable. Use a custom server id instead.`,\n );\n }\n let server;\n try {\n server = lookup.get({ key: id });\n } catch {\n server = undefined;\n }\n if (server) {\n await server.remove();\n return;\n }\n const releasePersistence = holdCustomServerPersistence(\n persistenceQueues,\n storageScopeKey,\n );\n try {\n await clearOAuthProviderAuthState(storage, id);\n removeCustomServer(id);\n } catch (error) {\n releasePersistence();\n throw error;\n }\n releasePersistence();\n },\n };\n};\n\nexport const McpManagerResource = resource(useMcpManagerResource);\n\n// Ensure modelContext exists as a sibling when the manager mounts. If an\n// ancestor (e.g. a chat runtime) already provides modelContext, this is a\n// no-op; otherwise it's auto-mounted alongside `mcp`.\nattachTransformScopes(useMcpManagerResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":";;;;;;;;;;;;;;AAyCA,SAASgC,qBAA6B;CACpC,IAAI,OAAOC,WAAW,aAAa,OAAO;CAC1C,OAAO,GAAGA,OAAOC,SAASC,OAAM;AAClC;AAIA,MAAMC,gBAAgC,CAAA;AAEtC,MAAMC,yBAAwBC,UAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAG5B,MAAAb,aAAmBW,MAAKX,cAALS;CACnB,MAAAN,cAAoBQ,MAAKR,eAAL;CAA0B,IAAAW;CAAA,IAAAF,EAAA,OAAAD,MAAAT,kBAAA;EAC1BY,KAAAH,MAAKT,oBAAqBG,mBAAmB;EAACO,EAAA,KAAAD,MAAAT;EAAAU,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAlE,MAAAG,cAAoBD;CACpB,MAAAV,oBAA0BO,MAAKP;CAAmB,IAAAY;CAAA,IAAAJ,EAAA,OAAAD,MAAAV,SAAA;EAE3Be,KAAAL,MAAKV,WAAYT,gBAAgB;EAACoB,EAAA,KAAAD,MAAAV;EAAAW,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CACzD,MAAAX,UAAgB1B,YAAY0C,EAAc;CAC1C,MAAA,CAAAC,qBAA4B7C,SAC1B8C,KACF;CACA,MAAAC,kBACEnB,QAAOoB,YAAaC,KAAAA,IAApB,aAAA,UAAuDrB,QAAOoB;CAAW,IAAAE;CAAA,IAAAX,EAAA,OAAAM,qBAAAN,EAAA,OAAAX,WAAAW,EAAA,OAAAQ,iBAAA;EAGvEG,KAAA9C,QACE2C,iBACAhC,yBAAyB;GAAAa;GAAAuB,UAEbJ;GAAeF;EAE3B,CAAC,CACH;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAX;EAAAW,EAAA,KAAAQ;EAAAR,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CATL,MAAA,EAAAa,eAAAC,YAAAC,qBAAAC,uBACErD,YACEgD,EAQF;CAGA7B,sBAAsB,CAAA,GACjBM,WAAU6B,IAAKC,MAAW,GAAC,GAC3BL,cAAaI,IAAKE,MAAW,CAAC,CAClC;CAAC,IAAAC;CAAA,IAAApB,EAAA,OAAAT,eAAAS,EAAA,OAAAR,qBAAAQ,EAAA,QAAAZ,cAAAY,EAAA,QAAAa,iBAAAb,EAAA,QAAAM,qBAAAN,EAAA,QAAAG,eAAAH,EAAA,QAAAgB,sBAAAhB,EAAA,QAAAX,WAAAW,EAAA,QAAAQ,iBAAA;EAAA,IAAAa;EAAA,IAAArB,EAAA,QAAAT,eAAAS,EAAA,QAAAR,qBAAAQ,EAAA,QAAAG,eAAAH,EAAA,QAAAX,SAAA;GAEuCgC,MAAAC,QACvCzD,QACE0D,IAACC,IACDjD,kBAAkB;IAAAiD,IACZD,IAACC;IAAGC,MACF;IAAWC,MACXH,IAACG;IAAKC,KACPJ,IAACI;IAAIC,MACJL,IAACK;IAAKC,MACNN,IAACM;IAAKxC;IAAAc;IAAAZ;IAAAC,mBAIO+B,IAAC/B,qBAADA;IAAwC,GACvD+B,IAACO,UAAWpB,KAAAA,IAAZ,EAAAoB,OAAiCP,IAACO,MAAY,IAA9C,CAA8C;IAAC,GAC/CP,IAACQ,gBAAiBrB,KAAAA,IAAlB,EAAAqB,aACeR,IAACQ,YACf,IAFD,CAEC;IAACC,UACIC;GAGZ,CAAC,CACH;GAACjC,EAAA,MAAAT;GAAAS,EAAA,MAAAR;GAAAQ,EAAA,MAAAG;GAAAH,EAAA,MAAAX;GAAAW,EAAA,MAAAqB;EAAA,OAAAA,KAAArB,EAAA;EAtBH,MAAAkC,oBAA0B9C,WAAU6B,IAAKI,EAuBzC;EAAE,IAAAc;EAAA,IAAAnC,EAAA,QAAAT,eAAAS,EAAA,QAAAR,qBAAAQ,EAAA,QAAAM,qBAAAN,EAAA,QAAAG,eAAAH,EAAA,QAAAgB,sBAAAhB,EAAA,QAAAX,WAAAW,EAAA,QAAAQ,iBAAA;GACuC2B,MAAAC,QACvCvE,QACEwE,IAACb,IACDjD,kBACEI,0BACE;IAAA6C,IACMa,IAACb;IAAGC,MACF;IAAQC,MACRW,IAACX;IAAKC,KACPU,IAACV;IAAIE,MACJQ,IAACR;IAAKxC;IAAAc;IAAAZ;IAAAC,mBAIO6C,IAAC7C,qBAADA;IAAwC,GACvD6C,IAACP,UAAWpB,KAAAA,IAAZ,EAAAoB,OAAiCO,IAACP,MAAY,IAA9C,CAA8C;IAAC,GAC/CO,IAACN,gBAAiBrB,KAAAA,IAAlB,EAAAqB,aACeM,IAACN,YACf,IAFD,CAEC;IAACC,UACI,YAAA;KACRhB,mBAAmBqB,IAACb,EAAG;IAAC;GAE5B,SAEE/C,4BAA4B6B,mBAAmBE,eAAe,CAClE,CACF,CACF;GAACR,EAAA,MAAAT;GAAAS,EAAA,MAAAR;GAAAQ,EAAA,MAAAM;GAAAN,EAAA,MAAAG;GAAAH,EAAA,MAAAgB;GAAAhB,EAAA,MAAAX;GAAAW,EAAA,MAAAQ;GAAAR,EAAA,MAAAmC;EAAA,OAAAA,KAAAnC,EAAA;EA3BH,MAAAsC,iBAAuBzB,cAAaI,IAAKkB,EA4BzC;EACOf,KAAA,CAAA,GAAIc,mBAAiB,GAAKI,cAAc;EAACtC,EAAA,KAAAT;EAAAS,EAAA,KAAAR;EAAAQ,EAAA,MAAAZ;EAAAY,EAAA,MAAAa;EAAAb,EAAA,MAAAM;EAAAN,EAAA,MAAAG;EAAAH,EAAA,MAAAgB;EAAAhB,EAAA,MAAAX;EAAAW,EAAA,MAAAQ;EAAAR,EAAA,MAAAoB;CAAA,OAAAA,KAAApB,EAAA;CAalD,MAAAwC,SAAe1E,gBAAgByE,EAAc;CAG3C,MAAAE,MAAYD,OAAME;CAAO,IAAArB;CAAA,IAAArB,EAAA,QAAAyC,KAAA;EAGXpB,KAAAoB,IAAGE,OAAQC,MAA6B;EAAC5C,EAAA,MAAAyC;EAAAzC,EAAA,MAAAqB;CAAA,OAAAA,KAAArB,EAAA;CAAA,IAAAmC;CAAA,IAAAnC,EAAA,QAAAyC,KAAA;EACtCN,KAAAM,IAAGE,OAAQE,MAA0B;EAAC7C,EAAA,MAAAyC;EAAAzC,EAAA,MAAAmC;CAAA,OAAAA,KAAAnC,EAAA;CAAA,IAAA8C;CAAA,IAAA9C,EAAA,QAAAyC,OAAAzC,EAAA,QAAAc,cAAAd,EAAA,QAAAqB,MAAArB,EAAA,QAAAmC,IAAA;EAHhDW,KAAA;GAAAC,SACIN;GAAGrD,YACAiC;GAAyCR,eACtCsB;GAAsCrB;EAEvD;EAACd,EAAA,MAAAyC;EAAAzC,EAAA,MAAAc;EAAAd,EAAA,MAAAqB;EAAArB,EAAA,MAAAmC;EAAAnC,EAAA,MAAA8C;CAAA,OAAAA,KAAA9C,EAAA;CAPH,MAAA0C,QAEEI;CAM6B,IAAAE;CAAA,IAAAhD,EAAA,QAAAwC,UAAAxC,EAAA,QAAA0C,MAAAK,SAAA;EAS7BC,MAA4C,CAAC;EAC7C,KAAK,MAAAC,UAAgBP,MAAKK,SAAQ;GAChC,IAAIE,OAAMC,oBAAqB,aAAa;GAC5C,KAAK,MAAAC,QAAcF,OAAMG,OAAM;IAC7B,MAAAC,WAAiB,GAAGJ,OAAMzB,GAAG,IAAK2B,KAAIzB;IACtCsB,IAAIK,YAAY;KAAAC,MACR;KAAU,GACZH,KAAII,gBAAiB7C,KAAAA,IAArB,EAAA6C,aACeJ,KAAII,YAClB,IAFD,CAEC;KAACC,YACML,KAAIM;KAAqBC,UAC5BC,SACPnB,OAAMoB,IAAK,EAAAC,KAAOZ,OAAMzB,GAAI,CAAC,CAAC,CAAAsC,SAAUX,KAAIzB,MAAOiC,IAAe;IACtE;GARa;EASd;EACF3D,EAAA,MAAAwC;EAAAxC,EAAA,MAAA0C,MAAAK;EAAA/C,EAAA,MAAAgD;CAAA,OAAAA,MAAAhD,EAAA;CAhBH,MAAA+D,UAiBEf;CAGF,MAAAgB,YAAkBjG,sBAAsB;CAAE,IAAAkG;CAAA,IAAAjE,EAAA,QAAAgE,aAAAhE,EAAA,QAAA+D,SAAA;EAIxCE,WAAA;GACE,MAAAC,SAAeF,UAASG;GACxB,IAAI,CAACD,QAAM;GAAS,OACbA,OAAME,aAAaC,SAAU,EAAAC,wBACV,EAAAlB,OAASW,QAAQ,GAC3C,CAAC;EAAC;EACH/D,EAAA,MAAAgE;EAAAhE,EAAA,MAAA+D;EAAA/D,EAAA,MAAAiE;CAAA,OAAAA,KAAAjE,EAAA;CAAA,IAAAuE;CAAA,IAAAvE,EAAA,QAAA+D,SAAA;EACDQ,KAAA,CAACR,OAAO;EAAC/D,EAAA,MAAA+D;EAAA/D,EAAA,MAAAuE;CAAA,OAAAA,KAAAvE,EAAA;CATX9B,wBACE,gBACA+F,IAOAM,EACF;CAAC,IAAAC;CAAA,IAAAxE,EAAA,QAAAwC,UAAAxC,EAAA,QAAA0C,OAAA;EAEoB8B,MAAA/C,MAAAgD,UAAA;GACnB,MAAAC,OAAajD,SAAS,cAAciB,MAAKtD,aAAcsD,MAAK7B;GAC5D,MAAA8D,QAAcD,KAAKD;GACnB,IAAI,CAACE,OACH,MAAM,IAAIC,MACR,0BAA0BnD,KAAI,YAAagD,MAAK,WAAYC,KAAIG,OAAO,EACzE;GACD,OACMrC,OAAMoB,IAAK,EAAAC,KAAOc,MAAKnD,GAAI,CAAC;EAAC;EACrCxB,EAAA,MAAAwC;EAAAxC,EAAA,MAAA0C;EAAA1C,EAAA,MAAAwE;CAAA,OAAAA,KAAAxE,EAAA;CATD,MAAA8E,eAAqBN;CASnB,IAAAO;CAAA,IAAA/E,EAAA,QAAA0C,OAAA;EAGUqC,YAAMrC;EAAK1C,EAAA,MAAA0C;EAAA1C,EAAA,MAAA+E;CAAA,OAAAA,MAAA/E,EAAA;CAAA,IAAAgF;CAAA,IAAAhF,EAAA,QAAAwC,UAAAxC,EAAA,QAAA8E,cAAA;EACbE,OAAAC,UAAA;GACN,IAAI,QAAQA,OAAK,OAASzC,OAAMoB,IAAK,EAAAC,KAAOoB,MAAKzD,GAAI,CAAC;GAAE,OACjDsD,aAAaG,MAAKxD,MAAOwD,MAAKR,KAAM;EAAC;EAC7CzE,EAAA,MAAAwC;EAAAxC,EAAA,MAAA8E;EAAA9E,EAAA,MAAAgF;CAAA,OAAAA,MAAAhF,EAAA;CAAA,IAAAkF;CAAA,IAAAC;CAAA,IAAAnF,EAAA,QAAA8E,cAAA;EACUI,OAAAE,QAAA;GAAC,MAAA,EAAAX,OAAAY,YAAAD;GAAS,OAAKN,aAAa,aAAaL,OAAK;EAAC;EAC5CU,OAAAG,QAAA;GAAC,MAAA,EAAAb,OAAAc,YAAAD;GAAS,OAAKR,aAAa,UAAUL,OAAK;EAAC;EAAAzE,EAAA,MAAA8E;EAAA9E,EAAA,MAAAkF;EAAAlF,EAAA,MAAAmF;CAAA,OAAA;EAAAD,MAAAlF,EAAA;EAAAmF,MAAAnF,EAAA;CAAA;CAAA,IAAAoF;CAAA,IAAApF,EAAA,QAAAe,qBAAA;EACzCqE,MAAA,OAAAE,QAAA;GAAO,MAAA,EAAA5D,MAAAC,KAAAE,MAAArC,mBAAAgG,qBAAA1D,OAAAC,gBAAAuD;GAQtB,MAAAG,SAAsC;IAAAjE,IAChCpD,YAAY;IAACsD;IAAAC;IAGXE;IAAqBrC,mBAC3BA;IAAiB,GACbsC,UAAUpB,KAAAA,IAAV,EAAAoB,MAAmC,IAAnC,CAAmC;IAAC,GACpCC,gBAAgBrB,KAAAA,IAAhB,EAAAqB,YAA+C,IAA/C,CAA+C;IAAC2D,WACzCC,KAAIC,IAAK;GACtB;GACA7E,qBAAoB8E,SAAU,CAAA,GAAIA,MAAMJ,MAAM,CAAC;GAAC,OACzCA,OAAMjE;EAAG;EACjBxB,EAAA,MAAAe;EAAAf,EAAA,MAAAoF;CAAA,OAAAA,MAAApF,EAAA;CAAA,IAAAsF;CAAA,IAAAtF,EAAA,QAAAwC,UAAAxC,EAAA,QAAAM,qBAAAN,EAAA,QAAAgB,sBAAAhB,EAAA,QAAA0C,SAAA1C,EAAA,QAAAX,WAAAW,EAAA,QAAAQ,iBAAA;EACa8E,MAAA,OAAA9D,OAAA;GAGZ,IAAIkB,MAAKtD,WAAW0G,MAAMC,QAAOxE,IAACC,OAAQA,EAAE,GAC1C,MAAM,IAAIoD,MACR,4BAA4BpD,GAAE,kFAChC;GAEEyB,IAAAA;GACJ,IAAA;IACEA,WAAST,OAAMoB,IAAK,EAAAC,KAAOrC,GAAG,CAAC;GAAzB,QAAA;IAENyB,WAASvC,KAAAA;GAAH;GAER,IAAIuC,UAAM;IACR,MAAMA,SAAM+C,OAAQ;IAAC;GAAA;GAGvB,MAAAC,qBAA2BxH,4BACzB6B,mBACAE,eACF;GACA,IAAA;IACE,MAAMnC,4BAA4BgB,SAASmC,EAAE;IAC7CR,mBAAmBQ,EAAE;GAAC,SAAA0E,KAAA;IACfC,MAAAA,QAAAA;IACPF,mBAAmB;IACnB,MAAME;GAAM;GAEdF,mBAAmB;EAAC;EACrBjG,EAAA,MAAAwC;EAAAxC,EAAA,MAAAM;EAAAN,EAAA,MAAAgB;EAAAhB,EAAA,MAAA0C;EAAA1C,EAAA,MAAAX;EAAAW,EAAA,MAAAQ;EAAAR,EAAA,MAAAsF;CAAA,OAAAA,MAAAtF,EAAA;CAAA,IAAAkG;CAAA,IAAAlG,EAAA,QAAA+E,OAAA/E,EAAA,QAAAgF,OAAAhF,EAAA,QAAAkF,OAAAlF,EAAA,QAAAmF,OAAAnF,EAAA,QAAAoF,OAAApF,EAAA,QAAAsF,KAAA;EA3DIY,MAAA;GAAAE,UACKrB;GAAW9B,QACb+B;GAGPqB,WACUnB;GAA+CoB,cAC5CnB;GAA4CoB,iBACzCnB;GAoBhBoB,cACalB;EA+BhB;EAACtF,EAAA,MAAA+E;EAAA/E,EAAA,MAAAgF;EAAAhF,EAAA,MAAAkF;EAAAlF,EAAA,MAAAmF;EAAAnF,EAAA,MAAAoF;EAAApF,EAAA,MAAAsF;EAAAtF,EAAA,MAAAkG;CAAA,OAAAA,MAAAlG,EAAA;CAAA,OA5DMkG;AA4DN;AAGH,MAAaO,qBAAqB7I,SAASkC,qBAAqB;AAKhE9B,sBAAsB8B,wBAAwB4G,QAAQC,WAAW;CAC/D,IAAI,CAACD,OAAOtC,gBAAgBuC,OAAOvC,aAAawC,WAAW,MACzDF,OAAOtC,eAAejG,aAAa;AAEvC,CAAC;AA1O6B,SAAAoC,QAAA;CAAA,uBAWpB,IAAIsG,IAAI;AAAC;AAXW,SAAA3F,OAAAK,GAAA;CAAA,OA6BCA,EAACC;AAAG;AA7BL,SAAAL,OAAAkB,GAAA;CAAA,OA8BIA,EAACb;AAAG;AA9BR,eAAAS,SAAA,CAAA;AAAA,SAAAW,OAAAkE,KAAA;CAAA,OAyGMzE,IAACZ,SAAU;AAAW;AAzG5B,SAAAoB,OAAAkE,KAAA;CAAA,OA0GS1E,IAACZ,SAAU;AAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"McpServerResource.d.ts","sourceRoot":"","sources":["../../src/resources/McpServerResource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAuBxD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAwB;AAClD,OAAO,KAAK,EACV,aAAa,EAIb,aAAa,EAGd,wBAAqB;AAItB,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,yBAAyB,GACpC,OAAO,sBAAsB,KAC5B,SAAS,OAAO,EA2BlB,CAAC;AAqrBF,eAAO,MAAM,iBAAiB,kGAwB5B,CAAC"}
1
+ {"version":3,"file":"McpServerResource.d.ts","sourceRoot":"","sources":["../../src/resources/McpServerResource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAqBxD,OAAO,KAAK,EAAE,UAAU,EAAE,2BAAwB;AAClD,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EAGd,wBAAqB;AAItB,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,yBAAyB,GACpC,OAAO,sBAAsB,KAC5B,SAAS,OAAO,EA2BlB,CAAC;AAikBF,eAAO,MAAM,iBAAiB,kGAwB5B,CAAC"}