@assistant-ui/react-mcp 0.1.19 → 0.1.21
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/LICENSE +1 -1
- package/dist/auth/buildHeaders.d.ts +2 -4
- package/dist/auth/buildHeaders.d.ts.map +1 -1
- package/dist/auth/createOAuthProvider.d.ts +19 -20
- package/dist/auth/createOAuthProvider.d.ts.map +1 -1
- package/dist/auth/types.d.ts +12 -14
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/connector.d.ts +1 -3
- package/dist/connector.d.ts.map +1 -1
- package/dist/context/McpConnectorByIndexProvider.d.ts +2 -4
- package/dist/context/McpConnectorByIndexProvider.d.ts.map +1 -1
- package/dist/context/McpConnectorByIndexProvider.js +1 -1
- package/dist/context/McpConnectorByIndexProvider.js.map +1 -1
- package/dist/context/McpCustomServerByIndexProvider.d.ts +2 -4
- package/dist/context/McpCustomServerByIndexProvider.d.ts.map +1 -1
- package/dist/context/McpCustomServerByIndexProvider.js +1 -1
- package/dist/context/McpCustomServerByIndexProvider.js.map +1 -1
- package/dist/context/McpServerByIdProvider.d.ts +2 -4
- package/dist/context/McpServerByIdProvider.d.ts.map +1 -1
- package/dist/context/McpServerByIdProvider.js +1 -1
- package/dist/context/McpServerByIdProvider.js.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.d.ts +9 -11
- package/dist/hooks/useMcpOAuthCallback.d.ts.map +1 -1
- package/dist/hooks/useMcpOAuthCallback.js +2 -2
- package/dist/hooks/useMcpOAuthCallback.js.map +1 -1
- package/dist/index.d.ts +19 -18
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -4
- package/dist/mcp-scope.d.ts +110 -112
- package/dist/mcp-scope.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormAuthFields.d.ts +12 -14
- package/dist/primitives/addForm/McpAddFormAuthFields.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormAuthFields.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormAuthSelect.d.ts +3 -5
- package/dist/primitives/addForm/McpAddFormAuthSelect.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormAuthSelect.js +1 -1
- package/dist/primitives/addForm/McpAddFormAuthSelect.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormBearerTokenField.d.ts +3 -5
- package/dist/primitives/addForm/McpAddFormBearerTokenField.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormBearerTokenField.js +1 -1
- package/dist/primitives/addForm/McpAddFormBearerTokenField.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormCancel.d.ts +4 -6
- package/dist/primitives/addForm/McpAddFormCancel.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormCancel.js +1 -1
- package/dist/primitives/addForm/McpAddFormCancel.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormError.d.ts +4 -6
- package/dist/primitives/addForm/McpAddFormError.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormError.js +1 -1
- package/dist/primitives/addForm/McpAddFormError.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormNameField.d.ts +3 -5
- package/dist/primitives/addForm/McpAddFormNameField.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormNameField.js +1 -1
- package/dist/primitives/addForm/McpAddFormNameField.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormRoot.d.ts +9 -11
- package/dist/primitives/addForm/McpAddFormRoot.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormRoot.js +2 -2
- package/dist/primitives/addForm/McpAddFormScopesField.d.ts +3 -5
- package/dist/primitives/addForm/McpAddFormScopesField.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormScopesField.js +1 -1
- package/dist/primitives/addForm/McpAddFormScopesField.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormSubmit.d.ts +4 -6
- package/dist/primitives/addForm/McpAddFormSubmit.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormSubmit.js +1 -1
- package/dist/primitives/addForm/McpAddFormSubmit.js.map +1 -1
- package/dist/primitives/addForm/McpAddFormUrlField.d.ts +3 -5
- package/dist/primitives/addForm/McpAddFormUrlField.d.ts.map +1 -1
- package/dist/primitives/addForm/McpAddFormUrlField.js +1 -1
- package/dist/primitives/addForm/McpAddFormUrlField.js.map +1 -1
- package/dist/primitives/addForm/context.d.ts +18 -20
- package/dist/primitives/addForm/context.d.ts.map +1 -1
- package/dist/primitives/addForm.d.ts +10 -15
- package/dist/primitives/addForm.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveAccept.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveAccept.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveAccept.js +2 -2
- package/dist/primitives/elicitation/McpElicitationPrimitiveAccept.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveCancel.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveCancel.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveCancel.js +2 -2
- package/dist/primitives/elicitation/McpElicitationPrimitiveCancel.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveDecline.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveDecline.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveDecline.js +2 -2
- package/dist/primitives/elicitation/McpElicitationPrimitiveDecline.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveError.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveError.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveError.js +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveError.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveFields.d.ts +6 -8
- package/dist/primitives/elicitation/McpElicitationPrimitiveFields.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveFields.js +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveFields.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveItems.d.ts +6 -9
- package/dist/primitives/elicitation/McpElicitationPrimitiveItems.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveItems.js +2 -2
- package/dist/primitives/elicitation/McpElicitationPrimitiveItems.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveMessage.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveMessage.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveMessage.js +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveMessage.js.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveRoot.d.ts +4 -6
- package/dist/primitives/elicitation/McpElicitationPrimitiveRoot.d.ts.map +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveRoot.js +1 -1
- package/dist/primitives/elicitation/McpElicitationPrimitiveRoot.js.map +1 -1
- package/dist/primitives/elicitation/context.d.ts +8 -10
- package/dist/primitives/elicitation/context.d.ts.map +1 -1
- package/dist/primitives/elicitation/initialElicitationDraft.d.ts +0 -2
- package/dist/primitives/elicitation/initialElicitationDraft.d.ts.map +1 -1
- package/dist/primitives/elicitation/prepareElicitationContent.d.ts +3 -5
- package/dist/primitives/elicitation/prepareElicitationContent.d.ts.map +1 -1
- package/dist/primitives/elicitation.d.ts +8 -14
- package/dist/primitives/elicitation.d.ts.map +1 -1
- package/dist/primitives/manager/McpManagerAddCustomTrigger.d.ts +4 -6
- package/dist/primitives/manager/McpManagerAddCustomTrigger.d.ts.map +1 -1
- package/dist/primitives/manager/McpManagerAddCustomTrigger.js +1 -1
- package/dist/primitives/manager/McpManagerAddCustomTrigger.js.map +1 -1
- package/dist/primitives/manager/McpManagerConnectors.d.ts +12 -14
- package/dist/primitives/manager/McpManagerConnectors.d.ts.map +1 -1
- package/dist/primitives/manager/McpManagerConnectors.js +1 -1
- package/dist/primitives/manager/McpManagerCustomServers.d.ts +12 -14
- package/dist/primitives/manager/McpManagerCustomServers.d.ts.map +1 -1
- package/dist/primitives/manager/McpManagerCustomServers.js +1 -1
- package/dist/primitives/manager/McpManagerRoot.d.ts +4 -6
- package/dist/primitives/manager/McpManagerRoot.d.ts.map +1 -1
- package/dist/primitives/manager/McpManagerRoot.js +2 -2
- package/dist/primitives/manager/McpManagerRoot.js.map +1 -1
- package/dist/primitives/manager.d.ts +4 -9
- package/dist/primitives/manager.d.ts.map +1 -1
- package/dist/primitives/server/McpServerConnectButton.d.ts +4 -6
- package/dist/primitives/server/McpServerConnectButton.d.ts.map +1 -1
- package/dist/primitives/server/McpServerConnectButton.js +2 -2
- package/dist/primitives/server/McpServerConnectButton.js.map +1 -1
- package/dist/primitives/server/McpServerDisconnectButton.d.ts +4 -6
- package/dist/primitives/server/McpServerDisconnectButton.d.ts.map +1 -1
- package/dist/primitives/server/McpServerDisconnectButton.js +2 -2
- package/dist/primitives/server/McpServerDisconnectButton.js.map +1 -1
- package/dist/primitives/server/McpServerError.d.ts +4 -6
- package/dist/primitives/server/McpServerError.d.ts.map +1 -1
- package/dist/primitives/server/McpServerError.js +2 -2
- package/dist/primitives/server/McpServerError.js.map +1 -1
- package/dist/primitives/server/McpServerIcon.d.ts +11 -13
- package/dist/primitives/server/McpServerIcon.d.ts.map +1 -1
- package/dist/primitives/server/McpServerIcon.js +2 -2
- package/dist/primitives/server/McpServerIcon.js.map +1 -1
- package/dist/primitives/server/McpServerName.d.ts +4 -6
- package/dist/primitives/server/McpServerName.d.ts.map +1 -1
- package/dist/primitives/server/McpServerName.js +2 -2
- package/dist/primitives/server/McpServerName.js.map +1 -1
- package/dist/primitives/server/McpServerOAuthLink.d.ts +9 -11
- package/dist/primitives/server/McpServerOAuthLink.d.ts.map +1 -1
- package/dist/primitives/server/McpServerOAuthLink.js +2 -2
- package/dist/primitives/server/McpServerOAuthLink.js.map +1 -1
- package/dist/primitives/server/McpServerRemoveButton.d.ts +4 -6
- package/dist/primitives/server/McpServerRemoveButton.d.ts.map +1 -1
- package/dist/primitives/server/McpServerRemoveButton.js +2 -2
- package/dist/primitives/server/McpServerRemoveButton.js.map +1 -1
- package/dist/primitives/server/McpServerRoot.d.ts +4 -6
- package/dist/primitives/server/McpServerRoot.d.ts.map +1 -1
- package/dist/primitives/server/McpServerRoot.js +2 -2
- package/dist/primitives/server/McpServerRoot.js.map +1 -1
- package/dist/primitives/server/McpServerStatus.d.ts +4 -6
- package/dist/primitives/server/McpServerStatus.d.ts.map +1 -1
- package/dist/primitives/server/McpServerStatus.js +2 -2
- package/dist/primitives/server/McpServerStatus.js.map +1 -1
- package/dist/primitives/server/McpServerToolName.d.ts +4 -6
- package/dist/primitives/server/McpServerToolName.d.ts.map +1 -1
- package/dist/primitives/server/McpServerToolName.js +1 -1
- package/dist/primitives/server/McpServerToolName.js.map +1 -1
- package/dist/primitives/server/McpServerTools.d.ts +5 -7
- package/dist/primitives/server/McpServerTools.d.ts.map +1 -1
- package/dist/primitives/server/McpServerTools.js +2 -2
- package/dist/primitives/server/McpServerTools.js.map +1 -1
- package/dist/primitives/server.d.ts +11 -16
- package/dist/primitives/server.d.ts.map +1 -1
- package/dist/resources/McpManagerResource.d.ts +11 -13
- package/dist/resources/McpManagerResource.d.ts.map +1 -1
- package/dist/resources/McpManagerResource.js +2 -2
- package/dist/resources/McpManagerResource.js.map +1 -1
- package/dist/resources/McpServerRemovalFence.d.ts +1 -3
- package/dist/resources/McpServerRemovalFence.d.ts.map +1 -1
- package/dist/resources/McpServerResource.d.ts +18 -20
- package/dist/resources/McpServerResource.d.ts.map +1 -1
- package/dist/resources/McpServerResource.js +51 -43
- package/dist/resources/McpServerResource.js.map +1 -1
- package/dist/resources/storage/McpCustomStorage.d.ts +1 -3
- package/dist/resources/storage/McpCustomStorage.d.ts.map +1 -1
- package/dist/resources/storage/McpLocalStorage.d.ts +14 -16
- package/dist/resources/storage/McpLocalStorage.d.ts.map +1 -1
- package/dist/resources/storage/McpLocalStorage.js +1 -1
- package/dist/resources/storage/McpLocalStorage.js.map +1 -1
- package/dist/resources/storage/McpMemoryStorage.d.ts +1 -3
- package/dist/resources/storage/McpMemoryStorage.d.ts.map +1 -1
- package/dist/resources/storage/types.d.ts +22 -24
- package/dist/resources/storage/types.d.ts.map +1 -1
- package/dist/resources/validateElicitationContent.d.ts +3 -4
- package/dist/resources/validateElicitationContent.d.ts.map +1 -1
- package/dist/utils/createMcpId.d.ts +0 -2
- package/dist/utils/createMcpId.d.ts.map +1 -1
- package/dist/utils/invokeMcpCallback.d.ts +0 -2
- package/dist/utils/invokeMcpCallback.d.ts.map +1 -1
- package/dist/utils/serverId.d.ts +0 -2
- package/dist/utils/serverId.d.ts.map +1 -1
- package/dist/utils/serverUrl.d.ts +1 -3
- package/dist/utils/serverUrl.d.ts.map +1 -1
- package/package.json +12 -9
- package/src/resources/McpServerResource.test.ts +112 -0
- package/src/resources/McpServerResource.ts +22 -7
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { clearOAuthProviderAuthState } from "../auth/createOAuthProvider.js";
|
|
1
2
|
import { assertUniqueServerIds } from "../utils/serverId.js";
|
|
2
3
|
import { createMcpId } from "../utils/createMcpId.js";
|
|
3
|
-
import { clearOAuthProviderAuthState } from "../auth/createOAuthProvider.js";
|
|
4
4
|
import { withMcpServerRemovalFence } from "./McpServerRemovalFence.js";
|
|
5
5
|
import { McpServerResource } from "./McpServerResource.js";
|
|
6
6
|
import { McpLocalStorage } from "./storage/McpLocalStorage.js";
|
|
7
|
-
import { attachTransformScopes, useAssistantClientRef, useClientLookup } from "@assistant-ui/store";
|
|
8
7
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
8
|
+
import { attachTransformScopes, useAssistantClientRef, useClientLookup } from "@assistant-ui/store";
|
|
9
9
|
import { useEffect, useEffectEvent, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
10
10
|
import { resource, useResource, withKey } from "@assistant-ui/tap";
|
|
11
11
|
import { useAssistantScopeEffect } from "@assistant-ui/store/client";
|
|
@@ -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","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","_c","storageElement","serverElements"],"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,6 +1,4 @@
|
|
|
1
|
-
import { McpServerResourceProps } from "./McpServerResource.js";
|
|
2
|
-
//#region src/resources/McpServerRemovalFence.d.ts
|
|
1
|
+
import type { McpServerResourceProps } from "./McpServerResource.js";
|
|
3
2
|
export declare const withMcpServerRemovalFence: (props: McpServerResourceProps, beginRemovalFence: () => () => void) => McpServerResourceProps;
|
|
4
3
|
export declare const beginMcpServerRemovalFence: (props: McpServerResourceProps) => (() => void) | undefined;
|
|
5
|
-
//#endregion
|
|
6
4
|
//# sourceMappingURL=McpServerRemovalFence.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpServerRemovalFence.d.ts","
|
|
1
|
+
{"version":3,"file":"McpServerRemovalFence.d.ts","sourceRoot":"","sources":["../../src/resources/McpServerRemovalFence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,+BAA4B;AAQlE,eAAO,MAAM,yBAAyB,GACpC,OAAO,sBAAsB,EAC7B,mBAAmB,MAAM,MAAM,IAAI,KAClC,sBAI2B,CAAC;AAE/B,eAAO,MAAM,0BAA0B,GACrC,OAAO,sBAAsB,KAC5B,CAAC,MAAM,IAAI,CAAC,GAAG,SACsD,CAAC"}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { MCPStorage } from "./storage/types.js";
|
|
3
|
-
import {
|
|
4
|
-
//#region src/resources/McpServerResource.d.ts
|
|
1
|
+
import type { ClientOutput } from "@assistant-ui/store";
|
|
2
|
+
import type { MCPStorage } from "./storage/types.js";
|
|
3
|
+
import type { MCPAuthConfig, MCPServerKind } from "../mcp-scope.js";
|
|
5
4
|
export type McpServerResourceProps = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
5
|
+
id: string;
|
|
6
|
+
kind: MCPServerKind;
|
|
7
|
+
name: string;
|
|
8
|
+
url: string;
|
|
9
|
+
icon?: string | undefined;
|
|
10
|
+
auth: MCPAuthConfig;
|
|
11
|
+
storage: MCPStorage;
|
|
12
|
+
redirectUri: string;
|
|
13
|
+
autoConnect: boolean;
|
|
14
|
+
connectionTimeout?: number | undefined;
|
|
15
|
+
cache?: {
|
|
16
|
+
readonly defaultTtlMs?: number;
|
|
17
|
+
} | undefined;
|
|
18
|
+
readonly elicitation?: boolean;
|
|
19
|
+
onRemove: () => Promise<void>;
|
|
21
20
|
};
|
|
22
21
|
export declare const getConnectionDependencies: (props: McpServerResourceProps) => readonly unknown[];
|
|
23
22
|
export declare const McpServerResource: import("@assistant-ui/tap").Resource<ClientOutput<"mcpServer">, [props: McpServerResourceProps]>;
|
|
24
|
-
//#endregion
|
|
25
23
|
//# sourceMappingURL=McpServerResource.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpServerResource.d.ts","
|
|
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,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createMcpId } from "../utils/createMcpId.js";
|
|
1
|
+
import { buildHeaders } from "../auth/buildHeaders.js";
|
|
3
2
|
import { hasPersistedCredentials, isAuthStateForServerUrl } from "../utils/serverUrl.js";
|
|
4
3
|
import { clearOAuthProviderAuthState, createOAuthProvider, hasUsableOAuthTokens } from "../auth/createOAuthProvider.js";
|
|
5
|
-
import {
|
|
4
|
+
import { assertValidServerId } from "../utils/serverId.js";
|
|
5
|
+
import { createMcpId } from "../utils/createMcpId.js";
|
|
6
6
|
import { validateElicitationContent } from "./validateElicitationContent.js";
|
|
7
7
|
import { beginMcpServerRemovalFence } from "./McpServerRemovalFence.js";
|
|
8
8
|
import { useEffect, useEffectEvent, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
@@ -46,6 +46,7 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
46
46
|
const clientRef = useRef(null);
|
|
47
47
|
const transportRef = useRef(null);
|
|
48
48
|
const pendingTransportRef = useRef(null);
|
|
49
|
+
const transportGenerationRef = useRef(/* @__PURE__ */ new WeakMap());
|
|
49
50
|
const connectionGenerationRef = useRef(0);
|
|
50
51
|
const pendingAuthValidationRef = useRef(null);
|
|
51
52
|
const elicitationResolversRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -129,17 +130,22 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
129
130
|
unbound: hasPersistedCredentials(state)
|
|
130
131
|
};
|
|
131
132
|
});
|
|
132
|
-
const buildTransport = useEffectEvent(async () => {
|
|
133
|
+
const buildTransport = useEffectEvent(async (generation_0) => {
|
|
133
134
|
if (props.auth.type === "oauth") {
|
|
135
|
+
const generationOwner = { current: generation_0 };
|
|
134
136
|
const authProvider = createOAuthProvider({
|
|
135
137
|
serverId: props.id,
|
|
136
138
|
serverUrl: props.url,
|
|
137
139
|
config: props.auth,
|
|
138
140
|
storage: props.storage,
|
|
139
141
|
redirectUri: props.redirectUri,
|
|
140
|
-
onAuthorizationUrl: (url) =>
|
|
142
|
+
onAuthorizationUrl: (url) => {
|
|
143
|
+
if (isCurrentConnection(generationOwner.current)) setAuthorizationUrl(url.toString());
|
|
144
|
+
}
|
|
141
145
|
});
|
|
142
|
-
|
|
146
|
+
const transport_2 = new StreamableHTTPClientTransport(new URL(props.url), { authProvider });
|
|
147
|
+
transportGenerationRef.current.set(transport_2, generationOwner);
|
|
148
|
+
return transport_2;
|
|
143
149
|
}
|
|
144
150
|
if (props.auth.type === "bearer") {
|
|
145
151
|
const { state: state_0, unbound } = await loadAuthState();
|
|
@@ -161,21 +167,21 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
161
167
|
return info;
|
|
162
168
|
}));
|
|
163
169
|
});
|
|
164
|
-
const syncTools = useEffectEvent(async (client,
|
|
170
|
+
const syncTools = useEffectEvent(async (client, generation_1, options) => {
|
|
165
171
|
const listPromise = client.listTools();
|
|
166
172
|
const list_0 = options?.startedAt === void 0 ? await listPromise : await withConnectionTimeout(listPromise, "listing tools", options.startedAt);
|
|
167
|
-
if (!isCurrentConnection(
|
|
173
|
+
if (!isCurrentConnection(generation_1)) return false;
|
|
168
174
|
applyToolsList(list_0);
|
|
169
175
|
return true;
|
|
170
176
|
});
|
|
171
|
-
const finalizeConnect = useEffectEvent(async (
|
|
177
|
+
const finalizeConnect = useEffectEvent(async (transport_3, generation_2) => {
|
|
172
178
|
const clientOptions = {
|
|
173
179
|
...props.elicitation === false ? {} : { capabilities: { elicitation: {} } },
|
|
174
180
|
listChanged: { tools: {
|
|
175
181
|
autoRefresh: true,
|
|
176
182
|
debounceMs: 300,
|
|
177
183
|
onChanged: (error_0, items) => {
|
|
178
|
-
if (!isCurrentConnection(
|
|
184
|
+
if (!isCurrentConnection(generation_2)) return;
|
|
179
185
|
if (error_0 !== null) {
|
|
180
186
|
setLastError({ message: error_0.message });
|
|
181
187
|
return;
|
|
@@ -192,7 +198,7 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
192
198
|
version: "0.0.0"
|
|
193
199
|
}, clientOptions);
|
|
194
200
|
if (props.elicitation !== false) client_0.setRequestHandler("elicitation/create", (request, context) => {
|
|
195
|
-
if (!isCurrentConnection(
|
|
201
|
+
if (!isCurrentConnection(generation_2)) return Promise.resolve({ action: "cancel" });
|
|
196
202
|
if (!("requestedSchema" in request.params)) return Promise.resolve({ action: "cancel" });
|
|
197
203
|
const { message, requestedSchema } = request.params;
|
|
198
204
|
const id_2 = createMcpId();
|
|
@@ -220,43 +226,43 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
220
226
|
return promise_0;
|
|
221
227
|
});
|
|
222
228
|
const startedAt_0 = Date.now();
|
|
223
|
-
await withConnectionTimeout(client_0.connect(
|
|
224
|
-
if (!isCurrentConnection(
|
|
225
|
-
if (!await syncTools(client_0,
|
|
229
|
+
await withConnectionTimeout(client_0.connect(transport_3), "connecting", startedAt_0);
|
|
230
|
+
if (!isCurrentConnection(generation_2)) return false;
|
|
231
|
+
if (!await syncTools(client_0, generation_2, { startedAt: startedAt_0 })) return false;
|
|
226
232
|
pendingTransportRef.current = null;
|
|
227
233
|
clientRef.current = client_0;
|
|
228
|
-
transportRef.current =
|
|
234
|
+
transportRef.current = transport_3;
|
|
229
235
|
setConnectionState("connected");
|
|
230
236
|
return true;
|
|
231
237
|
});
|
|
232
238
|
const doConnect = useEffectEvent(async () => {
|
|
233
|
-
const
|
|
239
|
+
const generation_3 = ++connectionGenerationRef.current;
|
|
234
240
|
await closeTransports();
|
|
235
|
-
if (!isCurrentConnection(
|
|
241
|
+
if (!isCurrentConnection(generation_3)) return;
|
|
236
242
|
setConnectionState("connecting");
|
|
237
243
|
setLastError(null);
|
|
238
244
|
setAuthorizationUrl(null);
|
|
239
245
|
setTools([]);
|
|
240
|
-
let
|
|
246
|
+
let transport_4 = null;
|
|
241
247
|
try {
|
|
242
|
-
|
|
243
|
-
if (!isCurrentConnection(
|
|
244
|
-
await closeQueuedTransports([
|
|
248
|
+
transport_4 = await buildTransport(generation_3);
|
|
249
|
+
if (!isCurrentConnection(generation_3)) {
|
|
250
|
+
await closeQueuedTransports([transport_4]);
|
|
245
251
|
return;
|
|
246
252
|
}
|
|
247
|
-
pendingTransportRef.current =
|
|
248
|
-
await finalizeConnect(
|
|
253
|
+
pendingTransportRef.current = transport_4;
|
|
254
|
+
await finalizeConnect(transport_4, generation_3);
|
|
249
255
|
} catch (err) {
|
|
250
|
-
if (!isCurrentConnection(
|
|
256
|
+
if (!isCurrentConnection(generation_3)) return;
|
|
251
257
|
if (err instanceof UnauthorizedError) {
|
|
252
258
|
pendingTransportRef.current = null;
|
|
253
|
-
transportRef.current =
|
|
259
|
+
transportRef.current = transport_4;
|
|
254
260
|
setConnectionState("authRequired");
|
|
255
261
|
} else {
|
|
256
262
|
cancelPendingElicitations();
|
|
257
|
-
if (
|
|
263
|
+
if (transport_4) {
|
|
258
264
|
pendingTransportRef.current = null;
|
|
259
|
-
await closeQueuedTransports([
|
|
265
|
+
await closeQueuedTransports([transport_4]);
|
|
260
266
|
}
|
|
261
267
|
setLastError({ message: err instanceof Error ? err.message : String(err) });
|
|
262
268
|
setConnectionState("error");
|
|
@@ -302,31 +308,33 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
302
308
|
pendingAuthValidation.resolve();
|
|
303
309
|
}
|
|
304
310
|
}
|
|
305
|
-
const
|
|
311
|
+
const generation_4 = ++connectionGenerationRef.current;
|
|
306
312
|
cancelPendingElicitations();
|
|
307
313
|
await closePendingTransport();
|
|
308
|
-
if (!isCurrentConnection(
|
|
314
|
+
if (!isCurrentConnection(generation_4)) throw createInterruptedAuthError();
|
|
309
315
|
setConnectionState("authPending");
|
|
310
316
|
setLastError(null);
|
|
311
317
|
try {
|
|
312
|
-
let
|
|
313
|
-
if (!
|
|
314
|
-
|
|
315
|
-
if (!isCurrentConnection(
|
|
316
|
-
await closeQueuedTransports([
|
|
318
|
+
let transport_5 = transportRef.current;
|
|
319
|
+
if (!transport_5) {
|
|
320
|
+
transport_5 = await buildTransport(generation_4);
|
|
321
|
+
if (!isCurrentConnection(generation_4)) {
|
|
322
|
+
await closeQueuedTransports([transport_5]);
|
|
317
323
|
throw createInterruptedAuthError();
|
|
318
324
|
}
|
|
319
325
|
}
|
|
326
|
+
const generationOwner_0 = transportGenerationRef.current.get(transport_5);
|
|
327
|
+
if (generationOwner_0) generationOwner_0.current = generation_4;
|
|
320
328
|
transportRef.current = null;
|
|
321
329
|
clientRef.current = null;
|
|
322
|
-
pendingTransportRef.current =
|
|
323
|
-
await
|
|
324
|
-
if (!isCurrentConnection(
|
|
330
|
+
pendingTransportRef.current = transport_5;
|
|
331
|
+
await transport_5.finishAuth(url_0.searchParams);
|
|
332
|
+
if (!isCurrentConnection(generation_4)) throw createInterruptedAuthError();
|
|
325
333
|
setAuthorizationUrl(null);
|
|
326
|
-
if (!await finalizeConnect(
|
|
334
|
+
if (!await finalizeConnect(transport_5, generation_4)) throw createInterruptedAuthError();
|
|
327
335
|
} catch (err_0) {
|
|
328
336
|
const error_1 = err_0 instanceof Error ? err_0 : new Error(String(err_0));
|
|
329
|
-
if (!isCurrentConnection(
|
|
337
|
+
if (!isCurrentConnection(generation_4)) throw createInterruptedAuthError(error_1);
|
|
330
338
|
await closeTransports();
|
|
331
339
|
setLastError({ message: error_1.message });
|
|
332
340
|
setConnectionState("error");
|
|
@@ -343,18 +351,18 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
343
351
|
doConnect();
|
|
344
352
|
return;
|
|
345
353
|
}
|
|
346
|
-
const
|
|
354
|
+
const generation_5 = connectionGenerationRef.current;
|
|
347
355
|
let loaded;
|
|
348
356
|
try {
|
|
349
357
|
loaded = await loadAuthState();
|
|
350
358
|
} catch (error_2) {
|
|
351
|
-
if (signal.cancelled || !isCurrentConnection(
|
|
359
|
+
if (signal.cancelled || !isCurrentConnection(generation_5)) return;
|
|
352
360
|
const message_0 = error_2 instanceof Error ? error_2.message : String(error_2);
|
|
353
361
|
setLastError({ message: `MCP server "${props.id}" failed to load saved authentication: ${message_0}` });
|
|
354
362
|
setConnectionState("error");
|
|
355
363
|
return;
|
|
356
364
|
}
|
|
357
|
-
if (signal.cancelled || !isCurrentConnection(
|
|
365
|
+
if (signal.cancelled || !isCurrentConnection(generation_5)) return;
|
|
358
366
|
if (loaded.unbound) {
|
|
359
367
|
setLastError({ message: unboundAuthMessage() });
|
|
360
368
|
return;
|
|
@@ -366,7 +374,7 @@ const useMcpServerResourceInstance = (props) => {
|
|
|
366
374
|
const pendingAuthValidation_0 = pendingAuthValidationRef.current;
|
|
367
375
|
if (pendingAuthValidation_0) {
|
|
368
376
|
await pendingAuthValidation_0.promise;
|
|
369
|
-
if (signal.cancelled || !isCurrentConnection(
|
|
377
|
+
if (signal.cancelled || !isCurrentConnection(generation_5)) return;
|
|
370
378
|
}
|
|
371
379
|
doConnect();
|
|
372
380
|
});
|