@assistant-ui/react-mcp 0.1.15 → 0.1.17
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/auth/createOAuthProvider.d.ts +19 -2
- package/dist/auth/createOAuthProvider.d.ts.map +1 -1
- package/dist/auth/createOAuthProvider.js +197 -35
- package/dist/auth/createOAuthProvider.js.map +1 -1
- package/dist/auth/types.d.ts +6 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.d.ts.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.js +5 -6
- package/dist/hooks/useMcpOAuthCallback.js.map +1 -1
- package/dist/resources/McpManagerResource.d.ts.map +1 -1
- package/dist/resources/McpManagerResource.js +2 -1
- package/dist/resources/McpManagerResource.js.map +1 -1
- package/dist/resources/McpServerResource.d.ts +2 -1
- package/dist/resources/McpServerResource.d.ts.map +1 -1
- package/dist/resources/McpServerResource.js +79 -19
- package/dist/resources/McpServerResource.js.map +1 -1
- package/dist/resources/storage/McpLocalStorage.d.ts +7 -0
- package/dist/resources/storage/McpLocalStorage.d.ts.map +1 -1
- package/dist/resources/storage/McpLocalStorage.js +146 -37
- package/dist/resources/storage/McpLocalStorage.js.map +1 -1
- package/dist/resources/storage/McpMemoryStorage.d.ts.map +1 -1
- package/dist/resources/storage/McpMemoryStorage.js +9 -6
- package/dist/resources/storage/McpMemoryStorage.js.map +1 -1
- package/dist/resources/storage/types.d.ts +12 -0
- package/dist/resources/storage/types.d.ts.map +1 -1
- package/dist/utils/serverUrl.d.ts +8 -0
- package/dist/utils/serverUrl.d.ts.map +1 -0
- package/dist/utils/serverUrl.js +15 -0
- package/dist/utils/serverUrl.js.map +1 -0
- package/package.json +7 -7
- package/src/auth/createOAuthProvider.test.ts +919 -5
- package/src/auth/createOAuthProvider.ts +328 -42
- package/src/auth/types.ts +6 -1
- package/src/hooks/useMcpOAuthCallback.test.ts +74 -1
- package/src/hooks/useMcpOAuthCallback.tsx +11 -8
- package/src/resources/McpManagerResource.ts +5 -1
- package/src/resources/McpServerResource.test.ts +612 -16
- package/src/resources/McpServerResource.ts +95 -23
- package/src/resources/storage/McpLocalStorage.test.ts +97 -1
- package/src/resources/storage/McpLocalStorage.ts +90 -47
- package/src/resources/storage/McpMemoryStorage.test.ts +99 -0
- package/src/resources/storage/McpMemoryStorage.ts +23 -17
- package/src/resources/storage/types.ts +12 -0
- package/src/utils/serverUrl.test.ts +66 -0
- package/src/utils/serverUrl.ts +23 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { assertValidServerId } from "../../utils/serverId.js";
|
|
2
|
+
import { normalizeMcpServerUrl } from "../../utils/serverUrl.js";
|
|
3
|
+
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
4
|
+
import "@assistant-ui/tap/react-shim";
|
|
2
5
|
import { resource } from "@assistant-ui/tap";
|
|
3
6
|
import { OAuthClientInformationFullSchema, OAuthMetadataSchema, OAuthProtectedResourceMetadataSchema, OAuthTokensSchema } from "@modelcontextprotocol/core";
|
|
4
7
|
//#region src/resources/storage/McpLocalStorage.ts
|
|
@@ -70,6 +73,15 @@ const isSecureNetworkUrl = (value) => {
|
|
|
70
73
|
return false;
|
|
71
74
|
}
|
|
72
75
|
};
|
|
76
|
+
const isMcpServerUrl = (value) => {
|
|
77
|
+
if (typeof value !== "string") return false;
|
|
78
|
+
try {
|
|
79
|
+
const url = new URL(value);
|
|
80
|
+
return url.protocol === "https:" || url.protocol === "http:";
|
|
81
|
+
} catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
73
85
|
const normalizeDiscoveryState = (value) => {
|
|
74
86
|
if (!isRecord(value) || !isSecureNetworkUrl(value.authorizationServerUrl)) return;
|
|
75
87
|
const state = { authorizationServerUrl: value.authorizationServerUrl };
|
|
@@ -82,57 +94,154 @@ const normalizeDiscoveryState = (value) => {
|
|
|
82
94
|
};
|
|
83
95
|
const normalizePersistedAuthState = (value) => {
|
|
84
96
|
if (!isRecord(value)) return null;
|
|
97
|
+
if ("serverUrl" in value && !isMcpServerUrl(value.serverUrl)) return null;
|
|
85
98
|
const state = {};
|
|
99
|
+
if (isMcpServerUrl(value.serverUrl)) state.serverUrl = normalizeMcpServerUrl(value.serverUrl);
|
|
86
100
|
if (isNonEmptyString(value.token)) state.token = value.token;
|
|
101
|
+
if (isNonEmptyString(value.tokensClientId)) state.tokensClientId = value.tokensClientId;
|
|
87
102
|
if (isNonEmptyString(value.codeVerifier)) state.codeVerifier = value.codeVerifier;
|
|
103
|
+
if (isNonEmptyString(value.state)) state.state = value.state;
|
|
88
104
|
const tokens = normalizeOAuthTokens(value.tokens);
|
|
89
105
|
if (tokens) state.tokens = tokens;
|
|
90
106
|
const clientInformation = normalizeClientInformation(value.clientInformation);
|
|
91
107
|
if (clientInformation) state.clientInformation = clientInformation;
|
|
108
|
+
if (value.clientInformationSource === "registered") state.clientInformationSource = value.clientInformationSource;
|
|
92
109
|
const discoveryState = normalizeDiscoveryState(value.discoveryState);
|
|
93
110
|
if (discoveryState) state.discoveryState = discoveryState;
|
|
94
111
|
return Object.keys(state).length > 0 ? state : null;
|
|
95
112
|
};
|
|
96
|
-
const useMcpLocalStorage = (
|
|
113
|
+
const useMcpLocalStorage = (t0) => {
|
|
114
|
+
const $ = c(36);
|
|
115
|
+
let t1;
|
|
116
|
+
if ($[0] !== t0) {
|
|
117
|
+
t1 = t0 === void 0 ? {} : t0;
|
|
118
|
+
$[0] = t0;
|
|
119
|
+
$[1] = t1;
|
|
120
|
+
} else t1 = $[1];
|
|
121
|
+
const opts = t1;
|
|
97
122
|
const prefix = opts.keyPrefix ?? "aui-mcp";
|
|
123
|
+
let t2;
|
|
124
|
+
if ($[2] !== opts) {
|
|
125
|
+
t2 = resolveStorage(opts);
|
|
126
|
+
$[2] = opts;
|
|
127
|
+
$[3] = t2;
|
|
128
|
+
} else t2 = $[3];
|
|
129
|
+
const storage = t2;
|
|
130
|
+
const scopeId = opts.scopeId ?? (opts.storage === void 0 ? `local-storage:${prefix}` : void 0);
|
|
98
131
|
const customServersKey = `${prefix}:custom-servers`;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
let t3;
|
|
133
|
+
if ($[4] !== prefix) {
|
|
134
|
+
t3 = (id) => `${prefix}:auth:${id}`;
|
|
135
|
+
$[4] = prefix;
|
|
136
|
+
$[5] = t3;
|
|
137
|
+
} else t3 = $[5];
|
|
138
|
+
const authKey = t3;
|
|
139
|
+
let t4;
|
|
140
|
+
if ($[6] !== storage) {
|
|
141
|
+
t4 = (key, fallback) => {
|
|
142
|
+
if (!storage) return fallback;
|
|
143
|
+
try {
|
|
144
|
+
const raw = storage.getItem(key);
|
|
145
|
+
if (raw == null) return fallback;
|
|
146
|
+
return JSON.parse(raw);
|
|
147
|
+
} catch {
|
|
148
|
+
return fallback;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
$[6] = storage;
|
|
152
|
+
$[7] = t4;
|
|
153
|
+
} else t4 = $[7];
|
|
154
|
+
const read = t4;
|
|
155
|
+
let t5;
|
|
156
|
+
if ($[8] !== storage) {
|
|
157
|
+
t5 = (key_0, value) => {
|
|
158
|
+
if (!storage) return;
|
|
159
|
+
try {
|
|
160
|
+
storage.setItem(key_0, JSON.stringify(value));
|
|
161
|
+
} catch {}
|
|
162
|
+
};
|
|
163
|
+
$[8] = storage;
|
|
164
|
+
$[9] = t5;
|
|
165
|
+
} else t5 = $[9];
|
|
166
|
+
const write = t5;
|
|
167
|
+
let t6;
|
|
168
|
+
if ($[10] !== storage) {
|
|
169
|
+
t6 = (key_1) => {
|
|
170
|
+
if (!storage) return;
|
|
171
|
+
try {
|
|
172
|
+
storage.removeItem(key_1);
|
|
173
|
+
} catch {}
|
|
174
|
+
};
|
|
175
|
+
$[10] = storage;
|
|
176
|
+
$[11] = t6;
|
|
177
|
+
} else t6 = $[11];
|
|
178
|
+
const remove = t6;
|
|
179
|
+
let t7;
|
|
180
|
+
if ($[12] !== scopeId) {
|
|
181
|
+
t7 = scopeId !== void 0 ? { scopeId } : {};
|
|
182
|
+
$[12] = scopeId;
|
|
183
|
+
$[13] = t7;
|
|
184
|
+
} else t7 = $[13];
|
|
185
|
+
let t8;
|
|
186
|
+
if ($[14] !== customServersKey || $[15] !== read) {
|
|
187
|
+
t8 = async () => normalizeCustomServerRecords(read(customServersKey, []));
|
|
188
|
+
$[14] = customServersKey;
|
|
189
|
+
$[15] = read;
|
|
190
|
+
$[16] = t8;
|
|
191
|
+
} else t8 = $[16];
|
|
192
|
+
let t9;
|
|
193
|
+
if ($[17] !== customServersKey || $[18] !== write) {
|
|
194
|
+
t9 = async (records) => {
|
|
126
195
|
write(customServersKey, records);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
196
|
+
};
|
|
197
|
+
$[17] = customServersKey;
|
|
198
|
+
$[18] = write;
|
|
199
|
+
$[19] = t9;
|
|
200
|
+
} else t9 = $[19];
|
|
201
|
+
let t10;
|
|
202
|
+
if ($[20] !== authKey || $[21] !== read) {
|
|
203
|
+
t10 = async (id_0) => normalizePersistedAuthState(read(authKey(id_0), null));
|
|
204
|
+
$[20] = authKey;
|
|
205
|
+
$[21] = read;
|
|
206
|
+
$[22] = t10;
|
|
207
|
+
} else t10 = $[22];
|
|
208
|
+
let t11;
|
|
209
|
+
if ($[23] !== authKey || $[24] !== write) {
|
|
210
|
+
t11 = async (id_1, state) => {
|
|
211
|
+
write(authKey(id_1), state);
|
|
212
|
+
};
|
|
213
|
+
$[23] = authKey;
|
|
214
|
+
$[24] = write;
|
|
215
|
+
$[25] = t11;
|
|
216
|
+
} else t11 = $[25];
|
|
217
|
+
let t12;
|
|
218
|
+
if ($[26] !== authKey || $[27] !== remove) {
|
|
219
|
+
t12 = async (id_2) => {
|
|
220
|
+
remove(authKey(id_2));
|
|
221
|
+
};
|
|
222
|
+
$[26] = authKey;
|
|
223
|
+
$[27] = remove;
|
|
224
|
+
$[28] = t12;
|
|
225
|
+
} else t12 = $[28];
|
|
226
|
+
let t13;
|
|
227
|
+
if ($[29] !== t10 || $[30] !== t11 || $[31] !== t12 || $[32] !== t7 || $[33] !== t8 || $[34] !== t9) {
|
|
228
|
+
t13 = {
|
|
229
|
+
...t7,
|
|
230
|
+
loadCustomServers: t8,
|
|
231
|
+
saveCustomServers: t9,
|
|
232
|
+
loadAuthState: t10,
|
|
233
|
+
saveAuthState: t11,
|
|
234
|
+
clearAuthState: t12
|
|
235
|
+
};
|
|
236
|
+
$[29] = t10;
|
|
237
|
+
$[30] = t11;
|
|
238
|
+
$[31] = t12;
|
|
239
|
+
$[32] = t7;
|
|
240
|
+
$[33] = t8;
|
|
241
|
+
$[34] = t9;
|
|
242
|
+
$[35] = t13;
|
|
243
|
+
} else t13 = $[35];
|
|
244
|
+
return t13;
|
|
136
245
|
};
|
|
137
246
|
const McpLocalStorage = resource(useMcpLocalStorage);
|
|
138
247
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpLocalStorage.js","names":["resource","OAuthMetadataSchema","OAuthClientInformationFullSchema","OAuthProtectedResourceMetadataSchema","OAuthTokensSchema","MCPAuthConfig","MCPCustomServerRecord","MCPPersistedAuthState","assertValidServerId","MCPStorage","McpLocalStorageOptions","keyPrefix","storage","Storage","resolveStorage","opts","globalThis","localStorage","isRecord","value","Record","Array","isArray","isOptionalString","undefined","isNonEmptyString","trim","length","isOptionalNonEmptyString","isOptionalStringArray","every","item","isOptionalConnectionTimeout","Number","isFinite","isValidServerId","id","isMCPAuthConfig","auth","type","token","scopes","authorizationEndpoint","tokenEndpoint","registrationEndpoint","clientId","clientSecret","isCustomServerRecord","name","url","createdAt","connectionTimeout","normalizeCustomServerRecord","record","normalizeCustomServerRecords","flatMap","normalizeOAuthTokens","result","safeParse","success","data","normalizeClientInformation","isSecureNetworkUrl","URL","protocol","hostname","endsWith","startsWith","normalizeDiscoveryState","authorizationServerUrl","state","NonNullable","resourceMetadataUrl","metadata","authorizationServerMetadata","resourceMetadata","normalizePersistedAuthState","codeVerifier","tokens","clientInformation","discoveryState","Object","keys","useMcpLocalStorage","prefix","customServersKey","authKey","read","key","fallback","T","raw","getItem","JSON","parse","write","setItem","stringify","remove","removeItem","loadCustomServers","saveCustomServers","records","loadAuthState","saveAuthState","clearAuthState","McpLocalStorage"],"sources":["../../../src/resources/storage/McpLocalStorage.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport {\n OAuthMetadataSchema,\n OAuthClientInformationFullSchema,\n OAuthProtectedResourceMetadataSchema,\n OAuthTokensSchema,\n} from \"@modelcontextprotocol/core\";\nimport type { MCPAuthConfig, MCPCustomServerRecord } from \"../../mcp-scope\";\nimport type { MCPPersistedAuthState } from \"../../auth/types\";\nimport { assertValidServerId } from \"../../utils/serverId\";\nimport type { MCPStorage } from \"./types\";\n\nexport type McpLocalStorageOptions = {\n /** Namespace prefix for keys. Default \"aui-mcp\". */\n keyPrefix?: string;\n /** Override the underlying Storage. Defaults to globalThis.localStorage. */\n storage?: Storage;\n};\n\nfunction resolveStorage(opts: McpLocalStorageOptions): Storage | null {\n if (opts.storage) return opts.storage;\n if (typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis) {\n try {\n return (globalThis as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n }\n return null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isOptionalString = (value: unknown): value is string | undefined =>\n value === undefined || typeof value === \"string\";\n\nconst isNonEmptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.trim().length > 0;\n\nconst isOptionalNonEmptyString = (\n value: unknown,\n): value is string | undefined =>\n value === undefined || isNonEmptyString(value);\n\nconst isOptionalStringArray = (value: unknown): value is string[] | undefined =>\n value === undefined ||\n (Array.isArray(value) && value.every((item) => typeof item === \"string\"));\n\nconst isOptionalConnectionTimeout = (\n value: unknown,\n): value is number | undefined =>\n value === undefined ||\n (typeof value === \"number\" && Number.isFinite(value) && value >= 0);\n\nconst isValidServerId = (id: string): boolean => {\n try {\n assertValidServerId(id);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isMCPAuthConfig = (auth: unknown): auth is MCPAuthConfig => {\n if (!isRecord(auth)) return false;\n\n switch (auth.type) {\n case \"none\":\n return true;\n case \"bearer\":\n return isOptionalNonEmptyString(auth.token);\n case \"oauth\":\n return (\n isOptionalStringArray(auth.scopes) &&\n isOptionalString(auth.authorizationEndpoint) &&\n isOptionalString(auth.tokenEndpoint) &&\n isOptionalString(auth.registrationEndpoint) &&\n isOptionalString(auth.clientId) &&\n isOptionalString(auth.clientSecret)\n );\n default:\n return false;\n }\n};\n\nconst isCustomServerRecord = (\n value: unknown,\n): value is MCPCustomServerRecord => {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\" || !isValidServerId(value.id)) {\n return false;\n }\n return (\n isNonEmptyString(value.name) &&\n isNonEmptyString(value.url) &&\n Number.isFinite(value.createdAt) &&\n isMCPAuthConfig(value.auth) &&\n isOptionalConnectionTimeout(value.connectionTimeout)\n );\n};\n\nconst normalizeCustomServerRecord = (\n value: unknown,\n): MCPCustomServerRecord | null => {\n if (isCustomServerRecord(value)) return value;\n if (!isRecord(value)) return null;\n\n const record = { ...value };\n delete record.connectionTimeout;\n return isCustomServerRecord(record) ? record : null;\n};\n\nexport const normalizeCustomServerRecords = (\n value: unknown,\n): MCPCustomServerRecord[] => {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item) => {\n const record = normalizeCustomServerRecord(item);\n return record === null ? [] : [record];\n });\n};\n\nconst normalizeOAuthTokens = (\n value: unknown,\n): MCPPersistedAuthState[\"tokens\"] | undefined => {\n const result = OAuthTokensSchema.safeParse(value);\n return result.success ? result.data : undefined;\n};\n\nconst normalizeClientInformation = (\n value: unknown,\n): MCPPersistedAuthState[\"clientInformation\"] | undefined => {\n const result = OAuthClientInformationFullSchema.safeParse(value);\n return result.success ? result.data : undefined;\n};\n\nconst isSecureNetworkUrl = (value: unknown): value is string => {\n if (!isNonEmptyString(value)) return false;\n try {\n const url = new URL(value);\n return (\n url.protocol === \"https:\" ||\n (url.protocol === \"http:\" &&\n (url.hostname === \"localhost\" ||\n url.hostname.endsWith(\".localhost\") ||\n url.hostname.startsWith(\"127.\") ||\n url.hostname === \"[::1]\"))\n );\n } catch {\n return false;\n }\n};\n\nconst normalizeDiscoveryState = (\n value: unknown,\n): MCPPersistedAuthState[\"discoveryState\"] | undefined => {\n if (!isRecord(value) || !isSecureNetworkUrl(value.authorizationServerUrl)) {\n return undefined;\n }\n\n // A malformed optional field is dropped alone: keeping the validated\n // authorization server URL preserves the redirect-time binding, and the SDK\n // re-discovers whatever metadata is missing.\n const state: NonNullable<MCPPersistedAuthState[\"discoveryState\"]> = {\n authorizationServerUrl: value.authorizationServerUrl,\n };\n\n if (isSecureNetworkUrl(value.resourceMetadataUrl)) {\n state.resourceMetadataUrl = value.resourceMetadataUrl;\n }\n\n const metadata = OAuthMetadataSchema.safeParse(\n value.authorizationServerMetadata,\n );\n if (metadata.success) state.authorizationServerMetadata = metadata.data;\n\n const resourceMetadata = OAuthProtectedResourceMetadataSchema.safeParse(\n value.resourceMetadata,\n );\n if (resourceMetadata.success) state.resourceMetadata = resourceMetadata.data;\n\n return state;\n};\n\nexport const normalizePersistedAuthState = (\n value: unknown,\n): MCPPersistedAuthState | null => {\n if (!isRecord(value)) return null;\n\n const state: MCPPersistedAuthState = {};\n if (isNonEmptyString(value.token)) state.token = value.token;\n if (isNonEmptyString(value.codeVerifier)) {\n state.codeVerifier = value.codeVerifier;\n }\n\n const tokens = normalizeOAuthTokens(value.tokens);\n if (tokens) state.tokens = tokens;\n\n const clientInformation = normalizeClientInformation(value.clientInformation);\n if (clientInformation) state.clientInformation = clientInformation;\n\n const discoveryState = normalizeDiscoveryState(value.discoveryState);\n if (discoveryState) state.discoveryState = discoveryState;\n\n return Object.keys(state).length > 0 ? state : null;\n};\n\nconst useMcpLocalStorage = (opts: McpLocalStorageOptions = {}): MCPStorage => {\n const prefix = opts.keyPrefix ?? \"aui-mcp\";\n const customServersKey = `${prefix}:custom-servers`;\n const authKey = (id: string) => `${prefix}:auth:${id}`;\n const storage = resolveStorage(opts);\n\n const read = <T>(key: string, fallback: T): T => {\n if (!storage) return fallback;\n try {\n const raw = storage.getItem(key);\n if (raw == null) return fallback;\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n };\n\n const write = (key: string, value: unknown): void => {\n if (!storage) return;\n try {\n storage.setItem(key, JSON.stringify(value));\n } catch {\n // quota or serialization failure — silently drop\n }\n };\n\n const remove = (key: string): void => {\n if (!storage) return;\n try {\n storage.removeItem(key);\n } catch {\n // ignore\n }\n };\n\n return {\n loadCustomServers: async () =>\n normalizeCustomServerRecords(read<unknown>(customServersKey, [])),\n saveCustomServers: async (records) => {\n write(customServersKey, records);\n },\n loadAuthState: async (id) =>\n normalizePersistedAuthState(read<unknown>(authKey(id), null)),\n saveAuthState: async (id, state) => {\n write(authKey(id), state);\n },\n clearAuthState: async (id) => {\n remove(authKey(id));\n },\n };\n};\n\nexport const McpLocalStorage = resource(useMcpLocalStorage);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpLocalStorage.js","names":["resource","useMemo","OAuthMetadataSchema","OAuthClientInformationFullSchema","OAuthProtectedResourceMetadataSchema","OAuthTokensSchema","normalizeMcpServerUrl","MCPAuthConfig","MCPCustomServerRecord","MCPPersistedAuthState","assertValidServerId","MCPStorage","McpLocalStorageOptions","keyPrefix","storage","Storage","scopeId","resolveStorage","opts","globalThis","localStorage","isRecord","value","Record","Array","isArray","isOptionalString","undefined","isNonEmptyString","trim","length","isOptionalNonEmptyString","isOptionalStringArray","every","item","isOptionalConnectionTimeout","Number","isFinite","isValidServerId","id","isMCPAuthConfig","auth","type","token","scopes","authorizationEndpoint","tokenEndpoint","registrationEndpoint","clientId","clientSecret","isCustomServerRecord","name","url","createdAt","connectionTimeout","normalizeCustomServerRecord","record","normalizeCustomServerRecords","flatMap","normalizeOAuthTokens","result","safeParse","success","data","normalizeClientInformation","isSecureNetworkUrl","URL","protocol","hostname","endsWith","startsWith","isMcpServerUrl","normalizeDiscoveryState","authorizationServerUrl","state","NonNullable","resourceMetadataUrl","metadata","authorizationServerMetadata","resourceMetadata","normalizePersistedAuthState","serverUrl","tokensClientId","codeVerifier","tokens","clientInformation","clientInformationSource","discoveryState","Object","keys","useMcpLocalStorage","t0","$","_c","t1","prefix","t2","customServersKey","t3","authKey","t4","key","fallback","raw","getItem","JSON","parse","T","read","t5","key_0","setItem","stringify","write","t6","key_1","removeItem","remove","t7","t8","t9","records","t10","id_0","t11","id_1","t12","id_2","t13","loadCustomServers","saveCustomServers","loadAuthState","saveAuthState","clearAuthState","McpLocalStorage"],"sources":["../../../src/resources/storage/McpLocalStorage.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport { useMemo } from \"react\";\nimport {\n OAuthMetadataSchema,\n OAuthClientInformationFullSchema,\n OAuthProtectedResourceMetadataSchema,\n OAuthTokensSchema,\n} from \"@modelcontextprotocol/core\";\nimport { normalizeMcpServerUrl } from \"../../utils/serverUrl\";\nimport type { MCPAuthConfig, MCPCustomServerRecord } from \"../../mcp-scope\";\nimport type { MCPPersistedAuthState } from \"../../auth/types\";\nimport { assertValidServerId } from \"../../utils/serverId\";\nimport type { MCPStorage } from \"./types\";\n\nexport type McpLocalStorageOptions = {\n /** Namespace prefix for keys. Default \"aui-mcp\". */\n keyPrefix?: string;\n /** Override the underlying Storage. Defaults to globalThis.localStorage. */\n storage?: Storage;\n /**\n * Stable identity for the backing data, used to key server reconnects.\n * Required to get reconnect-on-swap behavior when `storage` is overridden;\n * without it a custom backing store declares no scope, since a prefix\n * alone cannot distinguish two different stores.\n */\n scopeId?: string;\n};\n\nfunction resolveStorage(opts: McpLocalStorageOptions): Storage | null {\n if (opts.storage) return opts.storage;\n if (typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis) {\n try {\n return (globalThis as { localStorage: Storage }).localStorage;\n } catch {\n return null;\n }\n }\n return null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isOptionalString = (value: unknown): value is string | undefined =>\n value === undefined || typeof value === \"string\";\n\nconst isNonEmptyString = (value: unknown): value is string =>\n typeof value === \"string\" && value.trim().length > 0;\n\nconst isOptionalNonEmptyString = (\n value: unknown,\n): value is string | undefined =>\n value === undefined || isNonEmptyString(value);\n\nconst isOptionalStringArray = (value: unknown): value is string[] | undefined =>\n value === undefined ||\n (Array.isArray(value) && value.every((item) => typeof item === \"string\"));\n\nconst isOptionalConnectionTimeout = (\n value: unknown,\n): value is number | undefined =>\n value === undefined ||\n (typeof value === \"number\" && Number.isFinite(value) && value >= 0);\n\nconst isValidServerId = (id: string): boolean => {\n try {\n assertValidServerId(id);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isMCPAuthConfig = (auth: unknown): auth is MCPAuthConfig => {\n if (!isRecord(auth)) return false;\n\n switch (auth.type) {\n case \"none\":\n return true;\n case \"bearer\":\n return isOptionalNonEmptyString(auth.token);\n case \"oauth\":\n return (\n isOptionalStringArray(auth.scopes) &&\n isOptionalString(auth.authorizationEndpoint) &&\n isOptionalString(auth.tokenEndpoint) &&\n isOptionalString(auth.registrationEndpoint) &&\n isOptionalString(auth.clientId) &&\n isOptionalString(auth.clientSecret)\n );\n default:\n return false;\n }\n};\n\nconst isCustomServerRecord = (\n value: unknown,\n): value is MCPCustomServerRecord => {\n if (!isRecord(value)) return false;\n if (typeof value.id !== \"string\" || !isValidServerId(value.id)) {\n return false;\n }\n return (\n isNonEmptyString(value.name) &&\n isNonEmptyString(value.url) &&\n Number.isFinite(value.createdAt) &&\n isMCPAuthConfig(value.auth) &&\n isOptionalConnectionTimeout(value.connectionTimeout)\n );\n};\n\nconst normalizeCustomServerRecord = (\n value: unknown,\n): MCPCustomServerRecord | null => {\n if (isCustomServerRecord(value)) return value;\n if (!isRecord(value)) return null;\n\n const record = { ...value };\n delete record.connectionTimeout;\n return isCustomServerRecord(record) ? record : null;\n};\n\nexport const normalizeCustomServerRecords = (\n value: unknown,\n): MCPCustomServerRecord[] => {\n if (!Array.isArray(value)) return [];\n return value.flatMap((item) => {\n const record = normalizeCustomServerRecord(item);\n return record === null ? [] : [record];\n });\n};\n\nconst normalizeOAuthTokens = (\n value: unknown,\n): MCPPersistedAuthState[\"tokens\"] | undefined => {\n const result = OAuthTokensSchema.safeParse(value);\n return result.success ? result.data : undefined;\n};\n\nconst normalizeClientInformation = (\n value: unknown,\n): MCPPersistedAuthState[\"clientInformation\"] | undefined => {\n const result = OAuthClientInformationFullSchema.safeParse(value);\n return result.success ? result.data : undefined;\n};\n\nconst isSecureNetworkUrl = (value: unknown): value is string => {\n if (!isNonEmptyString(value)) return false;\n try {\n const url = new URL(value);\n return (\n url.protocol === \"https:\" ||\n (url.protocol === \"http:\" &&\n (url.hostname === \"localhost\" ||\n url.hostname.endsWith(\".localhost\") ||\n url.hostname.startsWith(\"127.\") ||\n url.hostname === \"[::1]\"))\n );\n } catch {\n return false;\n }\n};\n\nconst isMcpServerUrl = (value: unknown): value is string => {\n if (typeof value !== \"string\") return false;\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" || url.protocol === \"http:\";\n } catch {\n return false;\n }\n};\n\nconst normalizeDiscoveryState = (\n value: unknown,\n): MCPPersistedAuthState[\"discoveryState\"] | undefined => {\n if (!isRecord(value) || !isSecureNetworkUrl(value.authorizationServerUrl)) {\n return undefined;\n }\n\n // A malformed optional field is dropped alone: keeping the validated\n // authorization server URL preserves the redirect-time binding, and the SDK\n // re-discovers whatever metadata is missing.\n const state: NonNullable<MCPPersistedAuthState[\"discoveryState\"]> = {\n authorizationServerUrl: value.authorizationServerUrl,\n };\n\n if (isSecureNetworkUrl(value.resourceMetadataUrl)) {\n state.resourceMetadataUrl = value.resourceMetadataUrl;\n }\n\n const metadata = OAuthMetadataSchema.safeParse(\n value.authorizationServerMetadata,\n );\n if (metadata.success) state.authorizationServerMetadata = metadata.data;\n\n const resourceMetadata = OAuthProtectedResourceMetadataSchema.safeParse(\n value.resourceMetadata,\n );\n if (resourceMetadata.success) state.resourceMetadata = resourceMetadata.data;\n\n return state;\n};\n\nexport const normalizePersistedAuthState = (\n value: unknown,\n): MCPPersistedAuthState | null => {\n if (!isRecord(value)) return null;\n if (\"serverUrl\" in value && !isMcpServerUrl(value.serverUrl)) return null;\n\n const state: MCPPersistedAuthState = {};\n if (isMcpServerUrl(value.serverUrl)) {\n state.serverUrl = normalizeMcpServerUrl(value.serverUrl);\n }\n if (isNonEmptyString(value.token)) state.token = value.token;\n if (isNonEmptyString(value.tokensClientId)) {\n state.tokensClientId = value.tokensClientId;\n }\n if (isNonEmptyString(value.codeVerifier)) {\n state.codeVerifier = value.codeVerifier;\n }\n if (isNonEmptyString(value.state)) state.state = value.state;\n\n const tokens = normalizeOAuthTokens(value.tokens);\n if (tokens) state.tokens = tokens;\n\n const clientInformation = normalizeClientInformation(value.clientInformation);\n if (clientInformation) state.clientInformation = clientInformation;\n if (value.clientInformationSource === \"registered\") {\n state.clientInformationSource = value.clientInformationSource;\n }\n\n const discoveryState = normalizeDiscoveryState(value.discoveryState);\n if (discoveryState) state.discoveryState = discoveryState;\n\n return Object.keys(state).length > 0 ? state : null;\n};\n\nconst useMcpLocalStorage = (opts: McpLocalStorageOptions = {}): MCPStorage => {\n const prefix = opts.keyPrefix ?? \"aui-mcp\";\n const storage = resolveStorage(opts);\n // Deriving a scope from the prefix is only honest for the shared\n // globalThis.localStorage; two custom backing stores under one prefix hold\n // different data, so an overridden backing declares no scope unless the\n // caller names one.\n const scopeId =\n opts.scopeId ??\n (opts.storage === undefined ? `local-storage:${prefix}` : undefined);\n\n // Callers key per-server coordination state on this instance, so it has to\n // stay referentially stable for as long as the underlying store does.\n return useMemo(() => {\n const customServersKey = `${prefix}:custom-servers`;\n const authKey = (id: string) => `${prefix}:auth:${id}`;\n\n const read = <T>(key: string, fallback: T): T => {\n if (!storage) return fallback;\n try {\n const raw = storage.getItem(key);\n if (raw == null) return fallback;\n return JSON.parse(raw) as T;\n } catch {\n return fallback;\n }\n };\n\n const write = (key: string, value: unknown): void => {\n if (!storage) return;\n try {\n storage.setItem(key, JSON.stringify(value));\n } catch {\n // quota or serialization failure — silently drop\n }\n };\n\n const remove = (key: string): void => {\n if (!storage) return;\n try {\n storage.removeItem(key);\n } catch {\n // ignore\n }\n };\n\n return {\n ...(scopeId !== undefined ? { scopeId } : {}),\n loadCustomServers: async () =>\n normalizeCustomServerRecords(read<unknown>(customServersKey, [])),\n saveCustomServers: async (records) => {\n write(customServersKey, records);\n },\n loadAuthState: async (id) =>\n normalizePersistedAuthState(read<unknown>(authKey(id), null)),\n saveAuthState: async (id, state) => {\n write(authKey(id), state);\n },\n clearAuthState: async (id) => {\n remove(authKey(id));\n },\n };\n }, [prefix, storage, scopeId]);\n};\n\nexport const McpLocalStorage = resource(useMcpLocalStorage);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpMemoryStorage.d.ts","names":[],"sources":["../../../src/resources/storage/McpMemoryStorage.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"McpMemoryStorage.d.ts","names":[],"sources":["../../../src/resources/storage/McpMemoryStorage.ts"],"mappings":";;cA6Ba,8CAAgB,SAAA"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
import { useMemo } from "@assistant-ui/tap/react-shim";
|
|
1
2
|
import { resource } from "@assistant-ui/tap";
|
|
3
|
+
import { generateId } from "@assistant-ui/core";
|
|
2
4
|
//#region src/resources/storage/McpMemoryStorage.ts
|
|
3
|
-
const useMcpMemoryStorage = () => {
|
|
5
|
+
const useMcpMemoryStorage = () => useMemo(() => {
|
|
4
6
|
let servers = [];
|
|
5
7
|
const auth = /* @__PURE__ */ new Map();
|
|
6
8
|
return {
|
|
9
|
+
scopeId: `memory:${generateId()}`,
|
|
7
10
|
loadCustomServers: async () => [...servers],
|
|
8
11
|
saveCustomServers: async (records) => {
|
|
9
12
|
servers = [...records];
|
|
10
13
|
},
|
|
11
14
|
loadAuthState: async (id) => auth.get(id) ?? null,
|
|
12
|
-
saveAuthState: async (
|
|
13
|
-
auth.set(
|
|
15
|
+
saveAuthState: async (id_0, state) => {
|
|
16
|
+
auth.set(id_0, state);
|
|
14
17
|
},
|
|
15
|
-
clearAuthState: async (
|
|
16
|
-
auth.delete(
|
|
18
|
+
clearAuthState: async (id_1) => {
|
|
19
|
+
auth.delete(id_1);
|
|
17
20
|
}
|
|
18
21
|
};
|
|
19
|
-
};
|
|
22
|
+
}, []);
|
|
20
23
|
const McpMemoryStorage = resource(useMcpMemoryStorage);
|
|
21
24
|
//#endregion
|
|
22
25
|
export { McpMemoryStorage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpMemoryStorage.js","names":["resource","MCPCustomServerRecord","MCPPersistedAuthState","MCPStorage","useMcpMemoryStorage","servers","auth","Map","loadCustomServers","saveCustomServers","records","loadAuthState","id","get","saveAuthState","state","set","clearAuthState","delete","McpMemoryStorage"],"sources":["../../../src/resources/storage/McpMemoryStorage.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport type { MCPCustomServerRecord } from \"../../mcp-scope\";\nimport type { MCPPersistedAuthState } from \"../../auth/types\";\nimport type { MCPStorage } from \"./types\";\n\nconst useMcpMemoryStorage = (): MCPStorage => {\n
|
|
1
|
+
{"version":3,"file":"McpMemoryStorage.js","names":["resource","useMemo","generateId","MCPCustomServerRecord","MCPPersistedAuthState","MCPStorage","useMcpMemoryStorage","servers","auth","Map","scopeId","loadCustomServers","saveCustomServers","records","loadAuthState","id","get","saveAuthState","state","set","clearAuthState","delete","McpMemoryStorage"],"sources":["../../../src/resources/storage/McpMemoryStorage.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport { useMemo } from \"react\";\nimport { generateId } from \"@assistant-ui/core\";\nimport type { MCPCustomServerRecord } from \"../../mcp-scope\";\nimport type { MCPPersistedAuthState } from \"../../auth/types\";\nimport type { MCPStorage } from \"./types\";\n\nconst useMcpMemoryStorage = (): MCPStorage =>\n useMemo(() => {\n let servers: MCPCustomServerRecord[] = [];\n const auth = new Map<string, MCPPersistedAuthState>();\n return {\n // Each memory store is its own private data: a distinct instance is a\n // distinct scope, so replacing one keys a reconnect.\n scopeId: `memory:${generateId()}`,\n loadCustomServers: async () => [...servers],\n saveCustomServers: async (records) => {\n servers = [...records];\n },\n loadAuthState: async (id) => auth.get(id) ?? null,\n saveAuthState: async (id, state) => {\n auth.set(id, state);\n },\n clearAuthState: async (id) => {\n auth.delete(id);\n },\n };\n }, []);\n\nexport const McpMemoryStorage = resource(useMcpMemoryStorage);\n"],"mappings":";;;;AAOA,MAAMM,4BACJL,cAAc;CACZ,IAAIM,UAAmC,CAAA;CACvC,MAAMC,uBAAO,IAAIC,IAAmC;CACpD,OAAO;EAGLC,SAAS,UAAUR,WAAW;EAC9BS,mBAAmB,YAAY,CAAC,GAAGJ,OAAO;EAC1CK,mBAAmB,OAAOC,YAAY;GACpCN,UAAU,CAAC,GAAGM,OAAO;EACvB;EACAC,eAAe,OAAOC,OAAOP,KAAKQ,IAAID,EAAE,KAAK;EAC7CE,eAAe,OAAOF,MAAIG,UAAU;GAClCV,KAAKW,IAAIJ,MAAIG,KAAK;EACpB;EACAE,gBAAgB,OAAOL,SAAO;GAC5BP,KAAKa,OAAON,IAAE;EAChB;CACF;AACF,GAAG,CAAA,CAAE;AAEP,MAAaO,mBAAmBtB,SAASM,mBAAmB"}
|
|
@@ -3,6 +3,18 @@ import { MCPPersistedAuthState } from "../../auth/types.js";
|
|
|
3
3
|
import { ResourceElement } from "@assistant-ui/tap";
|
|
4
4
|
//#region src/resources/storage/types.d.ts
|
|
5
5
|
type MCPStorage = {
|
|
6
|
+
/**
|
|
7
|
+
* Stable identity of the backing store. Two storages with the same scopeId
|
|
8
|
+
* must read and write the same persisted data. When present, server
|
|
9
|
+
* connections and the OAuth write fence key on it, so swapping to a
|
|
10
|
+
* differently-scoped storage reconnects instead of leaving a live OAuth flow
|
|
11
|
+
* on the replaced store, and clearing through a same-scoped replacement still
|
|
12
|
+
* waits for writes queued against the storage it replaced. When absent, the
|
|
13
|
+
* fence falls back to object identity while connections never re-key at all,
|
|
14
|
+
* so a storage rebuilt on every render has to declare a scopeId; without one
|
|
15
|
+
* a clear runs unfenced against the writes queued by the object it replaced.
|
|
16
|
+
*/
|
|
17
|
+
scopeId?: string;
|
|
6
18
|
loadCustomServers: () => Promise<MCPCustomServerRecord[]>;
|
|
7
19
|
saveCustomServers: (records: MCPCustomServerRecord[]) => Promise<void>;
|
|
8
20
|
loadAuthState: (serverId: string) => Promise<MCPPersistedAuthState | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/resources/storage/types.ts"],"mappings":";;;;KAIY;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/resources/storage/types.ts"],"mappings":";;;;KAIY;;;;;;;;;;;;EAYV;EACA,yBAAyB,QAAQ;EACjC,oBAAoB,SAAS,4BAA4B;EACzD,gBAAgB,qBAAqB,QAAQ;EAC7C,gBACE,kBACA,OAAO,0BACJ;EACL,iBAAiB,qBAAqB;;KAG5B,oBAAoB,gBAAgB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MCPPersistedAuthState } from "../auth/types.js";
|
|
2
|
+
//#region src/utils/serverUrl.d.ts
|
|
3
|
+
declare const normalizeMcpServerUrl: (serverUrl: string) => string;
|
|
4
|
+
declare const isAuthStateForServerUrl: (state: MCPPersistedAuthState | null, serverUrl: string) => boolean;
|
|
5
|
+
declare const hasPersistedCredentials: (state: MCPPersistedAuthState | null) => boolean;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { hasPersistedCredentials, isAuthStateForServerUrl, normalizeMcpServerUrl };
|
|
8
|
+
//# sourceMappingURL=serverUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverUrl.d.ts","names":[],"sources":["../../src/utils/serverUrl.ts"],"mappings":";;cAEa,wBAAyB;cAGzB,0BACX,OAAO,8BACP;cAaW,0BACX,OAAO"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/utils/serverUrl.ts
|
|
2
|
+
const normalizeMcpServerUrl = (serverUrl) => new URL(serverUrl).toString();
|
|
3
|
+
const isAuthStateForServerUrl = (state, serverUrl) => {
|
|
4
|
+
if (state?.serverUrl === void 0) return false;
|
|
5
|
+
try {
|
|
6
|
+
return normalizeMcpServerUrl(state.serverUrl) === normalizeMcpServerUrl(serverUrl);
|
|
7
|
+
} catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const hasPersistedCredentials = (state) => Boolean(state?.tokens) || Boolean(state?.token);
|
|
12
|
+
//#endregion
|
|
13
|
+
export { hasPersistedCredentials, isAuthStateForServerUrl, normalizeMcpServerUrl };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=serverUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverUrl.js","names":["MCPPersistedAuthState","normalizeMcpServerUrl","serverUrl","URL","toString","isAuthStateForServerUrl","state","undefined","hasPersistedCredentials","Boolean","tokens","token"],"sources":["../../src/utils/serverUrl.ts"],"sourcesContent":["import type { MCPPersistedAuthState } from \"../auth/types\";\n\nexport const normalizeMcpServerUrl = (serverUrl: string): string =>\n new URL(serverUrl).toString();\n\nexport const isAuthStateForServerUrl = (\n state: MCPPersistedAuthState | null,\n serverUrl: string,\n): boolean => {\n if (state?.serverUrl === undefined) return false;\n try {\n return (\n normalizeMcpServerUrl(state.serverUrl) ===\n normalizeMcpServerUrl(serverUrl)\n );\n } catch {\n return false;\n }\n};\n\nexport const hasPersistedCredentials = (\n state: MCPPersistedAuthState | null,\n): boolean => Boolean(state?.tokens) || Boolean(state?.token);\n"],"mappings":";AAEA,MAAaC,yBAAyBC,cACpC,IAAIC,IAAID,SAAS,CAAC,CAACE,SAAS;AAE9B,MAAaC,2BACXC,OACAJ,cACY;CACZ,IAAII,OAAOJ,cAAcK,KAAAA,GAAW,OAAO;CAC3C,IAAI;EACF,OACEN,sBAAsBK,MAAMJ,SAAS,MACrCD,sBAAsBC,SAAS;CAEnC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,MAAaM,2BACXF,UACYG,QAAQH,OAAOI,MAAM,KAAKD,QAAQH,OAAOK,KAAK"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "MCP server configuration and connection primitives for @assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@assistant-ui/core": "0.3.
|
|
31
|
-
"@assistant-ui/store": "0.3.
|
|
32
|
-
"@assistant-ui/tap": "0.9.
|
|
30
|
+
"@assistant-ui/core": "^0.3.18",
|
|
31
|
+
"@assistant-ui/store": "^0.3.13",
|
|
32
|
+
"@assistant-ui/tap": "^0.9.17",
|
|
33
33
|
"@modelcontextprotocol/client": "^2.0.0",
|
|
34
34
|
"@modelcontextprotocol/core": "^2.0.0",
|
|
35
35
|
"@radix-ui/react-primitive": "^2.1.10",
|
|
36
|
-
"assistant-stream": "0.3.
|
|
36
|
+
"assistant-stream": "^0.3.42"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@types/react": "*",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
48
|
+
"@assistant-ui/x-buildutils": "0.0.26",
|
|
49
49
|
"@testing-library/dom": "^10.4.1",
|
|
50
|
-
"@testing-library/react": "^16.3.
|
|
50
|
+
"@testing-library/react": "^16.3.3",
|
|
51
51
|
"@types/react": "^19.2.18",
|
|
52
52
|
"jsdom": "^30.0.1",
|
|
53
53
|
"react": "^19.2.8",
|