@assistant-ui/react-mcp 0.1.3 → 0.1.5
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.
- package/dist/context/McpConnectorByIndexProvider.js +16 -19
- package/dist/context/McpConnectorByIndexProvider.js.map +1 -1
- package/dist/context/McpCustomServerByIndexProvider.js +16 -19
- package/dist/context/McpCustomServerByIndexProvider.js.map +1 -1
- package/dist/context/McpServerByIdProvider.js +16 -19
- package/dist/context/McpServerByIdProvider.js.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.d.ts.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.js +21 -6
- package/dist/hooks/useMcpOAuthCallback.js.map +1 -1
- package/dist/primitives/server/McpServerRemoveButton.js +2 -1
- package/dist/primitives/server/McpServerRemoveButton.js.map +1 -1
- package/dist/resources/McpManagerResource.d.ts.map +1 -1
- package/dist/resources/McpManagerResource.js +155 -139
- package/dist/resources/McpManagerResource.js.map +1 -1
- package/dist/resources/McpServerResource.d.ts.map +1 -1
- package/dist/resources/McpServerResource.js +7 -2
- package/dist/resources/McpServerResource.js.map +1 -1
- package/package.json +16 -13
- package/src/context/McpConnectorByIndexProvider.tsx +8 -4
- package/src/context/McpCustomServerByIndexProvider.tsx +8 -4
- package/src/context/McpServerByIdProvider.tsx +8 -4
- package/src/hooks/useMcpOAuthCallback.test.ts +101 -2
- package/src/hooks/useMcpOAuthCallback.tsx +41 -5
- package/src/primitives/server/McpServerRemoveButton.test.tsx +71 -0
- package/src/primitives/server/McpServerRemoveButton.tsx +1 -1
- package/src/resources/McpManagerResource.test.ts +108 -1
- package/src/resources/McpManagerResource.ts +23 -13
- package/src/resources/McpServerResource.test.ts +37 -3
- package/src/resources/McpServerResource.ts +9 -2
- package/LICENSE +0 -21
|
@@ -15,6 +15,13 @@ const NO_CONNECTORS = [];
|
|
|
15
15
|
const reportCustomStorageFailure = (operation, error) => {
|
|
16
16
|
console.error(`[assistant-ui/react-mcp] failed to ${operation} custom servers:`, error);
|
|
17
17
|
};
|
|
18
|
+
const persistCustomServers = async (storage, records) => {
|
|
19
|
+
try {
|
|
20
|
+
await storage.saveCustomServers(records);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
reportCustomStorageFailure("save", error);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
18
25
|
const useMcpManagerResource = (props) => {
|
|
19
26
|
const $ = c(72);
|
|
20
27
|
const connectors = props.connectors ?? NO_CONNECTORS;
|
|
@@ -42,9 +49,31 @@ const useMcpManagerResource = (props) => {
|
|
|
42
49
|
const [customServers, setCustomServers] = useState(t2);
|
|
43
50
|
const [isHydrated, setIsHydrated] = useState(false);
|
|
44
51
|
const hydratedRef = useRef(false);
|
|
52
|
+
const storageRef = useRef(storage);
|
|
45
53
|
let t3;
|
|
46
|
-
if ($[5]
|
|
47
|
-
t3 =
|
|
54
|
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
55
|
+
t3 = Promise.resolve();
|
|
56
|
+
$[5] = t3;
|
|
57
|
+
} else t3 = $[5];
|
|
58
|
+
const persistenceQueueRef = useRef(t3);
|
|
59
|
+
let t4;
|
|
60
|
+
let t5;
|
|
61
|
+
if ($[6] !== storage) {
|
|
62
|
+
t4 = () => {
|
|
63
|
+
storageRef.current = storage;
|
|
64
|
+
};
|
|
65
|
+
t5 = [storage];
|
|
66
|
+
$[6] = storage;
|
|
67
|
+
$[7] = t4;
|
|
68
|
+
$[8] = t5;
|
|
69
|
+
} else {
|
|
70
|
+
t4 = $[7];
|
|
71
|
+
t5 = $[8];
|
|
72
|
+
}
|
|
73
|
+
useEffect(t4, t5);
|
|
74
|
+
let t6;
|
|
75
|
+
if ($[9] !== storage) {
|
|
76
|
+
t6 = async (signal) => {
|
|
48
77
|
const markHydrated = () => {
|
|
49
78
|
if (!signal.cancelled) {
|
|
50
79
|
hydratedRef.current = true;
|
|
@@ -54,8 +83,8 @@ const useMcpManagerResource = (props) => {
|
|
|
54
83
|
let records;
|
|
55
84
|
try {
|
|
56
85
|
records = await storage.loadCustomServers();
|
|
57
|
-
} catch (
|
|
58
|
-
const error =
|
|
86
|
+
} catch (t7) {
|
|
87
|
+
const error = t7;
|
|
59
88
|
if (!signal.cancelled) reportCustomStorageFailure("load", error);
|
|
60
89
|
markHydrated();
|
|
61
90
|
return;
|
|
@@ -68,64 +97,51 @@ const useMcpManagerResource = (props) => {
|
|
|
68
97
|
});
|
|
69
98
|
markHydrated();
|
|
70
99
|
};
|
|
71
|
-
$[
|
|
72
|
-
$[
|
|
73
|
-
} else
|
|
74
|
-
const hydrate = useEffectEvent(
|
|
75
|
-
let
|
|
76
|
-
if ($[
|
|
77
|
-
|
|
100
|
+
$[9] = storage;
|
|
101
|
+
$[10] = t6;
|
|
102
|
+
} else t6 = $[10];
|
|
103
|
+
const hydrate = useEffectEvent(t6);
|
|
104
|
+
let t7;
|
|
105
|
+
if ($[11] !== hydrate) {
|
|
106
|
+
t7 = () => {
|
|
78
107
|
const signal_0 = { cancelled: false };
|
|
79
108
|
hydrate(signal_0);
|
|
80
109
|
return () => {
|
|
81
110
|
signal_0.cancelled = true;
|
|
82
111
|
};
|
|
83
112
|
};
|
|
84
|
-
$[
|
|
85
|
-
$[
|
|
86
|
-
} else
|
|
87
|
-
let t5;
|
|
88
|
-
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
89
|
-
t5 = [];
|
|
90
|
-
$[9] = t5;
|
|
91
|
-
} else t5 = $[9];
|
|
92
|
-
useEffect(t4, t5);
|
|
93
|
-
let t6;
|
|
94
|
-
if ($[10] !== storage) {
|
|
95
|
-
t6 = async (records_0) => {
|
|
96
|
-
if (!hydratedRef.current) return;
|
|
97
|
-
try {
|
|
98
|
-
await storage.saveCustomServers(records_0);
|
|
99
|
-
} catch (t7) {
|
|
100
|
-
reportCustomStorageFailure("save", t7);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
$[10] = storage;
|
|
104
|
-
$[11] = t6;
|
|
105
|
-
} else t6 = $[11];
|
|
106
|
-
const persistCustomServers = useEffectEvent(t6);
|
|
107
|
-
let t7;
|
|
108
|
-
if ($[12] !== customServers || $[13] !== persistCustomServers) {
|
|
109
|
-
t7 = () => {
|
|
110
|
-
persistCustomServers(customServers);
|
|
111
|
-
};
|
|
112
|
-
$[12] = customServers;
|
|
113
|
-
$[13] = persistCustomServers;
|
|
114
|
-
$[14] = t7;
|
|
115
|
-
} else t7 = $[14];
|
|
113
|
+
$[11] = hydrate;
|
|
114
|
+
$[12] = t7;
|
|
115
|
+
} else t7 = $[12];
|
|
116
116
|
let t8;
|
|
117
|
-
if ($[
|
|
118
|
-
t8 = [
|
|
119
|
-
$[
|
|
120
|
-
|
|
121
|
-
} else t8 = $[16];
|
|
117
|
+
if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
|
|
118
|
+
t8 = [];
|
|
119
|
+
$[13] = t8;
|
|
120
|
+
} else t8 = $[13];
|
|
122
121
|
useEffect(t7, t8);
|
|
123
|
-
|
|
122
|
+
let t10;
|
|
124
123
|
let t9;
|
|
124
|
+
if ($[14] !== customServers) {
|
|
125
|
+
t9 = () => {
|
|
126
|
+
if (!hydratedRef.current) return;
|
|
127
|
+
const targetStorage = storageRef.current;
|
|
128
|
+
persistenceQueueRef.current = persistenceQueueRef.current.then(() => persistCustomServers(targetStorage, customServers));
|
|
129
|
+
};
|
|
130
|
+
t10 = [customServers];
|
|
131
|
+
$[14] = customServers;
|
|
132
|
+
$[15] = t10;
|
|
133
|
+
$[16] = t9;
|
|
134
|
+
} else {
|
|
135
|
+
t10 = $[15];
|
|
136
|
+
t9 = $[16];
|
|
137
|
+
}
|
|
138
|
+
useEffect(t9, t10);
|
|
139
|
+
assertUniqueServerIds([...connectors.map(_temp2), ...customServers.map(_temp3)]);
|
|
140
|
+
let t11;
|
|
125
141
|
if ($[17] !== autoConnect || $[18] !== connectionTimeout || $[19] !== connectors || $[20] !== customServers || $[21] !== redirectUri || $[22] !== storage) {
|
|
126
|
-
let
|
|
142
|
+
let t12;
|
|
127
143
|
if ($[24] !== autoConnect || $[25] !== connectionTimeout || $[26] !== redirectUri || $[27] !== storage) {
|
|
128
|
-
|
|
144
|
+
t12 = (c_0) => withKey(c_0.id, McpServerResource({
|
|
129
145
|
id: c_0.id,
|
|
130
146
|
kind: "connector",
|
|
131
147
|
name: c_0.name,
|
|
@@ -144,12 +160,12 @@ const useMcpManagerResource = (props) => {
|
|
|
144
160
|
$[25] = connectionTimeout;
|
|
145
161
|
$[26] = redirectUri;
|
|
146
162
|
$[27] = storage;
|
|
147
|
-
$[28] =
|
|
148
|
-
} else
|
|
149
|
-
const connectorElements = connectors.map(
|
|
150
|
-
let
|
|
163
|
+
$[28] = t12;
|
|
164
|
+
} else t12 = $[28];
|
|
165
|
+
const connectorElements = connectors.map(t12);
|
|
166
|
+
let t13;
|
|
151
167
|
if ($[29] !== autoConnect || $[30] !== connectionTimeout || $[31] !== redirectUri || $[32] !== storage) {
|
|
152
|
-
|
|
168
|
+
t13 = (s_0) => withKey(s_0.id, McpServerResource({
|
|
153
169
|
id: s_0.id,
|
|
154
170
|
kind: "custom",
|
|
155
171
|
name: s_0.name,
|
|
@@ -169,47 +185,47 @@ const useMcpManagerResource = (props) => {
|
|
|
169
185
|
$[30] = connectionTimeout;
|
|
170
186
|
$[31] = redirectUri;
|
|
171
187
|
$[32] = storage;
|
|
172
|
-
$[33] =
|
|
173
|
-
} else
|
|
174
|
-
const customElements = customServers.map(
|
|
175
|
-
|
|
188
|
+
$[33] = t13;
|
|
189
|
+
} else t13 = $[33];
|
|
190
|
+
const customElements = customServers.map(t13);
|
|
191
|
+
t11 = [...connectorElements, ...customElements];
|
|
176
192
|
$[17] = autoConnect;
|
|
177
193
|
$[18] = connectionTimeout;
|
|
178
194
|
$[19] = connectors;
|
|
179
195
|
$[20] = customServers;
|
|
180
196
|
$[21] = redirectUri;
|
|
181
197
|
$[22] = storage;
|
|
182
|
-
$[23] =
|
|
183
|
-
} else
|
|
184
|
-
const lookup = useClientLookup(
|
|
198
|
+
$[23] = t11;
|
|
199
|
+
} else t11 = $[23];
|
|
200
|
+
const lookup = useClientLookup(t11);
|
|
185
201
|
const all = lookup.state;
|
|
186
|
-
let
|
|
202
|
+
let t12;
|
|
187
203
|
if ($[34] !== all) {
|
|
188
|
-
|
|
204
|
+
t12 = all.filter(_temp5);
|
|
189
205
|
$[34] = all;
|
|
190
|
-
$[35] =
|
|
191
|
-
} else
|
|
192
|
-
let
|
|
206
|
+
$[35] = t12;
|
|
207
|
+
} else t12 = $[35];
|
|
208
|
+
let t13;
|
|
193
209
|
if ($[36] !== all) {
|
|
194
|
-
|
|
210
|
+
t13 = all.filter(_temp6);
|
|
195
211
|
$[36] = all;
|
|
196
|
-
$[37] =
|
|
197
|
-
} else
|
|
198
|
-
let
|
|
199
|
-
if ($[38] !== all || $[39] !== isHydrated || $[40] !==
|
|
200
|
-
|
|
212
|
+
$[37] = t13;
|
|
213
|
+
} else t13 = $[37];
|
|
214
|
+
let t14;
|
|
215
|
+
if ($[38] !== all || $[39] !== isHydrated || $[40] !== t12 || $[41] !== t13) {
|
|
216
|
+
t14 = {
|
|
201
217
|
servers: all,
|
|
202
|
-
connectors:
|
|
203
|
-
customServers:
|
|
218
|
+
connectors: t12,
|
|
219
|
+
customServers: t13,
|
|
204
220
|
isHydrated
|
|
205
221
|
};
|
|
206
222
|
$[38] = all;
|
|
207
223
|
$[39] = isHydrated;
|
|
208
|
-
$[40] =
|
|
209
|
-
$[41] =
|
|
210
|
-
$[42] =
|
|
211
|
-
} else
|
|
212
|
-
const state =
|
|
224
|
+
$[40] = t12;
|
|
225
|
+
$[41] = t13;
|
|
226
|
+
$[42] = t14;
|
|
227
|
+
} else t14 = $[42];
|
|
228
|
+
const state = t14;
|
|
213
229
|
let out;
|
|
214
230
|
if ($[43] !== lookup || $[44] !== state.servers) {
|
|
215
231
|
out = {};
|
|
@@ -231,27 +247,27 @@ const useMcpManagerResource = (props) => {
|
|
|
231
247
|
} else out = $[45];
|
|
232
248
|
const toolkit = out;
|
|
233
249
|
const clientRef = useAssistantClientRef();
|
|
234
|
-
let
|
|
235
|
-
let
|
|
250
|
+
let t15;
|
|
251
|
+
let t16;
|
|
236
252
|
if ($[46] !== clientRef || $[47] !== toolkit) {
|
|
237
|
-
|
|
253
|
+
t15 = () => {
|
|
238
254
|
const client = clientRef.current;
|
|
239
255
|
if (!client) return;
|
|
240
256
|
return client.modelContext.register({ getModelContext: () => ({ tools: toolkit }) });
|
|
241
257
|
};
|
|
242
|
-
|
|
258
|
+
t16 = [toolkit, clientRef];
|
|
243
259
|
$[46] = clientRef;
|
|
244
260
|
$[47] = toolkit;
|
|
245
|
-
$[48] =
|
|
246
|
-
$[49] =
|
|
261
|
+
$[48] = t15;
|
|
262
|
+
$[49] = t16;
|
|
247
263
|
} else {
|
|
248
|
-
|
|
249
|
-
|
|
264
|
+
t15 = $[48];
|
|
265
|
+
t16 = $[49];
|
|
250
266
|
}
|
|
251
|
-
useEffect(
|
|
252
|
-
let
|
|
267
|
+
useEffect(t15, t16);
|
|
268
|
+
let t17;
|
|
253
269
|
if ($[50] !== lookup || $[51] !== state) {
|
|
254
|
-
|
|
270
|
+
t17 = (kind, index) => {
|
|
255
271
|
const list = kind === "connector" ? state.connectors : state.customServers;
|
|
256
272
|
const entry = list[index];
|
|
257
273
|
if (!entry) throw new Error(`McpManagerResource: no ${kind} at index ${index} (length ${list.length})`);
|
|
@@ -259,47 +275,47 @@ const useMcpManagerResource = (props) => {
|
|
|
259
275
|
};
|
|
260
276
|
$[50] = lookup;
|
|
261
277
|
$[51] = state;
|
|
262
|
-
$[52] =
|
|
263
|
-
} else
|
|
264
|
-
const serverByKind =
|
|
265
|
-
let
|
|
278
|
+
$[52] = t17;
|
|
279
|
+
} else t17 = $[52];
|
|
280
|
+
const serverByKind = t17;
|
|
281
|
+
let t18;
|
|
266
282
|
if ($[53] !== state) {
|
|
267
|
-
|
|
283
|
+
t18 = () => state;
|
|
268
284
|
$[53] = state;
|
|
269
|
-
$[54] =
|
|
270
|
-
} else
|
|
271
|
-
let
|
|
285
|
+
$[54] = t18;
|
|
286
|
+
} else t18 = $[54];
|
|
287
|
+
let t19;
|
|
272
288
|
if ($[55] !== lookup || $[56] !== serverByKind) {
|
|
273
|
-
|
|
289
|
+
t19 = (query) => {
|
|
274
290
|
if ("id" in query) return lookup.get({ key: query.id });
|
|
275
291
|
return serverByKind(query.kind, query.index);
|
|
276
292
|
};
|
|
277
293
|
$[55] = lookup;
|
|
278
294
|
$[56] = serverByKind;
|
|
279
|
-
$[57] =
|
|
280
|
-
} else
|
|
281
|
-
let
|
|
282
|
-
let
|
|
295
|
+
$[57] = t19;
|
|
296
|
+
} else t19 = $[57];
|
|
297
|
+
let t20;
|
|
298
|
+
let t21;
|
|
283
299
|
if ($[58] !== serverByKind) {
|
|
284
|
-
|
|
285
|
-
const { index: index_0 } =
|
|
300
|
+
t20 = (t22) => {
|
|
301
|
+
const { index: index_0 } = t22;
|
|
286
302
|
return serverByKind("connector", index_0);
|
|
287
303
|
};
|
|
288
|
-
|
|
289
|
-
const { index: index_1 } =
|
|
304
|
+
t21 = (t23) => {
|
|
305
|
+
const { index: index_1 } = t23;
|
|
290
306
|
return serverByKind("custom", index_1);
|
|
291
307
|
};
|
|
292
308
|
$[58] = serverByKind;
|
|
293
|
-
$[59] =
|
|
294
|
-
$[60] =
|
|
309
|
+
$[59] = t20;
|
|
310
|
+
$[60] = t21;
|
|
295
311
|
} else {
|
|
296
|
-
|
|
297
|
-
|
|
312
|
+
t20 = $[59];
|
|
313
|
+
t21 = $[60];
|
|
298
314
|
}
|
|
299
|
-
let
|
|
315
|
+
let t22;
|
|
300
316
|
if ($[61] === Symbol.for("react.memo_cache_sentinel")) {
|
|
301
|
-
|
|
302
|
-
const { name, url, auth, connectionTimeout: connectionTimeout_0, cache, elicitation } =
|
|
317
|
+
t22 = async (t23) => {
|
|
318
|
+
const { name, url, auth, connectionTimeout: connectionTimeout_0, cache, elicitation } = t23;
|
|
303
319
|
const record = {
|
|
304
320
|
id: typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `mcp-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
305
321
|
name,
|
|
@@ -313,11 +329,11 @@ const useMcpManagerResource = (props) => {
|
|
|
313
329
|
setCustomServers((prev_1) => [...prev_1, record]);
|
|
314
330
|
return record.id;
|
|
315
331
|
};
|
|
316
|
-
$[61] =
|
|
317
|
-
} else
|
|
318
|
-
let
|
|
332
|
+
$[61] = t22;
|
|
333
|
+
} else t22 = $[61];
|
|
334
|
+
let t23;
|
|
319
335
|
if ($[62] !== lookup || $[63] !== state || $[64] !== storage) {
|
|
320
|
-
|
|
336
|
+
t23 = async (id) => {
|
|
321
337
|
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.`);
|
|
322
338
|
try {
|
|
323
339
|
await lookup.get({ key: id }).remove();
|
|
@@ -329,26 +345,26 @@ const useMcpManagerResource = (props) => {
|
|
|
329
345
|
$[62] = lookup;
|
|
330
346
|
$[63] = state;
|
|
331
347
|
$[64] = storage;
|
|
332
|
-
$[65] =
|
|
333
|
-
} else
|
|
334
|
-
let
|
|
335
|
-
if ($[66] !==
|
|
336
|
-
|
|
337
|
-
getState:
|
|
338
|
-
server:
|
|
339
|
-
connector:
|
|
340
|
-
customServer:
|
|
341
|
-
addCustomServer:
|
|
342
|
-
removeServer:
|
|
348
|
+
$[65] = t23;
|
|
349
|
+
} else t23 = $[65];
|
|
350
|
+
let t24;
|
|
351
|
+
if ($[66] !== t18 || $[67] !== t19 || $[68] !== t20 || $[69] !== t21 || $[70] !== t23) {
|
|
352
|
+
t24 = {
|
|
353
|
+
getState: t18,
|
|
354
|
+
server: t19,
|
|
355
|
+
connector: t20,
|
|
356
|
+
customServer: t21,
|
|
357
|
+
addCustomServer: t22,
|
|
358
|
+
removeServer: t23
|
|
343
359
|
};
|
|
344
|
-
$[66] =
|
|
345
|
-
$[67] =
|
|
346
|
-
$[68] =
|
|
347
|
-
$[69] =
|
|
348
|
-
$[70] =
|
|
349
|
-
$[71] =
|
|
350
|
-
} else
|
|
351
|
-
return
|
|
360
|
+
$[66] = t18;
|
|
361
|
+
$[67] = t19;
|
|
362
|
+
$[68] = t20;
|
|
363
|
+
$[69] = t21;
|
|
364
|
+
$[70] = t23;
|
|
365
|
+
$[71] = t24;
|
|
366
|
+
} else t24 = $[71];
|
|
367
|
+
return t24;
|
|
352
368
|
};
|
|
353
369
|
const McpManagerResource = resource(useMcpManagerResource);
|
|
354
370
|
attachTransformScopes(useMcpManagerResource, (scopes, parent) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpManagerResource.js","names":["useState","useEffect","useMemo","useEffectEvent","useRef","useResource","resource","withKey","useClientLookup","useAssistantClientRef","attachTransformScopes","ClientOutput","ModelContext","Tool","McpServerResource","McpLocalStorage","MCPStorageElement","assertUniqueServerIds","MCPAuthConfig","MCPConnector","MCPCustomServerRecord","MCPManagerState","McpManagerResourceProps","connectors","storage","oauthRedirectUri","autoConnect","connectionTimeout","defaultRedirectUri","window","location","origin","NO_CONNECTORS","reportCustomStorageFailure","operation","error","console","useMcpManagerResource","props","$","_c","t0","redirectUri","t1","storageElement","t2","Symbol","for","customServers","setCustomServers","isHydrated","setIsHydrated","hydratedRef","t3","signal","markHydrated","cancelled","current","records","loadCustomServers","t4","prev","length","persistedIds","Set","map","_temp","filter","r_0","has","r","id","hydrate","signal_0","t5","t6","records_0","saveCustomServers","t7","persistCustomServers","t8","_temp2","_temp3","t9","t10","c_0","c","kind","name","url","icon","auth","cache","undefined","elicitation","onRemove","_temp4","connectorElements","t11","s_0","s","prev_0","x","customElements","serverElements","lookup","all","state","_temp5","_temp6","t12","servers","out","server","connectionState","tool","tools","fullName","type","description","parameters","inputSchema","execute","args","get","key","callTool","toolkit","clientRef","t13","t14","client","modelContext","register","getModelContext","t15","index","list","entry","Error","serverByKind","t16","t17","query","t18","t19","t20","index_0","t21","index_1","connectionTimeout_0","record","crypto","randomUUID","Date","now","Math","random","toString","slice","createdAt","prev_1","some","c_1","remove","clearAuthState","prev_2","s_3","t22","getState","connector","customServer","addCustomServer","removeServer","McpManagerResource","scopes","parent","source","s_1","s_2"],"sources":["../../src/resources/McpManagerResource.ts"],"sourcesContent":["import { useState, useEffect, useMemo, useEffectEvent, useRef } 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 { ModelContext } from \"@assistant-ui/core/store\";\nimport type { Tool } from \"assistant-stream\";\nimport { McpServerResource } from \"./McpServerResource\";\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 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 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\n const [customServers, setCustomServers] = useState<MCPCustomServerRecord[]>(\n [],\n );\n const [isHydrated, setIsHydrated] = useState(false);\n\n const hydratedRef = useRef(false);\n\n const hydrate = useEffectEvent(async (signal: { cancelled: boolean }) => {\n const markHydrated = () => {\n if (!signal.cancelled) {\n hydratedRef.current = true;\n setIsHydrated(true);\n }\n };\n\n let records: Awaited<ReturnType<typeof storage.loadCustomServers>>;\n try {\n records = await storage.loadCustomServers();\n } catch (error) {\n if (!signal.cancelled) {\n reportCustomStorageFailure(\"load\", error);\n }\n markHydrated();\n return;\n }\n\n if (signal.cancelled) return;\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 setCustomServers((prev) => {\n if (prev.length === 0) return records;\n const persistedIds = new Set(records.map((r) => r.id));\n return [...records, ...prev.filter((r) => !persistedIds.has(r.id))];\n });\n markHydrated();\n });\n\n useEffect(() => {\n const signal = { cancelled: false };\n void hydrate(signal);\n return () => {\n signal.cancelled = true;\n };\n }, []);\n\n const persistCustomServers = useEffectEvent(\n async (records: MCPCustomServerRecord[]) => {\n if (!hydratedRef.current) return;\n try {\n await storage.saveCustomServers(records);\n } catch (error) {\n reportCustomStorageFailure(\"save\", error);\n }\n },\n );\n\n useEffect(() => {\n void persistCustomServers(customServers);\n }, [customServers]);\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 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 setCustomServers((prev) => prev.filter((x) => x.id !== s.id));\n },\n }),\n ),\n );\n return [...connectorElements, ...customElements];\n }, [\n connectors,\n customServers,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout,\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 useEffect(() => {\n const client = clientRef.current;\n if (!client) return;\n return client.modelContext.register({\n getModelContext: () => ({ tools: toolkit }),\n });\n }, [toolkit, clientRef]);\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:\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `mcp-${Date.now()}-${Math.random().toString(36).slice(2)}`,\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 setCustomServers((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 await storage.clearAuthState(id);\n setCustomServers((prev) => prev.filter((s) => s.id !== id));\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","useEffect","useMemo","useEffectEvent","useRef","useResource","resource","withKey","useClientLookup","useAssistantClientRef","attachTransformScopes","ClientOutput","ModelContext","Tool","McpServerResource","McpLocalStorage","MCPStorage","MCPStorageElement","assertUniqueServerIds","MCPAuthConfig","MCPConnector","MCPCustomServerRecord","MCPManagerState","McpManagerResourceProps","connectors","storage","oauthRedirectUri","autoConnect","connectionTimeout","defaultRedirectUri","window","location","origin","NO_CONNECTORS","reportCustomStorageFailure","operation","error","console","persistCustomServers","records","saveCustomServers","useMcpManagerResource","props","$","_c","t0","redirectUri","t1","storageElement","t2","Symbol","for","customServers","setCustomServers","isHydrated","setIsHydrated","hydratedRef","storageRef","t3","Promise","resolve","persistenceQueueRef","t4","t5","current","t6","signal","markHydrated","cancelled","loadCustomServers","t7","prev","length","persistedIds","Set","map","_temp","filter","r_0","has","r","id","hydrate","signal_0","t8","t10","t9","targetStorage","then","_temp2","_temp3","t11","t12","c_0","c","kind","name","url","icon","auth","cache","undefined","elicitation","onRemove","_temp4","connectorElements","t13","s_0","s","prev_0","x","customElements","serverElements","lookup","all","state","_temp5","_temp6","t14","servers","out","server","connectionState","tool","tools","fullName","type","description","parameters","inputSchema","execute","args","get","key","callTool","toolkit","clientRef","t15","t16","client","modelContext","register","getModelContext","t17","index","list","entry","Error","serverByKind","t18","t19","query","t20","t21","t22","index_0","t23","index_1","connectionTimeout_0","record","crypto","randomUUID","Date","now","Math","random","toString","slice","createdAt","prev_1","some","c_1","remove","clearAuthState","prev_2","s_3","t24","getState","connector","customServer","addCustomServer","removeServer","McpManagerResource","scopes","parent","source","s_1","s_2"],"sources":["../../src/resources/McpManagerResource.ts"],"sourcesContent":["import { useState, useEffect, useMemo, useEffectEvent, useRef } 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 { ModelContext } from \"@assistant-ui/core/store\";\nimport type { Tool } from \"assistant-stream\";\nimport { McpServerResource } from \"./McpServerResource\";\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 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\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\n const [customServers, setCustomServers] = useState<MCPCustomServerRecord[]>(\n [],\n );\n const [isHydrated, setIsHydrated] = useState(false);\n\n const hydratedRef = useRef(false);\n const storageRef = useRef(storage);\n const persistenceQueueRef = useRef(Promise.resolve());\n\n useEffect(() => {\n storageRef.current = storage;\n }, [storage]);\n\n const hydrate = useEffectEvent(async (signal: { cancelled: boolean }) => {\n const markHydrated = () => {\n if (!signal.cancelled) {\n hydratedRef.current = true;\n setIsHydrated(true);\n }\n };\n\n let records: Awaited<ReturnType<typeof storage.loadCustomServers>>;\n try {\n records = await storage.loadCustomServers();\n } catch (error) {\n if (!signal.cancelled) {\n reportCustomStorageFailure(\"load\", error);\n }\n markHydrated();\n return;\n }\n\n if (signal.cancelled) return;\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 setCustomServers((prev) => {\n if (prev.length === 0) return records;\n const persistedIds = new Set(records.map((r) => r.id));\n return [...records, ...prev.filter((r) => !persistedIds.has(r.id))];\n });\n markHydrated();\n });\n\n useEffect(() => {\n const signal = { cancelled: false };\n void hydrate(signal);\n return () => {\n signal.cancelled = true;\n };\n }, []);\n\n useEffect(() => {\n if (!hydratedRef.current) return;\n const targetStorage = storageRef.current;\n persistenceQueueRef.current = persistenceQueueRef.current.then(() =>\n persistCustomServers(targetStorage, customServers),\n );\n }, [customServers]);\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 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 setCustomServers((prev) => prev.filter((x) => x.id !== s.id));\n },\n }),\n ),\n );\n return [...connectorElements, ...customElements];\n }, [\n connectors,\n customServers,\n storage,\n redirectUri,\n autoConnect,\n connectionTimeout,\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 useEffect(() => {\n const client = clientRef.current;\n if (!client) return;\n return client.modelContext.register({\n getModelContext: () => ({ tools: toolkit }),\n });\n }, [toolkit, clientRef]);\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:\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `mcp-${Date.now()}-${Math.random().toString(36).slice(2)}`,\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 setCustomServers((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 await storage.clearAuthState(id);\n setCustomServers((prev) => prev.filter((s) => s.id !== id));\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpServerResource.d.ts","names":[],"sources":["../../src/resources/McpServerResource.ts"],"mappings":";;;;KA2BY;EACV;EACA,MAAM;EACN;EACA;EACA;EACA,MAAM;EACN,SAAS;EACT;EACA;EACA;EACA;aAAmB;;WACV;EACT,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"McpServerResource.d.ts","names":[],"sources":["../../src/resources/McpServerResource.ts"],"mappings":";;;;KA2BY;EACV;EACA,MAAM;EACN;EACA;EACA;EACA,MAAM;EACN,SAAS;EACT;EACA;EACA;EACA;aAAmB;;WACV;EACT,gBAAgB;;cA8kBL,+CAAiB,SAAA,4BAAA,OAAA"}
|
|
@@ -320,8 +320,13 @@ const useMcpServerResource = (props) => {
|
|
|
320
320
|
disconnect: doDisconnect,
|
|
321
321
|
remove: async () => {
|
|
322
322
|
await doDisconnect();
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
try {
|
|
324
|
+
await props.storage.clearAuthState(props.id);
|
|
325
|
+
await props.onRemove();
|
|
326
|
+
} catch (err_1) {
|
|
327
|
+
setLastError({ message: err_1 instanceof Error ? err_1.message : String(err_1) });
|
|
328
|
+
throw err_1;
|
|
329
|
+
}
|
|
325
330
|
},
|
|
326
331
|
callTool: async (name, args) => {
|
|
327
332
|
const client_1 = clientRef.current;
|