@agent-vm/mcp-portal 0.0.73 → 0.0.74
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/bin/mcp-portal.js +3 -3
- package/dist/cli/index.js +1 -1
- package/dist/core/index.js +2 -2
- package/dist/index.js +1 -1
- package/dist/{portal-core-Cgu714CL.js → portal-core-BPSvDGvi.js} +2 -2
- package/dist/{portal-core-Cgu714CL.js.map → portal-core-BPSvDGvi.js.map} +1 -1
- package/dist/{serve-command-D3SlETy_.js → serve-command-CV1s-Eln.js} +3 -3
- package/dist/{serve-command-D3SlETy_.js.map → serve-command-CV1s-Eln.js.map} +1 -1
- package/dist/{upstream-mcp-client-runtime-JlsfTm7_.js → upstream-mcp-client-runtime-DbPkS6Rk.js} +27 -2
- package/dist/upstream-mcp-client-runtime-DbPkS6Rk.js.map +1 -0
- package/dist/upstream-response-middleware-1MZnAD9C.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/upstream-mcp-client-runtime-JlsfTm7_.js.map +0 -1
package/dist/bin/mcp-portal.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as portalToolRecordSchema } from "../zod-schema-loader-yNekKNpm.js";
|
|
3
|
-
import { t as createUpstreamMcpClientRuntime } from "../upstream-mcp-client-runtime-
|
|
4
|
-
import { i as resolveUpstreamServers, n as createPortalCore } from "../portal-core-
|
|
3
|
+
import { t as createUpstreamMcpClientRuntime } from "../upstream-mcp-client-runtime-DbPkS6Rk.js";
|
|
4
|
+
import { i as resolveUpstreamServers, n as createPortalCore } from "../portal-core-BPSvDGvi.js";
|
|
5
5
|
import { t as generateTypescriptCatalogArtifact } from "../typescript-artifact-BVLt3Ifd.js";
|
|
6
6
|
import { n as deriveAgentBearerToken, r as formatMasterKeyFingerprint, t as decodePortalMasterKey } from "../agent-bearer-token-DCtpDPCZ.js";
|
|
7
7
|
import { i as resolveAgentHmacKeys, n as createPortalApprovalVerifier, t as createPortalAgentRuntimeRecords } from "../resolve-agent-identity-DnC_Pmnh.js";
|
|
8
|
-
import { c as resolveSecretValue, i as deriveApprovalHmacKeysFromMasterKey, n as buildProfilePolicyMaps, o as parsePortalServerCliArgs, r as createServeSecretResolver, s as startPortalServer } from "../serve-command-
|
|
8
|
+
import { c as resolveSecretValue, i as deriveApprovalHmacKeysFromMasterKey, n as buildProfilePolicyMaps, o as parsePortalServerCliArgs, r as createServeSecretResolver, s as startPortalServer } from "../serve-command-CV1s-Eln.js";
|
|
9
9
|
import { t as parseHmacKeysFromEnv } from "../hmac-env-B4shpRRB.js";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
import { loadMcpConfig, loadMcpPortalConfig } from "@agent-vm/config-contracts";
|
package/dist/cli/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as handlePortalServerError, i as deriveApprovalHmacKeysFromMasterKey, n as buildProfilePolicyMaps, o as parsePortalServerCliArgs, r as createServeSecretResolver, s as startPortalServer, t as applyAgentOverrides } from "../serve-command-
|
|
1
|
+
import { a as handlePortalServerError, i as deriveApprovalHmacKeysFromMasterKey, n as buildProfilePolicyMaps, o as parsePortalServerCliArgs, r as createServeSecretResolver, s as startPortalServer, t as applyAgentOverrides } from "../serve-command-CV1s-Eln.js";
|
|
2
2
|
export { applyAgentOverrides, buildProfilePolicyMaps, createServeSecretResolver, deriveApprovalHmacKeysFromMasterKey, handlePortalServerError, parsePortalServerCliArgs, startPortalServer };
|
package/dist/core/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as redactCredentialText } from "../upstream-response-middleware-BjUWZ2G8.js";
|
|
2
|
-
import { t as createUpstreamMcpClientRuntime } from "../upstream-mcp-client-runtime-
|
|
3
|
-
import { i as resolveUpstreamServers, n as createPortalCore, r as listPortalCoreToolDescriptors, t as collectPortalCoreResult } from "../portal-core-
|
|
2
|
+
import { t as createUpstreamMcpClientRuntime } from "../upstream-mcp-client-runtime-DbPkS6Rk.js";
|
|
3
|
+
import { i as resolveUpstreamServers, n as createPortalCore, r as listPortalCoreToolDescriptors, t as collectPortalCoreResult } from "../portal-core-BPSvDGvi.js";
|
|
4
4
|
import { n as portalToolInputSchemas, r as validatePortalToolArguments, t as createPortalToolHandlers } from "../portal-tools-DKci1szO.js";
|
|
5
5
|
export { collectPortalCoreResult, createPortalCore, createPortalToolHandlers, createUpstreamMcpClientRuntime, listPortalCoreToolDescriptors, portalToolInputSchemas, redactCredentialText, resolveUpstreamServers, validatePortalToolArguments };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { a as portalToolRecordSchema, c as isJsonObject, i as portalToolAnnotationsSchema, l as jsonObjectSchema, n as decodeToolRef, o as safeToolMetadataSchema, r as encodeToolRef, s as assertJsonObject, t as buildZodValidatorFromJsonSchema, u as jsonValueSchema } from "./zod-schema-loader-yNekKNpm.js";
|
|
2
2
|
import { a as redactUpstreamCatalogValue, c as createToolSummary, d as portalAgentScopeKey, f as resolvePortalAccessPolicy, i as redactThrownError, l as summarizeJsonSchema, n as redactCredentialText, o as redactUpstreamResponse, r as redactExactCredentialText, s as toRedactedJsonValue, t as isCredentialConfigKey, u as createPortalAgentIdentity } from "./upstream-response-middleware-BjUWZ2G8.js";
|
|
3
|
-
import { i as createSearchIndex, n as createPortalSessionManager, r as buildToolGraph, t as createUpstreamMcpClientRuntime } from "./upstream-mcp-client-runtime-
|
|
3
|
+
import { i as createSearchIndex, n as createPortalSessionManager, r as buildToolGraph, t as createUpstreamMcpClientRuntime } from "./upstream-mcp-client-runtime-DbPkS6Rk.js";
|
|
4
4
|
export { assertJsonObject, buildToolGraph, buildZodValidatorFromJsonSchema, createPortalAgentIdentity, createPortalSessionManager, createSearchIndex, createToolSummary, createUpstreamMcpClientRuntime, decodeToolRef, encodeToolRef, isCredentialConfigKey, isJsonObject, jsonObjectSchema, jsonValueSchema, portalAgentScopeKey, portalToolAnnotationsSchema, portalToolRecordSchema, redactCredentialText, redactExactCredentialText, redactThrownError, redactUpstreamCatalogValue, redactUpstreamResponse, resolvePortalAccessPolicy, safeToolMetadataSchema, summarizeJsonSchema, toRedactedJsonValue };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { l as jsonObjectSchema } from "./zod-schema-loader-yNekKNpm.js";
|
|
2
2
|
import { f as resolvePortalAccessPolicy, u as createPortalAgentIdentity } from "./upstream-response-middleware-BjUWZ2G8.js";
|
|
3
|
-
import { n as createPortalSessionManager } from "./upstream-mcp-client-runtime-
|
|
3
|
+
import { n as createPortalSessionManager } from "./upstream-mcp-client-runtime-DbPkS6Rk.js";
|
|
4
4
|
import { n as portalToolInputSchemas, t as createPortalToolHandlers } from "./portal-tools-DKci1szO.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { mcpConfigToResolvedProviders } from "@agent-vm/config-contracts";
|
|
@@ -413,4 +413,4 @@ function createPortalCore(props) {
|
|
|
413
413
|
//#endregion
|
|
414
414
|
export { resolveUpstreamServers as i, createPortalCore as n, listPortalCoreToolDescriptors as r, collectPortalCoreResult as t };
|
|
415
415
|
|
|
416
|
-
//# sourceMappingURL=portal-core-
|
|
416
|
+
//# sourceMappingURL=portal-core-BPSvDGvi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal-core-Cgu714CL.js","names":[],"sources":["../src/core/provider-runtime.ts","../src/core/portal-core.ts"],"sourcesContent":["import {\n\tmcpConfigToResolvedProviders,\n\ttype McpConfig,\n\ttype ResolvedMcpProvider,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\n\nimport type { NormalizedUpstreamMcpServer } from '../upstream-mcp-client-runtime.js';\n\nexport interface ResolveUpstreamServersProps {\n\treadonly config: McpConfig;\n\treadonly resolveSecret: (secret: SecretValue) => Promise<string>;\n}\n\nasync function resolveProviderSecretRecord(\n\tsecrets: Readonly<Record<string, SecretValue>>,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<Readonly<Record<string, string>>> {\n\tconst resolvedEntries = await Promise.all(\n\t\tObject.entries(secrets).map(\n\t\t\tasync ([name, secret]) => [name, await resolveSecret(secret)] as const,\n\t\t),\n\t);\n\treturn Object.fromEntries(resolvedEntries);\n}\n\nasync function resolveUpstreamServer(\n\tprovider: ResolvedMcpProvider,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<NormalizedUpstreamMcpServer> {\n\tif (provider.transport === 'stdio') {\n\t\treturn {\n\t\t\targs: provider.args,\n\t\t\tcommand: provider.command,\n\t\t\t...(provider.cwd === undefined ? {} : { cwd: provider.cwd }),\n\t\t\tenv: await resolveProviderSecretRecord(provider.env, resolveSecret),\n\t\t\tnamespace: provider.namespace,\n\t\t\ttransport: 'stdio',\n\t\t};\n\t}\n\n\treturn {\n\t\theaders: await resolveProviderSecretRecord(provider.headers, resolveSecret),\n\t\tnamespace: provider.namespace,\n\t\ttransport: provider.transport,\n\t\turl: provider.url,\n\t};\n}\n\nexport async function resolveUpstreamServers(\n\tprops: ResolveUpstreamServersProps,\n): Promise<readonly NormalizedUpstreamMcpServer[]> {\n\treturn await Promise.all(\n\t\tmcpConfigToResolvedProviders(props.config).map(async (provider) =>\n\t\t\tresolveUpstreamServer(provider, props.resolveSecret),\n\t\t),\n\t);\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nimport { jsonObjectSchema } from '../json-schema.js';\nimport {\n\tcreatePortalAgentIdentity,\n\tresolvePortalAccessPolicy,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalAgentScopeSource,\n} from '../portal-access-policy.js';\nimport {\n\tcreatePortalSessionManager,\n\ttype PortalSessionManager,\n\ttype PortalSessionRuntime,\n} from '../portal-session.js';\nimport type { SkillGraphInput } from '../tool-graph.js';\nimport {\n\tcreatePortalToolHandlers,\n\tportalToolInputSchemas,\n\ttype PortalApprovalCall,\n\ttype PortalBatchDiagnostic,\n\ttype PortalBatchResult,\n\ttype PortalToolResult,\n\ttype PortalToolRuntime,\n} from './portal-tools.js';\n\nexport type PortalAgentScope = PortalAgentIdentity;\n\nexport type PortalCoreToolName =\n\t| 'mcp_portal_list'\n\t| 'mcp_portal_search'\n\t| 'mcp_portal_describe'\n\t| 'mcp_portal_call';\n\nexport interface PortalAuditEvent {\n\treadonly kind: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n}\n\nexport interface PortalCoreResult {\n\treadonly auditEvents?: readonly PortalAuditEvent[];\n\treadonly content: readonly PortalCoreContentBlock[];\n\treadonly items: readonly PortalCoreItemResult[];\n\treadonly structuredContent?: unknown;\n}\n\nexport type PortalCoreItemResult =\n\t| {\n\t\t\treadonly content: readonly PortalCoreContentBlock[];\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'success';\n\t\t\treadonly structuredContent?: unknown;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'failed';\n\t };\n\nexport interface PortalCoreItemError {\n\treadonly code: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n\treadonly toolName?: string;\n}\n\nexport type PortalCoreContentBlock =\n\t| { readonly text: string; readonly type: 'text' }\n\t| { readonly type: 'json'; readonly value: unknown };\n\nexport type PortalCoreEvent =\n\t| {\n\t\t\treadonly kind: 'started';\n\t\t\treadonly toolName: PortalCoreToolName;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_started';\n\t\t\treadonly namespace?: string;\n\t\t\treadonly requestId: string;\n\t\t\treadonly toolName?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress?: number;\n\t\t\treadonly requestId?: string;\n\t\t\treadonly total?: number;\n\t }\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly content: PortalCoreContentBlock;\n\t\t\treadonly kind: 'partial_content';\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_completed';\n\t\t\treadonly requestId: string;\n\t\t\treadonly result: Extract<PortalCoreItemResult, { readonly status: 'success' }>;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly kind: 'item_failed';\n\t\t\treadonly requestId: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'completed';\n\t\t\treadonly result: PortalCoreResult;\n\t }\n\t| {\n\t\t\treadonly error: unknown;\n\t\t\treadonly kind: 'failed';\n\t };\n\nexport interface PortalCoreStreamCall {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: PortalCoreToolName;\n}\n\nconst maxQueuedPortalCoreEvents = 1_024;\nconst maxPortalCoreEventBytes = 256 * 1_024;\n\nexport interface PortalCoreCollectOptions {\n\treadonly onEvent?: (event: PortalCoreEvent) => Promise<void> | void;\n}\n\nexport interface PortalCoreRuntime extends PortalSessionRuntime {\n\treadonly callUpstreamTool: PortalToolRuntime['callUpstreamTool'];\n}\n\nexport type PortalApprovalEvaluator = NonNullable<PortalToolRuntime['approval']>;\n\ninterface CreatePortalCoreBaseProps {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly runtime: PortalCoreRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport type CreatePortalCoreProps =\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval: PortalApprovalEvaluator;\n\t\t\treadonly approvalTrustBoundary?: never;\n\t })\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval?: never;\n\t\t\treadonly approvalTrustBoundary: 'openclaw-before-tool-call-hook';\n\t });\n\nexport interface PortalCore {\n\treadonly approval: {\n\t\treadonly evaluateCalls: (\n\t\t\tcalls: readonly PortalApprovalCall[],\n\t\t\tscope: PortalAgentScope,\n\t\t\tapprovalToken: string | undefined,\n\t\t) => ReturnType<PortalApprovalEvaluator>;\n\t};\n\treadonly callStream: (call: PortalCoreStreamCall) => AsyncIterable<PortalCoreEvent>;\n\treadonly close: () => Promise<void>;\n\treadonly collectPortalCoreResult: typeof collectPortalCoreResult;\n\treadonly createAgentScope: (input: {\n\t\treadonly agentId: string;\n\t\treadonly agentScopeId: string;\n\t\treadonly authSubject?: string;\n\t\treadonly sessionId?: string;\n\t\treadonly sessionKey?: string;\n\t\treadonly source: PortalAgentScopeSource;\n\t}) => PortalAgentScope;\n\treadonly describeTools: (scope: PortalAgentScope) => readonly PortalCoreToolDescriptor[];\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (scope: PortalAgentScope) => Promise<void>;\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalCoreToolDescriptor {\n\treadonly description: string;\n\treadonly inputSchema: Tool['inputSchema'];\n\treadonly name: PortalCoreToolName;\n}\n\nconst portalCallRequestSchema = z\n\t.object({\n\t\targuments: jsonObjectSchema,\n\t\tid: z.string().min(1),\n\t\tnamespace: z.string().min(1),\n\t\ttoolName: z.string().min(1),\n\t})\n\t.strict();\nconst portalCallInputSchema = z\n\t.object({\n\t\tcalls: z.array(portalCallRequestSchema).min(1),\n\t\tportalApprovalToken: z.string().min(1).optional(),\n\t})\n\t.strict();\n\nfunction diagnosticsToAuditEvents(\n\tdiagnostics: readonly PortalBatchDiagnostic[],\n): readonly PortalAuditEvent[] {\n\treturn diagnostics.map((diagnostic) => ({\n\t\tkind: diagnostic.kind,\n\t\tmessage: diagnostic.message,\n\t\t...(diagnostic.namespace !== undefined ? { namespace: diagnostic.namespace } : {}),\n\t}));\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction errorRecordFromUnknown(error: unknown): Record<string, unknown> {\n\treturn isUnknownRecord(error) ? error : {};\n}\n\nfunction messageFromUnknown(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tconst record = errorRecordFromUnknown(error);\n\tconst message = record.message;\n\treturn typeof message === 'string' ? message : String(error);\n}\n\nfunction errorFromAbortSignal(signal: AbortSignal): Error {\n\tconst reason: unknown = signal.reason;\n\treturn reason instanceof Error ? reason : new Error('MCP Portal core stream aborted.');\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow errorFromAbortSignal(signal);\n\t}\n}\n\nfunction assertPortalCoreEventSize(event: PortalCoreEvent): void {\n\tconst serialized = JSON.stringify(event);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxPortalCoreEventBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP Portal core event exceeded ${String(maxPortalCoreEventBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction waitForQueuedCoreEvent(props: {\n\treadonly setNotifyQueuedEvent: (notify: (() => void) | undefined) => void;\n\treadonly signal?: AbortSignal;\n}): Promise<void> {\n\tif (props.signal === undefined) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tprops.setNotifyQueuedEvent(resolve);\n\t\t});\n\t}\n\tconst signal = props.signal;\n\treturn new Promise<void>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tsignal.removeEventListener('abort', onAbort);\n\t\t\tprops.setNotifyQueuedEvent(undefined);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onNotify = (): void => {\n\t\t\tsettle(resolve);\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tsettle(() => reject(errorFromAbortSignal(signal)));\n\t\t};\n\t\tprops.setNotifyQueuedEvent(onNotify);\n\t\tsignal.addEventListener('abort', onAbort, { once: true });\n\t\tif (signal.aborted) {\n\t\t\tonAbort();\n\t\t}\n\t});\n}\n\nfunction itemErrorFromPortalResult(result: PortalToolResult): PortalCoreItemError {\n\tif (result.ok) {\n\t\tthrow new Error('Cannot convert successful portal result into an item error.');\n\t}\n\tconst errorRecord = errorRecordFromUnknown(result.error);\n\tconst kind = errorRecord.kind;\n\tconst namespace = errorRecord.namespace;\n\tconst toolName = errorRecord.toolName;\n\n\treturn {\n\t\tcode: typeof kind === 'string' ? kind : 'portal_item_failed',\n\t\tmessage: messageFromUnknown(result.error),\n\t\t...(typeof namespace === 'string' ? { namespace } : {}),\n\t\t...(typeof toolName === 'string' ? { toolName } : {}),\n\t};\n}\n\nfunction itemResultFromPortalToolResult(\n\trequestId: string,\n\tresult: PortalToolResult,\n): PortalCoreItemResult {\n\tif (!result.ok) {\n\t\treturn {\n\t\t\terror: itemErrorFromPortalResult(result),\n\t\t\trequestId,\n\t\t\tstatus: 'failed',\n\t\t};\n\t}\n\n\treturn {\n\t\tcontent: [{ type: 'json', value: result.output }],\n\t\trequestId,\n\t\tstatus: 'success',\n\t\tstructuredContent: result.output,\n\t};\n}\n\nfunction scalarBatchResultToCoreResult(batchResult: PortalBatchResult): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(batchResult.diagnostics),\n\t\tcontent: [{ type: 'json', value: batchResult }],\n\t\titems: [],\n\t\tstructuredContent: batchResult,\n\t};\n}\n\nfunction batchItemsToCoreResult(props: {\n\treadonly diagnostics: readonly PortalBatchDiagnostic[];\n\treadonly items: readonly PortalCoreItemResult[];\n}): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(props.diagnostics),\n\t\tcontent: [],\n\t\titems: props.items,\n\t};\n}\n\nfunction namespaceDescription(namespaces: readonly string[]): string {\n\treturn namespaces.length === 0\n\t\t? 'No upstream MCP namespaces are authorized for this agent scope.'\n\t\t: `Authorized MCP namespaces for this agent scope: ${namespaces.join(', ')}.`;\n}\n\nexport function listPortalCoreToolDescriptors(\n\tnamespaces: readonly string[] = [],\n): readonly PortalCoreToolDescriptor[] {\n\tconst scopeDescription = namespaceDescription(namespaces);\n\treturn [\n\t\t{\n\t\t\tdescription: `List authorized MCP namespaces and compact tool summaries. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_list,\n\t\t\tname: 'mcp_portal_list',\n\t\t},\n\t\t{\n\t\t\tdescription: `Search the caller scoped MCP Portal index. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_search,\n\t\t\tname: 'mcp_portal_search',\n\t\t},\n\t\t{\n\t\t\tdescription: `Describe exact MCP tool schemas and optional TypeScript/Zod helpers. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_describe,\n\t\t\tname: 'mcp_portal_describe',\n\t\t},\n\t\t{\n\t\t\tdescription: `Validate and call an authorized upstream MCP tool by namespace and toolName. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_call,\n\t\t\tname: 'mcp_portal_call',\n\t\t},\n\t];\n}\n\nexport async function collectPortalCoreResult(\n\tevents: AsyncIterable<PortalCoreEvent>,\n\toptions: PortalCoreCollectOptions = {},\n): Promise<PortalCoreResult> {\n\tlet result: PortalCoreResult | undefined;\n\tfor await (const event of events) {\n\t\tawait options.onEvent?.(event);\n\t\tif (event.kind === 'completed') {\n\t\t\tresult = event.result;\n\t\t}\n\t\tif (event.kind === 'failed') {\n\t\t\tthrow event.error;\n\t\t}\n\t}\n\tif (result === undefined) {\n\t\tthrow new Error('MCP Portal core stream ended without a completed event.');\n\t}\n\treturn result;\n}\n\nasync function* scalarToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly sessionManager: PortalSessionManager;\n\treadonly toolName: Exclude<PortalCoreToolName, 'mcp_portal_call'>;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst handlers = createPortalToolHandlers(props.toolRuntime);\n\tconst handler =\n\t\tprops.toolName === 'mcp_portal_list'\n\t\t\t? handlers.list\n\t\t\t: props.toolName === 'mcp_portal_search'\n\t\t\t\t? handlers.search\n\t\t\t\t: handlers.describe;\n\tthrowIfAborted(props.signal);\n\tconst batchResult = await handler({ identity: props.scope, input: props.input });\n\tthrowIfAborted(props.signal);\n\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n}\n\nasync function* callToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst parsedInput = portalCallInputSchema.safeParse(props.input);\n\tconst queuedEvents: PortalCoreEvent[] = [];\n\tlet notifyQueuedEvent: (() => void) | undefined;\n\tlet executionDone = false;\n\tconst pushEvent = (event: PortalCoreEvent): void => {\n\t\tassertPortalCoreEventSize(event);\n\t\tif (queuedEvents.length >= maxQueuedPortalCoreEvents) {\n\t\t\tthrow new Error(`MCP Portal core event queue exceeded ${maxQueuedPortalCoreEvents} events.`);\n\t\t}\n\t\tqueuedEvents.push(event);\n\t\tnotifyQueuedEvent?.();\n\t\tnotifyQueuedEvent = undefined;\n\t};\n\tconst streamingToolRuntime: PortalToolRuntime = {\n\t\t...props.toolRuntime,\n\t\tcallUpstreamTool: async (call) => {\n\t\t\tthrowIfAborted(props.signal);\n\t\t\tpushEvent({\n\t\t\t\tkind: 'item_started',\n\t\t\t\tnamespace: call.namespace,\n\t\t\t\trequestId: call.requestId,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t});\n\t\t\tpushEvent({\n\t\t\t\tkind: 'progress',\n\t\t\t\tmessage: `Calling upstream MCP tool ${call.namespace}.${call.toolName}.`,\n\t\t\t\trequestId: call.requestId,\n\t\t\t});\n\t\t\treturn await props.toolRuntime.callUpstreamTool({\n\t\t\t\t...call,\n\t\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t\t\tonEvent: (event) => {\n\t\t\t\t\tif (event.kind === 'progress') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t...(event.message !== undefined ? { message: event.message } : {}),\n\t\t\t\t\t\t\t...(event.progress !== undefined ? { progress: event.progress } : {}),\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t\t...(event.total !== undefined ? { total: event.total } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.kind === 'partial_content') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tcontent: event.content,\n\t\t\t\t\t\t\tkind: 'partial_content',\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tpushEvent({\n\t\t\t\t\t\tkind: 'upstream_notification',\n\t\t\t\t\t\tmethod: event.method,\n\t\t\t\t\t\tparams: event.params,\n\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n\tconst handlers = createPortalToolHandlers(streamingToolRuntime);\n\tif (!parsedInput.success) {\n\t\tconst batchResult = await handlers.call({ identity: props.scope, input: props.input });\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\n\tconst itemResults: PortalCoreItemResult[] = [];\n\tconst batchResultPromise = handlers\n\t\t.call({\n\t\t\tidentity: props.scope,\n\t\t\tinput: props.input,\n\t\t})\n\t\t.finally(() => {\n\t\t\texecutionDone = true;\n\t\t\tnotifyQueuedEvent?.();\n\t\t\tnotifyQueuedEvent = undefined;\n\t\t});\n\tconst hasPendingExecutionEvents = (): boolean => !executionDone || queuedEvents.length > 0;\n\twhile (hasPendingExecutionEvents()) {\n\t\tconst event = queuedEvents.shift();\n\t\tif (event !== undefined) {\n\t\t\tyield event;\n\t\t\tcontinue;\n\t\t}\n\t\tthrowIfAborted(props.signal);\n\t\t// Streaming consumes events as they arrive; there is no parallel work to collect here.\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tawait waitForQueuedCoreEvent({\n\t\t\tsetNotifyQueuedEvent: (notify) => {\n\t\t\t\tnotifyQueuedEvent = notify;\n\t\t\t},\n\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t});\n\t}\n\tconst batchResult = await batchResultPromise;\n\tthrowIfAborted(props.signal);\n\tif (batchResult.errors.length > 0) {\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\tfor (const request of parsedInput.data.calls) {\n\t\tconst portalResult = batchResult.results[request.id];\n\t\tconst itemResult =\n\t\t\tportalResult === undefined\n\t\t\t\t? ({\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcode: 'portal_item_missing',\n\t\t\t\t\t\t\tmessage: `MCP Portal did not return a result for request \"${request.id}\".`,\n\t\t\t\t\t\t\tnamespace: request.namespace,\n\t\t\t\t\t\t\ttoolName: request.toolName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequestId: request.id,\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t} satisfies PortalCoreItemResult)\n\t\t\t\t: itemResultFromPortalToolResult(request.id, portalResult);\n\t\titemResults.push(itemResult);\n\t\tif (itemResult.status === 'success') {\n\t\t\tyield { kind: 'item_completed', requestId: request.id, result: itemResult };\n\t\t} else {\n\t\t\tyield { error: itemResult.error, kind: 'item_failed', requestId: request.id };\n\t\t}\n\t}\n\n\tyield {\n\t\tkind: 'completed',\n\t\tresult: batchItemsToCoreResult({ diagnostics: batchResult.diagnostics, items: itemResults }),\n\t};\n}\n\nexport function createPortalCore(props: CreatePortalCoreProps): PortalCore {\n\tconst sessionManager = createPortalSessionManager({\n\t\taccessPolicy: props.accessPolicy,\n\t\tcatalogTtlMs: props.catalogTtlMs,\n\t\truntime: props.runtime,\n\t\t...(props.skills !== undefined ? { skills: props.skills } : {}),\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t});\n\tconst createdAgentScopeIds = new Set<string>();\n\tconst approval: PortalApprovalEvaluator =\n\t\tprops.approval ??\n\t\t(() => {\n\t\t\tif (props.approvalTrustBoundary === 'openclaw-before-tool-call-hook') {\n\t\t\t\treturn { kind: 'allow' };\n\t\t\t}\n\t\t\tthrow new Error('MCP Portal approval evaluation is not configured.');\n\t\t});\n\tconst toolRuntime: PortalToolRuntime = {\n\t\tapproval,\n\t\tcallUpstreamTool: props.runtime.callUpstreamTool,\n\t\tgetSession: sessionManager.getSession,\n\t};\n\n\tasync function* callStream(call: PortalCoreStreamCall): AsyncIterable<PortalCoreEvent> {\n\t\ttry {\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tyield { kind: 'started', toolName: call.toolName };\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tif (call.toolName === 'mcp_portal_call') {\n\t\t\t\tyield* callToolStream({\n\t\t\t\t\tinput: call.input,\n\t\t\t\t\tscope: call.scope,\n\t\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\t\ttoolRuntime,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield* scalarToolStream({\n\t\t\t\tinput: call.input,\n\t\t\t\tscope: call.scope,\n\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\tsessionManager,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t\ttoolRuntime,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tyield { error, kind: 'failed' };\n\t\t}\n\t}\n\n\treturn {\n\t\tapproval: {\n\t\t\tevaluateCalls: (calls, scope, approvalToken) => approval(calls, scope, approvalToken),\n\t\t},\n\t\tcallStream,\n\t\tclose: async () => {\n\t\t\tawait Promise.all(\n\t\t\t\t[...createdAgentScopeIds].map((agentScopeId) =>\n\t\t\t\t\tsessionManager.invalidateAgentScope(agentScopeId),\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\tcollectPortalCoreResult,\n\t\tcreateAgentScope: (input) => {\n\t\t\tconst scope = createPortalAgentIdentity(input);\n\t\t\tcreatedAgentScopeIds.add(scope.agentScopeId);\n\t\t\treturn scope;\n\t\t},\n\t\tdescribeTools: (scope) => {\n\t\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\t\tconfig: props.accessPolicy,\n\t\t\t\tidentity: scope,\n\t\t\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t\t\t});\n\t\t\treturn listPortalCoreToolDescriptors(policy.allowedNamespaces);\n\t\t},\n\t\tinvalidateAgentScope: async (agentScopeId) => {\n\t\t\tcreatedAgentScopeIds.delete(agentScopeId);\n\t\t\tawait sessionManager.invalidateAgentScope(agentScopeId);\n\t\t},\n\t\tinvalidateSession: async (scope) => {\n\t\t\tawait sessionManager.invalidateSession(scope);\n\t\t},\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portal-core-BPSvDGvi.js","names":[],"sources":["../src/core/provider-runtime.ts","../src/core/portal-core.ts"],"sourcesContent":["import {\n\tmcpConfigToResolvedProviders,\n\ttype McpConfig,\n\ttype ResolvedMcpProvider,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\n\nimport type { NormalizedUpstreamMcpServer } from '../upstream-mcp-client-runtime.js';\n\nexport interface ResolveUpstreamServersProps {\n\treadonly config: McpConfig;\n\treadonly resolveSecret: (secret: SecretValue) => Promise<string>;\n}\n\nasync function resolveProviderSecretRecord(\n\tsecrets: Readonly<Record<string, SecretValue>>,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<Readonly<Record<string, string>>> {\n\tconst resolvedEntries = await Promise.all(\n\t\tObject.entries(secrets).map(\n\t\t\tasync ([name, secret]) => [name, await resolveSecret(secret)] as const,\n\t\t),\n\t);\n\treturn Object.fromEntries(resolvedEntries);\n}\n\nasync function resolveUpstreamServer(\n\tprovider: ResolvedMcpProvider,\n\tresolveSecret: (secret: SecretValue) => Promise<string>,\n): Promise<NormalizedUpstreamMcpServer> {\n\tif (provider.transport === 'stdio') {\n\t\treturn {\n\t\t\targs: provider.args,\n\t\t\tcommand: provider.command,\n\t\t\t...(provider.cwd === undefined ? {} : { cwd: provider.cwd }),\n\t\t\tenv: await resolveProviderSecretRecord(provider.env, resolveSecret),\n\t\t\tnamespace: provider.namespace,\n\t\t\ttransport: 'stdio',\n\t\t};\n\t}\n\n\treturn {\n\t\theaders: await resolveProviderSecretRecord(provider.headers, resolveSecret),\n\t\tnamespace: provider.namespace,\n\t\ttransport: provider.transport,\n\t\turl: provider.url,\n\t};\n}\n\nexport async function resolveUpstreamServers(\n\tprops: ResolveUpstreamServersProps,\n): Promise<readonly NormalizedUpstreamMcpServer[]> {\n\treturn await Promise.all(\n\t\tmcpConfigToResolvedProviders(props.config).map(async (provider) =>\n\t\t\tresolveUpstreamServer(provider, props.resolveSecret),\n\t\t),\n\t);\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\n\nimport { jsonObjectSchema } from '../json-schema.js';\nimport {\n\tcreatePortalAgentIdentity,\n\tresolvePortalAccessPolicy,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalAgentScopeSource,\n} from '../portal-access-policy.js';\nimport {\n\tcreatePortalSessionManager,\n\ttype PortalSessionManager,\n\ttype PortalSessionRuntime,\n} from '../portal-session.js';\nimport type { SkillGraphInput } from '../tool-graph.js';\nimport {\n\tcreatePortalToolHandlers,\n\tportalToolInputSchemas,\n\ttype PortalApprovalCall,\n\ttype PortalBatchDiagnostic,\n\ttype PortalBatchResult,\n\ttype PortalToolResult,\n\ttype PortalToolRuntime,\n} from './portal-tools.js';\n\nexport type PortalAgentScope = PortalAgentIdentity;\n\nexport type PortalCoreToolName =\n\t| 'mcp_portal_list'\n\t| 'mcp_portal_search'\n\t| 'mcp_portal_describe'\n\t| 'mcp_portal_call';\n\nexport interface PortalAuditEvent {\n\treadonly kind: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n}\n\nexport interface PortalCoreResult {\n\treadonly auditEvents?: readonly PortalAuditEvent[];\n\treadonly content: readonly PortalCoreContentBlock[];\n\treadonly items: readonly PortalCoreItemResult[];\n\treadonly structuredContent?: unknown;\n}\n\nexport type PortalCoreItemResult =\n\t| {\n\t\t\treadonly content: readonly PortalCoreContentBlock[];\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'success';\n\t\t\treadonly structuredContent?: unknown;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly requestId: string;\n\t\t\treadonly status: 'failed';\n\t };\n\nexport interface PortalCoreItemError {\n\treadonly code: string;\n\treadonly message: string;\n\treadonly namespace?: string;\n\treadonly toolName?: string;\n}\n\nexport type PortalCoreContentBlock =\n\t| { readonly text: string; readonly type: 'text' }\n\t| { readonly type: 'json'; readonly value: unknown };\n\nexport type PortalCoreEvent =\n\t| {\n\t\t\treadonly kind: 'started';\n\t\t\treadonly toolName: PortalCoreToolName;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_started';\n\t\t\treadonly namespace?: string;\n\t\t\treadonly requestId: string;\n\t\t\treadonly toolName?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress?: number;\n\t\t\treadonly requestId?: string;\n\t\t\treadonly total?: number;\n\t }\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly content: PortalCoreContentBlock;\n\t\t\treadonly kind: 'partial_content';\n\t\t\treadonly requestId?: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'item_completed';\n\t\t\treadonly requestId: string;\n\t\t\treadonly result: Extract<PortalCoreItemResult, { readonly status: 'success' }>;\n\t }\n\t| {\n\t\t\treadonly error: PortalCoreItemError;\n\t\t\treadonly kind: 'item_failed';\n\t\t\treadonly requestId: string;\n\t }\n\t| {\n\t\t\treadonly kind: 'completed';\n\t\t\treadonly result: PortalCoreResult;\n\t }\n\t| {\n\t\t\treadonly error: unknown;\n\t\t\treadonly kind: 'failed';\n\t };\n\nexport interface PortalCoreStreamCall {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: PortalCoreToolName;\n}\n\nconst maxQueuedPortalCoreEvents = 1_024;\nconst maxPortalCoreEventBytes = 256 * 1_024;\n\nexport interface PortalCoreCollectOptions {\n\treadonly onEvent?: (event: PortalCoreEvent) => Promise<void> | void;\n}\n\nexport interface PortalCoreRuntime extends PortalSessionRuntime {\n\treadonly callUpstreamTool: PortalToolRuntime['callUpstreamTool'];\n}\n\nexport type PortalApprovalEvaluator = NonNullable<PortalToolRuntime['approval']>;\n\ninterface CreatePortalCoreBaseProps {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly runtime: PortalCoreRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport type CreatePortalCoreProps =\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval: PortalApprovalEvaluator;\n\t\t\treadonly approvalTrustBoundary?: never;\n\t })\n\t| (CreatePortalCoreBaseProps & {\n\t\t\treadonly approval?: never;\n\t\t\treadonly approvalTrustBoundary: 'openclaw-before-tool-call-hook';\n\t });\n\nexport interface PortalCore {\n\treadonly approval: {\n\t\treadonly evaluateCalls: (\n\t\t\tcalls: readonly PortalApprovalCall[],\n\t\t\tscope: PortalAgentScope,\n\t\t\tapprovalToken: string | undefined,\n\t\t) => ReturnType<PortalApprovalEvaluator>;\n\t};\n\treadonly callStream: (call: PortalCoreStreamCall) => AsyncIterable<PortalCoreEvent>;\n\treadonly close: () => Promise<void>;\n\treadonly collectPortalCoreResult: typeof collectPortalCoreResult;\n\treadonly createAgentScope: (input: {\n\t\treadonly agentId: string;\n\t\treadonly agentScopeId: string;\n\t\treadonly authSubject?: string;\n\t\treadonly sessionId?: string;\n\t\treadonly sessionKey?: string;\n\t\treadonly source: PortalAgentScopeSource;\n\t}) => PortalAgentScope;\n\treadonly describeTools: (scope: PortalAgentScope) => readonly PortalCoreToolDescriptor[];\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (scope: PortalAgentScope) => Promise<void>;\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalCoreToolDescriptor {\n\treadonly description: string;\n\treadonly inputSchema: Tool['inputSchema'];\n\treadonly name: PortalCoreToolName;\n}\n\nconst portalCallRequestSchema = z\n\t.object({\n\t\targuments: jsonObjectSchema,\n\t\tid: z.string().min(1),\n\t\tnamespace: z.string().min(1),\n\t\ttoolName: z.string().min(1),\n\t})\n\t.strict();\nconst portalCallInputSchema = z\n\t.object({\n\t\tcalls: z.array(portalCallRequestSchema).min(1),\n\t\tportalApprovalToken: z.string().min(1).optional(),\n\t})\n\t.strict();\n\nfunction diagnosticsToAuditEvents(\n\tdiagnostics: readonly PortalBatchDiagnostic[],\n): readonly PortalAuditEvent[] {\n\treturn diagnostics.map((diagnostic) => ({\n\t\tkind: diagnostic.kind,\n\t\tmessage: diagnostic.message,\n\t\t...(diagnostic.namespace !== undefined ? { namespace: diagnostic.namespace } : {}),\n\t}));\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction errorRecordFromUnknown(error: unknown): Record<string, unknown> {\n\treturn isUnknownRecord(error) ? error : {};\n}\n\nfunction messageFromUnknown(error: unknown): string {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tconst record = errorRecordFromUnknown(error);\n\tconst message = record.message;\n\treturn typeof message === 'string' ? message : String(error);\n}\n\nfunction errorFromAbortSignal(signal: AbortSignal): Error {\n\tconst reason: unknown = signal.reason;\n\treturn reason instanceof Error ? reason : new Error('MCP Portal core stream aborted.');\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow errorFromAbortSignal(signal);\n\t}\n}\n\nfunction assertPortalCoreEventSize(event: PortalCoreEvent): void {\n\tconst serialized = JSON.stringify(event);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxPortalCoreEventBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP Portal core event exceeded ${String(maxPortalCoreEventBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction waitForQueuedCoreEvent(props: {\n\treadonly setNotifyQueuedEvent: (notify: (() => void) | undefined) => void;\n\treadonly signal?: AbortSignal;\n}): Promise<void> {\n\tif (props.signal === undefined) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tprops.setNotifyQueuedEvent(resolve);\n\t\t});\n\t}\n\tconst signal = props.signal;\n\treturn new Promise<void>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tsignal.removeEventListener('abort', onAbort);\n\t\t\tprops.setNotifyQueuedEvent(undefined);\n\t\t\tcomplete();\n\t\t};\n\t\tconst onNotify = (): void => {\n\t\t\tsettle(resolve);\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tsettle(() => reject(errorFromAbortSignal(signal)));\n\t\t};\n\t\tprops.setNotifyQueuedEvent(onNotify);\n\t\tsignal.addEventListener('abort', onAbort, { once: true });\n\t\tif (signal.aborted) {\n\t\t\tonAbort();\n\t\t}\n\t});\n}\n\nfunction itemErrorFromPortalResult(result: PortalToolResult): PortalCoreItemError {\n\tif (result.ok) {\n\t\tthrow new Error('Cannot convert successful portal result into an item error.');\n\t}\n\tconst errorRecord = errorRecordFromUnknown(result.error);\n\tconst kind = errorRecord.kind;\n\tconst namespace = errorRecord.namespace;\n\tconst toolName = errorRecord.toolName;\n\n\treturn {\n\t\tcode: typeof kind === 'string' ? kind : 'portal_item_failed',\n\t\tmessage: messageFromUnknown(result.error),\n\t\t...(typeof namespace === 'string' ? { namespace } : {}),\n\t\t...(typeof toolName === 'string' ? { toolName } : {}),\n\t};\n}\n\nfunction itemResultFromPortalToolResult(\n\trequestId: string,\n\tresult: PortalToolResult,\n): PortalCoreItemResult {\n\tif (!result.ok) {\n\t\treturn {\n\t\t\terror: itemErrorFromPortalResult(result),\n\t\t\trequestId,\n\t\t\tstatus: 'failed',\n\t\t};\n\t}\n\n\treturn {\n\t\tcontent: [{ type: 'json', value: result.output }],\n\t\trequestId,\n\t\tstatus: 'success',\n\t\tstructuredContent: result.output,\n\t};\n}\n\nfunction scalarBatchResultToCoreResult(batchResult: PortalBatchResult): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(batchResult.diagnostics),\n\t\tcontent: [{ type: 'json', value: batchResult }],\n\t\titems: [],\n\t\tstructuredContent: batchResult,\n\t};\n}\n\nfunction batchItemsToCoreResult(props: {\n\treadonly diagnostics: readonly PortalBatchDiagnostic[];\n\treadonly items: readonly PortalCoreItemResult[];\n}): PortalCoreResult {\n\treturn {\n\t\tauditEvents: diagnosticsToAuditEvents(props.diagnostics),\n\t\tcontent: [],\n\t\titems: props.items,\n\t};\n}\n\nfunction namespaceDescription(namespaces: readonly string[]): string {\n\treturn namespaces.length === 0\n\t\t? 'No upstream MCP namespaces are authorized for this agent scope.'\n\t\t: `Authorized MCP namespaces for this agent scope: ${namespaces.join(', ')}.`;\n}\n\nexport function listPortalCoreToolDescriptors(\n\tnamespaces: readonly string[] = [],\n): readonly PortalCoreToolDescriptor[] {\n\tconst scopeDescription = namespaceDescription(namespaces);\n\treturn [\n\t\t{\n\t\t\tdescription: `List authorized MCP namespaces and compact tool summaries. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_list,\n\t\t\tname: 'mcp_portal_list',\n\t\t},\n\t\t{\n\t\t\tdescription: `Search the caller scoped MCP Portal index. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_search,\n\t\t\tname: 'mcp_portal_search',\n\t\t},\n\t\t{\n\t\t\tdescription: `Describe exact MCP tool schemas and optional TypeScript/Zod helpers. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_describe,\n\t\t\tname: 'mcp_portal_describe',\n\t\t},\n\t\t{\n\t\t\tdescription: `Validate and call an authorized upstream MCP tool by namespace and toolName. ${scopeDescription}`,\n\t\t\tinputSchema: portalToolInputSchemas.mcp_portal_call,\n\t\t\tname: 'mcp_portal_call',\n\t\t},\n\t];\n}\n\nexport async function collectPortalCoreResult(\n\tevents: AsyncIterable<PortalCoreEvent>,\n\toptions: PortalCoreCollectOptions = {},\n): Promise<PortalCoreResult> {\n\tlet result: PortalCoreResult | undefined;\n\tfor await (const event of events) {\n\t\tawait options.onEvent?.(event);\n\t\tif (event.kind === 'completed') {\n\t\t\tresult = event.result;\n\t\t}\n\t\tif (event.kind === 'failed') {\n\t\t\tthrow event.error;\n\t\t}\n\t}\n\tif (result === undefined) {\n\t\tthrow new Error('MCP Portal core stream ended without a completed event.');\n\t}\n\treturn result;\n}\n\nasync function* scalarToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly sessionManager: PortalSessionManager;\n\treadonly toolName: Exclude<PortalCoreToolName, 'mcp_portal_call'>;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst handlers = createPortalToolHandlers(props.toolRuntime);\n\tconst handler =\n\t\tprops.toolName === 'mcp_portal_list'\n\t\t\t? handlers.list\n\t\t\t: props.toolName === 'mcp_portal_search'\n\t\t\t\t? handlers.search\n\t\t\t\t: handlers.describe;\n\tthrowIfAborted(props.signal);\n\tconst batchResult = await handler({ identity: props.scope, input: props.input });\n\tthrowIfAborted(props.signal);\n\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n}\n\nasync function* callToolStream(props: {\n\treadonly input: unknown;\n\treadonly scope: PortalAgentScope;\n\treadonly signal?: AbortSignal;\n\treadonly toolRuntime: PortalToolRuntime;\n}): AsyncIterable<PortalCoreEvent> {\n\tconst parsedInput = portalCallInputSchema.safeParse(props.input);\n\tconst queuedEvents: PortalCoreEvent[] = [];\n\tlet notifyQueuedEvent: (() => void) | undefined;\n\tlet executionDone = false;\n\tconst pushEvent = (event: PortalCoreEvent): void => {\n\t\tassertPortalCoreEventSize(event);\n\t\tif (queuedEvents.length >= maxQueuedPortalCoreEvents) {\n\t\t\tthrow new Error(`MCP Portal core event queue exceeded ${maxQueuedPortalCoreEvents} events.`);\n\t\t}\n\t\tqueuedEvents.push(event);\n\t\tnotifyQueuedEvent?.();\n\t\tnotifyQueuedEvent = undefined;\n\t};\n\tconst streamingToolRuntime: PortalToolRuntime = {\n\t\t...props.toolRuntime,\n\t\tcallUpstreamTool: async (call) => {\n\t\t\tthrowIfAborted(props.signal);\n\t\t\tpushEvent({\n\t\t\t\tkind: 'item_started',\n\t\t\t\tnamespace: call.namespace,\n\t\t\t\trequestId: call.requestId,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t});\n\t\t\tpushEvent({\n\t\t\t\tkind: 'progress',\n\t\t\t\tmessage: `Calling upstream MCP tool ${call.namespace}.${call.toolName}.`,\n\t\t\t\trequestId: call.requestId,\n\t\t\t});\n\t\t\treturn await props.toolRuntime.callUpstreamTool({\n\t\t\t\t...call,\n\t\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t\t\tonEvent: (event) => {\n\t\t\t\t\tif (event.kind === 'progress') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t...(event.message !== undefined ? { message: event.message } : {}),\n\t\t\t\t\t\t\t...(event.progress !== undefined ? { progress: event.progress } : {}),\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t\t...(event.total !== undefined ? { total: event.total } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (event.kind === 'partial_content') {\n\t\t\t\t\t\tpushEvent({\n\t\t\t\t\t\t\tcontent: event.content,\n\t\t\t\t\t\t\tkind: 'partial_content',\n\t\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tpushEvent({\n\t\t\t\t\t\tkind: 'upstream_notification',\n\t\t\t\t\t\tmethod: event.method,\n\t\t\t\t\t\tparams: event.params,\n\t\t\t\t\t\trequestId: call.requestId,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n\tconst handlers = createPortalToolHandlers(streamingToolRuntime);\n\tif (!parsedInput.success) {\n\t\tconst batchResult = await handlers.call({ identity: props.scope, input: props.input });\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\n\tconst itemResults: PortalCoreItemResult[] = [];\n\tconst batchResultPromise = handlers\n\t\t.call({\n\t\t\tidentity: props.scope,\n\t\t\tinput: props.input,\n\t\t})\n\t\t.finally(() => {\n\t\t\texecutionDone = true;\n\t\t\tnotifyQueuedEvent?.();\n\t\t\tnotifyQueuedEvent = undefined;\n\t\t});\n\tconst hasPendingExecutionEvents = (): boolean => !executionDone || queuedEvents.length > 0;\n\twhile (hasPendingExecutionEvents()) {\n\t\tconst event = queuedEvents.shift();\n\t\tif (event !== undefined) {\n\t\t\tyield event;\n\t\t\tcontinue;\n\t\t}\n\t\tthrowIfAborted(props.signal);\n\t\t// Streaming consumes events as they arrive; there is no parallel work to collect here.\n\t\t// eslint-disable-next-line no-await-in-loop\n\t\tawait waitForQueuedCoreEvent({\n\t\t\tsetNotifyQueuedEvent: (notify) => {\n\t\t\t\tnotifyQueuedEvent = notify;\n\t\t\t},\n\t\t\t...(props.signal !== undefined ? { signal: props.signal } : {}),\n\t\t});\n\t}\n\tconst batchResult = await batchResultPromise;\n\tthrowIfAborted(props.signal);\n\tif (batchResult.errors.length > 0) {\n\t\tyield { kind: 'completed', result: scalarBatchResultToCoreResult(batchResult) };\n\t\treturn;\n\t}\n\tfor (const request of parsedInput.data.calls) {\n\t\tconst portalResult = batchResult.results[request.id];\n\t\tconst itemResult =\n\t\t\tportalResult === undefined\n\t\t\t\t? ({\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcode: 'portal_item_missing',\n\t\t\t\t\t\t\tmessage: `MCP Portal did not return a result for request \"${request.id}\".`,\n\t\t\t\t\t\t\tnamespace: request.namespace,\n\t\t\t\t\t\t\ttoolName: request.toolName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequestId: request.id,\n\t\t\t\t\t\tstatus: 'failed',\n\t\t\t\t\t} satisfies PortalCoreItemResult)\n\t\t\t\t: itemResultFromPortalToolResult(request.id, portalResult);\n\t\titemResults.push(itemResult);\n\t\tif (itemResult.status === 'success') {\n\t\t\tyield { kind: 'item_completed', requestId: request.id, result: itemResult };\n\t\t} else {\n\t\t\tyield { error: itemResult.error, kind: 'item_failed', requestId: request.id };\n\t\t}\n\t}\n\n\tyield {\n\t\tkind: 'completed',\n\t\tresult: batchItemsToCoreResult({ diagnostics: batchResult.diagnostics, items: itemResults }),\n\t};\n}\n\nexport function createPortalCore(props: CreatePortalCoreProps): PortalCore {\n\tconst sessionManager = createPortalSessionManager({\n\t\taccessPolicy: props.accessPolicy,\n\t\tcatalogTtlMs: props.catalogTtlMs,\n\t\truntime: props.runtime,\n\t\t...(props.skills !== undefined ? { skills: props.skills } : {}),\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t});\n\tconst createdAgentScopeIds = new Set<string>();\n\tconst approval: PortalApprovalEvaluator =\n\t\tprops.approval ??\n\t\t(() => {\n\t\t\tif (props.approvalTrustBoundary === 'openclaw-before-tool-call-hook') {\n\t\t\t\treturn { kind: 'allow' };\n\t\t\t}\n\t\t\tthrow new Error('MCP Portal approval evaluation is not configured.');\n\t\t});\n\tconst toolRuntime: PortalToolRuntime = {\n\t\tapproval,\n\t\tcallUpstreamTool: props.runtime.callUpstreamTool,\n\t\tgetSession: sessionManager.getSession,\n\t};\n\n\tasync function* callStream(call: PortalCoreStreamCall): AsyncIterable<PortalCoreEvent> {\n\t\ttry {\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tyield { kind: 'started', toolName: call.toolName };\n\t\t\tthrowIfAborted(call.signal);\n\t\t\tif (call.toolName === 'mcp_portal_call') {\n\t\t\t\tyield* callToolStream({\n\t\t\t\t\tinput: call.input,\n\t\t\t\t\tscope: call.scope,\n\t\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\t\ttoolRuntime,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield* scalarToolStream({\n\t\t\t\tinput: call.input,\n\t\t\t\tscope: call.scope,\n\t\t\t\t...(call.signal !== undefined ? { signal: call.signal } : {}),\n\t\t\t\tsessionManager,\n\t\t\t\ttoolName: call.toolName,\n\t\t\t\ttoolRuntime,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tyield { error, kind: 'failed' };\n\t\t}\n\t}\n\n\treturn {\n\t\tapproval: {\n\t\t\tevaluateCalls: (calls, scope, approvalToken) => approval(calls, scope, approvalToken),\n\t\t},\n\t\tcallStream,\n\t\tclose: async () => {\n\t\t\tawait Promise.all(\n\t\t\t\t[...createdAgentScopeIds].map((agentScopeId) =>\n\t\t\t\t\tsessionManager.invalidateAgentScope(agentScopeId),\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t\tcollectPortalCoreResult,\n\t\tcreateAgentScope: (input) => {\n\t\t\tconst scope = createPortalAgentIdentity(input);\n\t\t\tcreatedAgentScopeIds.add(scope.agentScopeId);\n\t\t\treturn scope;\n\t\t},\n\t\tdescribeTools: (scope) => {\n\t\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\t\tconfig: props.accessPolicy,\n\t\t\t\tidentity: scope,\n\t\t\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t\t\t});\n\t\t\treturn listPortalCoreToolDescriptors(policy.allowedNamespaces);\n\t\t},\n\t\tinvalidateAgentScope: async (agentScopeId) => {\n\t\t\tcreatedAgentScopeIds.delete(agentScopeId);\n\t\t\tawait sessionManager.invalidateAgentScope(agentScopeId);\n\t\t},\n\t\tinvalidateSession: async (scope) => {\n\t\t\tawait sessionManager.invalidateSession(scope);\n\t\t},\n\t\tupstreamNamespaces: props.upstreamNamespaces,\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as createUpstreamMcpClientRuntime } from "./upstream-mcp-client-runtime-
|
|
2
|
-
import { i as resolveUpstreamServers, n as createPortalCore } from "./portal-core-
|
|
1
|
+
import { t as createUpstreamMcpClientRuntime } from "./upstream-mcp-client-runtime-DbPkS6Rk.js";
|
|
2
|
+
import { i as resolveUpstreamServers, n as createPortalCore } from "./portal-core-BPSvDGvi.js";
|
|
3
3
|
import { t as decodePortalMasterKey } from "./agent-bearer-token-DCtpDPCZ.js";
|
|
4
4
|
import { a as createPortalHttpApp, n as createPortalApprovalVerifier, r as createPortalHttpAgentResolver, t as createPortalAgentRuntimeRecords } from "./resolve-agent-identity-DnC_Pmnh.js";
|
|
5
5
|
import { createHmac } from "node:crypto";
|
|
@@ -355,4 +355,4 @@ async function startPortalServer(props) {
|
|
|
355
355
|
//#endregion
|
|
356
356
|
export { handlePortalServerError as a, resolveSecretValue as c, deriveApprovalHmacKeysFromMasterKey as i, buildProfilePolicyMaps as n, parsePortalServerCliArgs as o, createServeSecretResolver as r, startPortalServer as s, applyAgentOverrides as t };
|
|
357
357
|
|
|
358
|
-
//# sourceMappingURL=serve-command-
|
|
358
|
+
//# sourceMappingURL=serve-command-CV1s-Eln.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve-command-D3SlETy_.js","names":["createOnePasswordSecretResolver"],"sources":["../src/bin/secret-value-resolver.ts","../src/cli/serve-command.ts"],"sourcesContent":["import type { SecretValue } from '@agent-vm/config-contracts';\nimport type { SecretRef, SecretResolver } from '@agent-vm/secret-management';\n\nexport interface ResolveSecretValueProps {\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly secretResolver?: SecretResolver;\n}\n\nfunction secretRefFromSecretValue(secret: SecretValue): SecretRef {\n\tif (secret.source === 'environment') {\n\t\treturn { ref: secret.name, source: 'environment' };\n\t}\n\treturn { ref: secret.ref, source: '1password' };\n}\n\nexport async function resolveSecretValue(\n\tsecret: SecretValue,\n\tprops: ResolveSecretValueProps,\n): Promise<string> {\n\tif (secret.source === 'environment') {\n\t\tconst value = props.env[secret.name];\n\t\tif (value === undefined || value.length === 0) {\n\t\t\tthrow new Error(`Missing environment secret ${secret.name}.`);\n\t\t}\n\t\treturn value;\n\t}\n\n\tif (props.secretResolver === undefined) {\n\t\tthrow new Error(\"Secret with source '1password' requires a configured secret resolver.\");\n\t}\n\treturn await props.secretResolver.resolve(secretRefFromSecretValue(secret));\n}\n","import { createHmac } from 'node:crypto';\nimport { join } from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport {\n\tloadMcpConfig,\n\tloadMcpPortalConfig,\n\tresolveMcpPortalProfile,\n\ttype McpPortalAgentConfig,\n\ttype McpPortalConfig,\n\ttype McpPortalExternalAuthConfig,\n\ttype McpPortalProxyConfig,\n\ttype ResolvedMcpPortalProfile,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\nimport {\n\tcreateCompositeSecretResolver,\n\tcreateSecretResolver as createOnePasswordSecretResolver,\n\tresolveServiceAccountToken,\n\ttype SecretResolver,\n\ttype TokenSource,\n} from '@agent-vm/secret-management';\nimport { serve } from '@hono/node-server';\n\nimport { resolveSecretValue } from '../bin/secret-value-resolver.js';\nimport { createPortalCore } from '../core/portal-core.js';\nimport { resolveUpstreamServers } from '../core/provider-runtime.js';\nimport { createPortalHttpApp, type PortalHttpAuditEvent } from '../mcp-proxy/portal-http-server.js';\nimport {\n\tcreatePortalAgentRuntimeRecords,\n\tcreatePortalApprovalVerifier,\n\tcreatePortalHttpAgentResolver,\n\ttype PortalApprovalAuditEvent,\n} from '../mcp-proxy/resolve-agent-identity.js';\nimport type { PortalToolSelector } from '../portal-access-policy.js';\nimport { decodePortalMasterKey } from '../portal-auth/agent-bearer-token.js';\nimport { createUpstreamMcpClientRuntime } from '../upstream-mcp-client-runtime.js';\n\ntype PortalNodeServer = ReturnType<typeof serve>;\ntype PortalServeFunction = typeof serve;\n\nexport type PortalServerLogEvent =\n\t| {\n\t\t\treadonly event: 'server_error';\n\t\t\treadonly level: 'error';\n\t\t\treadonly message: string;\n\t\t\treadonly stack?: string;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly clientAddress: string;\n\t\t\treadonly decision: PortalHttpAuditEvent['decision'];\n\t\t\treadonly event: 'mcp_proxy_auth';\n\t\t\treadonly level: 'info' | 'warn';\n\t\t\treadonly reason?: PortalHttpAuditEvent['reason'];\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly clientAddress: string;\n\t\t\treadonly event: 'mcp_proxy_auth_audit_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly decision: PortalApprovalAuditEvent['decision'];\n\t\t\treadonly event: 'mcp_portal_approval';\n\t\t\treadonly level: 'info' | 'warn';\n\t\t\treadonly reason?: PortalApprovalAuditEvent['reason'];\n\t\t\treadonly timeMs: number;\n\t\t\treadonly verifierReason?: string;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly event: 'mcp_portal_approval_audit_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentScopeId: string;\n\t\t\treadonly event: 'upstream_close_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly namespace?: string;\n\t };\n\nexport interface PortalServerLogger {\n\treadonly log: (event: PortalServerLogEvent) => void;\n}\n\nexport interface PortalServerCliArgs {\n\treadonly agentOverrides: readonly string[];\n\treadonly configDir: string;\n\treadonly port?: number;\n}\n\nexport interface StartPortalServerProps {\n\treadonly args: PortalServerCliArgs;\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly logger?: PortalServerLogger;\n\treadonly resolveSecret?: (secret: SecretValue) => Promise<string>;\n\treadonly serveFn?: PortalServeFunction;\n}\n\nexport interface CreateServeSecretResolverDependencies {\n\treadonly createOnePasswordSecretResolver?: typeof createOnePasswordSecretResolver;\n\treadonly resolveServiceAccountToken?: typeof resolveServiceAccountToken;\n}\n\nfunction requirePortalTokenSourceValue(\n\tenv: Readonly<Record<string, string | undefined>>,\n\tname: string,\n\tsourceType: string,\n): string {\n\tconst value = env[name]?.trim();\n\tif (value === undefined || value.length === 0) {\n\t\tthrow new Error(`${name} is required when AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE=${sourceType}.`);\n\t}\n\treturn value;\n}\n\nfunction readPortalOnePasswordTokenSource(\n\tenv: Readonly<Record<string, string | undefined>>,\n): TokenSource | null {\n\tconst sourceType = env.AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE?.trim();\n\tif (sourceType === undefined || sourceType.length === 0) {\n\t\tconst configuredEnvVar = env.AGENT_VM_MCP_PORTAL_OP_TOKEN_ENV_VAR?.trim();\n\t\tconst envVar =\n\t\t\tconfiguredEnvVar === undefined || configuredEnvVar.length === 0\n\t\t\t\t? 'OP_SERVICE_ACCOUNT_TOKEN'\n\t\t\t\t: configuredEnvVar;\n\t\tconst token = env[envVar]?.trim();\n\t\treturn token === undefined || token.length === 0 ? null : { envVar, type: 'env' };\n\t}\n\n\tif (sourceType === 'env') {\n\t\treturn {\n\t\t\tenvVar: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_ENV_VAR',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\ttype: 'env',\n\t\t};\n\t}\n\tif (sourceType === 'op-cli') {\n\t\treturn {\n\t\t\tref: requirePortalTokenSourceValue(env, 'AGENT_VM_MCP_PORTAL_OP_TOKEN_REF', sourceType),\n\t\t\ttype: 'op-cli',\n\t\t};\n\t}\n\tif (sourceType === 'keychain') {\n\t\treturn {\n\t\t\taccount: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_KEYCHAIN_ACCOUNT',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\tservice: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_KEYCHAIN_SERVICE',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\ttype: 'keychain',\n\t\t};\n\t}\n\n\tthrow new Error(`Unsupported AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE \"${sourceType}\".`);\n}\n\nasync function resolvePortalServiceAccountToken(props: {\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly resolveToken: typeof resolveServiceAccountToken;\n\treadonly tokenSource: TokenSource;\n}): Promise<string> {\n\tif (props.tokenSource.type !== 'env') {\n\t\treturn await props.resolveToken(props.tokenSource);\n\t}\n\tconst envVar = props.tokenSource.envVar ?? 'OP_SERVICE_ACCOUNT_TOKEN';\n\tconst token = props.env[envVar]?.trim();\n\tif (token === undefined || token.length === 0) {\n\t\tthrow new Error(`Environment variable ${envVar} is not set`);\n\t}\n\treturn token;\n}\n\nexport async function createServeSecretResolver(\n\tenv: Readonly<Record<string, string | undefined>>,\n\tdependencies: CreateServeSecretResolverDependencies = {},\n): Promise<SecretResolver> {\n\tconst tokenSource = readPortalOnePasswordTokenSource(env);\n\tconst resolveToken = dependencies.resolveServiceAccountToken ?? resolveServiceAccountToken;\n\tconst createResolver =\n\t\tdependencies.createOnePasswordSecretResolver ?? createOnePasswordSecretResolver;\n\tconst onePasswordResolver =\n\t\ttokenSource === null\n\t\t\t? null\n\t\t\t: await createResolver({\n\t\t\t\t\tserviceAccountToken: await resolvePortalServiceAccountToken({\n\t\t\t\t\t\tenv,\n\t\t\t\t\t\tresolveToken,\n\t\t\t\t\t\ttokenSource,\n\t\t\t\t\t}),\n\t\t\t\t});\n\treturn createCompositeSecretResolver(onePasswordResolver, env);\n}\n\nexport interface ProfilePolicyMaps {\n\treadonly enabledNamespacesByAgent: Readonly<Record<string, readonly string[]>>;\n\treadonly enabledToolsByAgent: Readonly<Record<string, readonly PortalToolSelector[]>>;\n\treadonly hiddenToolsByAgent: Readonly<Record<string, readonly PortalToolSelector[]>>;\n}\n\nfunction parsePort(value: string | undefined): number | undefined {\n\tif (value === undefined) {\n\t\treturn undefined;\n\t}\n\tconst port = Number(value);\n\tif (!Number.isInteger(port) || port < 0 || port > 65_535) {\n\t\tthrow new Error(`Invalid --port value \"${value}\".`);\n\t}\n\treturn port;\n}\n\nexport function parsePortalServerCliArgs(argv: readonly string[]): PortalServerCliArgs {\n\tconst parsed = parseArgs({\n\t\targs: [...argv],\n\t\toptions: {\n\t\t\tagent: { multiple: true, type: 'string' },\n\t\t\t'config-dir': { type: 'string' },\n\t\t\tport: { short: 'p', type: 'string' },\n\t\t},\n\t\tstrict: true,\n\t});\n\tconst configDir = parsed.values['config-dir'];\n\tif (typeof configDir !== 'string' || configDir.length === 0) {\n\t\tthrow new Error('--config-dir <path> is required.');\n\t}\n\tconst rawAgentOverrides = parsed.values.agent;\n\tconst args = {\n\t\tagentOverrides: Array.isArray(rawAgentOverrides) ? rawAgentOverrides : [],\n\t\tconfigDir,\n\t};\n\tconst port = parsePort(parsed.values.port);\n\treturn port === undefined ? args : { ...args, port };\n}\n\nexport function applyAgentOverrides(\n\tagents: Readonly<Record<string, McpPortalAgentConfig>>,\n\toverrides: readonly string[],\n): Readonly<Record<string, McpPortalAgentConfig>> {\n\tconst nextAgents: Record<string, McpPortalAgentConfig> = { ...agents };\n\tfor (const override of overrides) {\n\t\tconst [agentId, profileName, extra] = override.split('=');\n\t\tif (\n\t\t\tagentId === undefined ||\n\t\t\tprofileName === undefined ||\n\t\t\textra !== undefined ||\n\t\t\tagentId.length === 0 ||\n\t\t\tprofileName.length === 0\n\t\t) {\n\t\t\tthrow new Error(`Invalid --agent override \"${override}\". Expected <agentId>=<profile>.`);\n\t\t}\n\t\tconst existingAgent = nextAgents[agentId];\n\t\tif (existingAgent === undefined) {\n\t\t\tthrow new Error(`Cannot override unknown MCP Portal agent \"${agentId}\".`);\n\t\t}\n\t\tnextAgents[agentId] = { ...existingAgent, profile: profileName };\n\t}\n\treturn nextAgents;\n}\n\nexport interface DeferredPort {\n\treadonly promise: Promise<number>;\n\treadonly reject: (error: Error) => void;\n\treadonly resolve: (port: number) => void;\n}\n\nfunction createDeferredPort(): DeferredPort {\n\tlet rejectPort: ((error: Error) => void) | undefined;\n\tlet resolvePort: ((port: number) => void) | undefined;\n\tconst promise = new Promise<number>((resolve, reject) => {\n\t\trejectPort = reject;\n\t\tresolvePort = resolve;\n\t});\n\treturn {\n\t\tpromise,\n\t\treject: (error) => {\n\t\t\tif (rejectPort === undefined) {\n\t\t\t\tthrow new Error('MCP Portal port rejector was not initialized.');\n\t\t\t}\n\t\t\trejectPort(error);\n\t\t},\n\t\tresolve: (port) => {\n\t\t\tif (resolvePort === undefined) {\n\t\t\t\tthrow new Error('MCP Portal port resolver was not initialized.');\n\t\t\t}\n\t\t\tresolvePort(port);\n\t\t},\n\t};\n}\n\nfunction defaultPortalServerLogger(): PortalServerLogger {\n\treturn {\n\t\tlog: (event) => {\n\t\t\tprocess.stderr.write(`${JSON.stringify(event)}\\n`);\n\t\t},\n\t};\n}\n\nexport function handlePortalServerError(props: {\n\treadonly error: Error;\n\treadonly hasListened: boolean;\n\treadonly listeningPort: DeferredPort;\n\treadonly logger: PortalServerLogger;\n}): void {\n\tprops.logger.log({\n\t\tevent: 'server_error',\n\t\tlevel: 'error',\n\t\tmessage: props.error.message,\n\t\t...(props.error.stack === undefined ? {} : { stack: props.error.stack }),\n\t});\n\tif (!props.hasListened) {\n\t\tprops.listeningPort.reject(props.error);\n\t}\n}\n\nfunction closeNodeServer(server: PortalNodeServer): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tserver.close((error) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction selectorsFromNamespaceTools(\n\tnamespaceTools: Readonly<Record<string, readonly string[]>>,\n): readonly PortalToolSelector[] {\n\treturn Object.entries(namespaceTools).flatMap(([namespace, toolNames]) =>\n\t\ttoolNames.map((toolName) => ({ namespace, toolName })),\n\t);\n}\n\nexport function buildProfilePolicyMaps(\n\tportalConfig: McpPortalConfig,\n): ProfilePolicyMaps & { readonly cacheTtlMs: number } {\n\tconst enabledNamespacesByAgent: Record<string, readonly string[]> = {};\n\tconst enabledToolsByAgent: Record<string, readonly PortalToolSelector[]> = {};\n\tconst hiddenToolsByAgent: Record<string, readonly PortalToolSelector[]> = {};\n\tconst profileTtls: number[] = [];\n\n\tfor (const [agentId, agent] of Object.entries(portalConfig.agents)) {\n\t\tconst profile: ResolvedMcpPortalProfile = resolveMcpPortalProfile(portalConfig, agent.profile);\n\t\tenabledNamespacesByAgent[agentId] = profile.enabledNamespaces;\n\t\tenabledToolsByAgent[agentId] = selectorsFromNamespaceTools(profile.enabledToolsByNamespace);\n\t\thiddenToolsByAgent[agentId] = selectorsFromNamespaceTools(profile.hiddenToolsByNamespace);\n\t\tprofileTtls.push(profile.cache.catalogTtlMs);\n\t}\n\n\treturn {\n\t\tcacheTtlMs: profileTtls.length === 0 ? 60_000 : Math.min(...profileTtls),\n\t\tenabledNamespacesByAgent,\n\t\tenabledToolsByAgent,\n\t\thiddenToolsByAgent,\n\t};\n}\n\nfunction withAgentOverrides(\n\tportalConfig: McpPortalConfig,\n\tagentOverrides: readonly string[],\n): McpPortalConfig {\n\treturn {\n\t\t...portalConfig,\n\t\tagents: applyAgentOverrides(portalConfig.agents, agentOverrides),\n\t};\n}\n\nfunction requireProxyConfig(portalConfig: McpPortalConfig): {\n\treadonly externalAuth: McpPortalExternalAuthConfig;\n\treadonly mcpProxy: McpPortalProxyConfig;\n} {\n\tif (portalConfig.externalAuth === undefined || portalConfig.mcpProxy === undefined) {\n\t\tthrow new Error(\n\t\t\t'mcp-proxy startup requires mcp-portal.config.jsonc externalAuth.masterKey and mcpProxy settings.',\n\t\t);\n\t}\n\treturn {\n\t\texternalAuth: portalConfig.externalAuth,\n\t\tmcpProxy: portalConfig.mcpProxy,\n\t};\n}\n\nexport function deriveApprovalHmacKeysFromMasterKey(props: {\n\treadonly agentIds: readonly string[];\n\treadonly masterKey: Buffer;\n}): ReadonlyMap<string, Buffer> {\n\treturn new Map(\n\t\tprops.agentIds.map((agentId) => [\n\t\t\tagentId,\n\t\t\tcreateHmac('sha256', props.masterKey).update(`mcp-portal:approval-agent:${agentId}`).digest(),\n\t\t]),\n\t);\n}\n\nfunction credentialVersionsByAgent(\n\tportalConfig: McpPortalConfig,\n): Readonly<Record<string, number>> {\n\treturn Object.fromEntries(\n\t\tObject.entries(portalConfig.agents).map(([agentId, agent]) => [\n\t\t\tagentId,\n\t\t\tagent.credentialVersion,\n\t\t]),\n\t);\n}\n\nexport async function startPortalServer(\n\tprops: StartPortalServerProps,\n): Promise<{ readonly close: () => Promise<void>; readonly port: number }> {\n\tconst logger = props.logger ?? defaultPortalServerLogger();\n\tconst serveFn = props.serveFn ?? serve;\n\tlet defaultSecretResolverPromise: Promise<SecretResolver> | undefined;\n\tconst getDefaultSecretResolver = (): Promise<SecretResolver> => {\n\t\tdefaultSecretResolverPromise ??= createServeSecretResolver(props.env);\n\t\treturn defaultSecretResolverPromise;\n\t};\n\tconst resolveSecret =\n\t\tprops.resolveSecret ??\n\t\t(async (secret: SecretValue) =>\n\t\t\tresolveSecretValue(secret, {\n\t\t\t\tenv: props.env,\n\t\t\t\tsecretResolver: await getDefaultSecretResolver(),\n\t\t\t}));\n\tconst mcpConfig = await loadMcpConfig(join(props.args.configDir, 'mcp.config.jsonc'));\n\tconst portalConfig = withAgentOverrides(\n\t\tawait loadMcpPortalConfig(join(props.args.configDir, 'mcp-portal.config.jsonc')),\n\t\tprops.args.agentOverrides,\n\t);\n\tconst proxyStartup = requireProxyConfig(portalConfig);\n\tconst masterKey = decodePortalMasterKey(await resolveSecret(proxyStartup.externalAuth.masterKey));\n\tconst hmacKeys = deriveApprovalHmacKeysFromMasterKey({\n\t\tagentIds: Object.keys(portalConfig.agents),\n\t\tmasterKey,\n\t});\n\tconst agentRecords = createPortalAgentRuntimeRecords({ hmacKeys, portalConfig });\n\tconst upstreamServers = await resolveUpstreamServers({ config: mcpConfig, resolveSecret });\n\tconst upstreamRuntime = createUpstreamMcpClientRuntime({\n\t\tadditionalRedactionValues: [masterKey.toString('base64url')],\n\t\tonCloseError: (error, context) => {\n\t\t\tlogger.log({\n\t\t\t\tagentScopeId: context.agentScopeId,\n\t\t\t\tevent: 'upstream_close_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\t...(context.namespace === undefined ? {} : { namespace: context.namespace }),\n\t\t\t});\n\t\t},\n\t\tservers: upstreamServers,\n\t});\n\tconst profilePolicyMaps = buildProfilePolicyMaps(portalConfig);\n\tconst verifyApproval = createPortalApprovalVerifier({\n\t\tauditErrorSink: (error, event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tevent: 'mcp_portal_approval_audit_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tauditSink: (event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tdecision: event.decision,\n\t\t\t\tevent: 'mcp_portal_approval',\n\t\t\t\tlevel: event.decision === 'allow' ? 'info' : 'warn',\n\t\t\t\t...('reason' in event ? { reason: event.reason } : {}),\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t\t...('verifierReason' in event ? { verifierReason: event.verifierReason } : {}),\n\t\t\t});\n\t\t},\n\t\trecords: agentRecords,\n\t});\n\tconst core = createPortalCore({\n\t\taccessPolicy: {\n\t\t\tdefaultPolicy: 'deny-all',\n\t\t\tenabledNamespacesByAgent: profilePolicyMaps.enabledNamespacesByAgent,\n\t\t\tenabledToolsByAgent: profilePolicyMaps.enabledToolsByAgent,\n\t\t\thiddenToolsByAgent: profilePolicyMaps.hiddenToolsByAgent,\n\t\t},\n\t\tapproval: (calls, identity, approvalToken) =>\n\t\t\tverifyApproval(calls, identity.agentId, approvalToken),\n\t\tcatalogTtlMs: profilePolicyMaps.cacheTtlMs,\n\t\truntime: {\n\t\t\t...upstreamRuntime,\n\t\t\tcallUpstreamTool: upstreamRuntime.callTool,\n\t\t},\n\t\tupstreamNamespaces: upstreamServers.map((server) => server.namespace),\n\t});\n\tconst app = createPortalHttpApp({\n\t\tagentBearerAuth: {\n\t\t\tauthorizationHeaderName: proxyStartup.mcpProxy.auth.headerName,\n\t\t\tcredentialVersionsByAgent: credentialVersionsByAgent(portalConfig),\n\t\t\tmasterKey,\n\t\t},\n\t\tauditSink: (event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tclientAddress: event.clientAddress,\n\t\t\t\tdecision: event.decision,\n\t\t\t\tevent: 'mcp_proxy_auth',\n\t\t\t\tlevel: event.decision === 'allow' ? 'info' : 'warn',\n\t\t\t\t...(event.reason === undefined ? {} : { reason: event.reason }),\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tauditErrorSink: (error, event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tclientAddress: event.clientAddress,\n\t\t\t\tevent: 'mcp_proxy_auth_audit_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tcore,\n\t\tonSessionClosed: async (identity) => {\n\t\t\tawait core.invalidateSession(identity);\n\t\t},\n\t\tregisteredAgentIds: Object.keys(portalConfig.agents),\n\t\tresolveAgentIdentity: createPortalHttpAgentResolver(agentRecords),\n\t});\n\tconst listeningPort = createDeferredPort();\n\tlet hasListened = false;\n\tconst server = serveFn(\n\t\t{\n\t\t\tfetch: app.fetch,\n\t\t\thostname: proxyStartup.mcpProxy.server.host,\n\t\t\tport: props.args.port ?? proxyStartup.mcpProxy.server.port,\n\t\t},\n\t\t(info) => {\n\t\t\thasListened = true;\n\t\t\tprocess.stdout.write(`listening port=${String(info.port)}\\n`);\n\t\t\tlisteningPort.resolve(info.port);\n\t\t},\n\t);\n\tserver.on('error', (error: Error) => {\n\t\thandlePortalServerError({ error, hasListened, listeningPort, logger });\n\t});\n\tconst port = await listeningPort.promise;\n\n\treturn {\n\t\tclose: async () => {\n\t\t\tawait app.closePortalSessions();\n\t\t\tawait core.close();\n\t\t\tawait closeNodeServer(server);\n\t\t},\n\t\tport,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serve-command-CV1s-Eln.js","names":["createOnePasswordSecretResolver"],"sources":["../src/bin/secret-value-resolver.ts","../src/cli/serve-command.ts"],"sourcesContent":["import type { SecretValue } from '@agent-vm/config-contracts';\nimport type { SecretRef, SecretResolver } from '@agent-vm/secret-management';\n\nexport interface ResolveSecretValueProps {\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly secretResolver?: SecretResolver;\n}\n\nfunction secretRefFromSecretValue(secret: SecretValue): SecretRef {\n\tif (secret.source === 'environment') {\n\t\treturn { ref: secret.name, source: 'environment' };\n\t}\n\treturn { ref: secret.ref, source: '1password' };\n}\n\nexport async function resolveSecretValue(\n\tsecret: SecretValue,\n\tprops: ResolveSecretValueProps,\n): Promise<string> {\n\tif (secret.source === 'environment') {\n\t\tconst value = props.env[secret.name];\n\t\tif (value === undefined || value.length === 0) {\n\t\t\tthrow new Error(`Missing environment secret ${secret.name}.`);\n\t\t}\n\t\treturn value;\n\t}\n\n\tif (props.secretResolver === undefined) {\n\t\tthrow new Error(\"Secret with source '1password' requires a configured secret resolver.\");\n\t}\n\treturn await props.secretResolver.resolve(secretRefFromSecretValue(secret));\n}\n","import { createHmac } from 'node:crypto';\nimport { join } from 'node:path';\nimport { parseArgs } from 'node:util';\n\nimport {\n\tloadMcpConfig,\n\tloadMcpPortalConfig,\n\tresolveMcpPortalProfile,\n\ttype McpPortalAgentConfig,\n\ttype McpPortalConfig,\n\ttype McpPortalExternalAuthConfig,\n\ttype McpPortalProxyConfig,\n\ttype ResolvedMcpPortalProfile,\n\ttype SecretValue,\n} from '@agent-vm/config-contracts';\nimport {\n\tcreateCompositeSecretResolver,\n\tcreateSecretResolver as createOnePasswordSecretResolver,\n\tresolveServiceAccountToken,\n\ttype SecretResolver,\n\ttype TokenSource,\n} from '@agent-vm/secret-management';\nimport { serve } from '@hono/node-server';\n\nimport { resolveSecretValue } from '../bin/secret-value-resolver.js';\nimport { createPortalCore } from '../core/portal-core.js';\nimport { resolveUpstreamServers } from '../core/provider-runtime.js';\nimport { createPortalHttpApp, type PortalHttpAuditEvent } from '../mcp-proxy/portal-http-server.js';\nimport {\n\tcreatePortalAgentRuntimeRecords,\n\tcreatePortalApprovalVerifier,\n\tcreatePortalHttpAgentResolver,\n\ttype PortalApprovalAuditEvent,\n} from '../mcp-proxy/resolve-agent-identity.js';\nimport type { PortalToolSelector } from '../portal-access-policy.js';\nimport { decodePortalMasterKey } from '../portal-auth/agent-bearer-token.js';\nimport { createUpstreamMcpClientRuntime } from '../upstream-mcp-client-runtime.js';\n\ntype PortalNodeServer = ReturnType<typeof serve>;\ntype PortalServeFunction = typeof serve;\n\nexport type PortalServerLogEvent =\n\t| {\n\t\t\treadonly event: 'server_error';\n\t\t\treadonly level: 'error';\n\t\t\treadonly message: string;\n\t\t\treadonly stack?: string;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly clientAddress: string;\n\t\t\treadonly decision: PortalHttpAuditEvent['decision'];\n\t\t\treadonly event: 'mcp_proxy_auth';\n\t\t\treadonly level: 'info' | 'warn';\n\t\t\treadonly reason?: PortalHttpAuditEvent['reason'];\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly clientAddress: string;\n\t\t\treadonly event: 'mcp_proxy_auth_audit_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly decision: PortalApprovalAuditEvent['decision'];\n\t\t\treadonly event: 'mcp_portal_approval';\n\t\t\treadonly level: 'info' | 'warn';\n\t\t\treadonly reason?: PortalApprovalAuditEvent['reason'];\n\t\t\treadonly timeMs: number;\n\t\t\treadonly verifierReason?: string;\n\t }\n\t| {\n\t\t\treadonly agentId: string;\n\t\t\treadonly event: 'mcp_portal_approval_audit_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly timeMs: number;\n\t }\n\t| {\n\t\t\treadonly agentScopeId: string;\n\t\t\treadonly event: 'upstream_close_error';\n\t\t\treadonly level: 'warn';\n\t\t\treadonly message: string;\n\t\t\treadonly namespace?: string;\n\t };\n\nexport interface PortalServerLogger {\n\treadonly log: (event: PortalServerLogEvent) => void;\n}\n\nexport interface PortalServerCliArgs {\n\treadonly agentOverrides: readonly string[];\n\treadonly configDir: string;\n\treadonly port?: number;\n}\n\nexport interface StartPortalServerProps {\n\treadonly args: PortalServerCliArgs;\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly logger?: PortalServerLogger;\n\treadonly resolveSecret?: (secret: SecretValue) => Promise<string>;\n\treadonly serveFn?: PortalServeFunction;\n}\n\nexport interface CreateServeSecretResolverDependencies {\n\treadonly createOnePasswordSecretResolver?: typeof createOnePasswordSecretResolver;\n\treadonly resolveServiceAccountToken?: typeof resolveServiceAccountToken;\n}\n\nfunction requirePortalTokenSourceValue(\n\tenv: Readonly<Record<string, string | undefined>>,\n\tname: string,\n\tsourceType: string,\n): string {\n\tconst value = env[name]?.trim();\n\tif (value === undefined || value.length === 0) {\n\t\tthrow new Error(`${name} is required when AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE=${sourceType}.`);\n\t}\n\treturn value;\n}\n\nfunction readPortalOnePasswordTokenSource(\n\tenv: Readonly<Record<string, string | undefined>>,\n): TokenSource | null {\n\tconst sourceType = env.AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE?.trim();\n\tif (sourceType === undefined || sourceType.length === 0) {\n\t\tconst configuredEnvVar = env.AGENT_VM_MCP_PORTAL_OP_TOKEN_ENV_VAR?.trim();\n\t\tconst envVar =\n\t\t\tconfiguredEnvVar === undefined || configuredEnvVar.length === 0\n\t\t\t\t? 'OP_SERVICE_ACCOUNT_TOKEN'\n\t\t\t\t: configuredEnvVar;\n\t\tconst token = env[envVar]?.trim();\n\t\treturn token === undefined || token.length === 0 ? null : { envVar, type: 'env' };\n\t}\n\n\tif (sourceType === 'env') {\n\t\treturn {\n\t\t\tenvVar: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_ENV_VAR',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\ttype: 'env',\n\t\t};\n\t}\n\tif (sourceType === 'op-cli') {\n\t\treturn {\n\t\t\tref: requirePortalTokenSourceValue(env, 'AGENT_VM_MCP_PORTAL_OP_TOKEN_REF', sourceType),\n\t\t\ttype: 'op-cli',\n\t\t};\n\t}\n\tif (sourceType === 'keychain') {\n\t\treturn {\n\t\t\taccount: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_KEYCHAIN_ACCOUNT',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\tservice: requirePortalTokenSourceValue(\n\t\t\t\tenv,\n\t\t\t\t'AGENT_VM_MCP_PORTAL_OP_TOKEN_KEYCHAIN_SERVICE',\n\t\t\t\tsourceType,\n\t\t\t),\n\t\t\ttype: 'keychain',\n\t\t};\n\t}\n\n\tthrow new Error(`Unsupported AGENT_VM_MCP_PORTAL_OP_TOKEN_SOURCE \"${sourceType}\".`);\n}\n\nasync function resolvePortalServiceAccountToken(props: {\n\treadonly env: Readonly<Record<string, string | undefined>>;\n\treadonly resolveToken: typeof resolveServiceAccountToken;\n\treadonly tokenSource: TokenSource;\n}): Promise<string> {\n\tif (props.tokenSource.type !== 'env') {\n\t\treturn await props.resolveToken(props.tokenSource);\n\t}\n\tconst envVar = props.tokenSource.envVar ?? 'OP_SERVICE_ACCOUNT_TOKEN';\n\tconst token = props.env[envVar]?.trim();\n\tif (token === undefined || token.length === 0) {\n\t\tthrow new Error(`Environment variable ${envVar} is not set`);\n\t}\n\treturn token;\n}\n\nexport async function createServeSecretResolver(\n\tenv: Readonly<Record<string, string | undefined>>,\n\tdependencies: CreateServeSecretResolverDependencies = {},\n): Promise<SecretResolver> {\n\tconst tokenSource = readPortalOnePasswordTokenSource(env);\n\tconst resolveToken = dependencies.resolveServiceAccountToken ?? resolveServiceAccountToken;\n\tconst createResolver =\n\t\tdependencies.createOnePasswordSecretResolver ?? createOnePasswordSecretResolver;\n\tconst onePasswordResolver =\n\t\ttokenSource === null\n\t\t\t? null\n\t\t\t: await createResolver({\n\t\t\t\t\tserviceAccountToken: await resolvePortalServiceAccountToken({\n\t\t\t\t\t\tenv,\n\t\t\t\t\t\tresolveToken,\n\t\t\t\t\t\ttokenSource,\n\t\t\t\t\t}),\n\t\t\t\t});\n\treturn createCompositeSecretResolver(onePasswordResolver, env);\n}\n\nexport interface ProfilePolicyMaps {\n\treadonly enabledNamespacesByAgent: Readonly<Record<string, readonly string[]>>;\n\treadonly enabledToolsByAgent: Readonly<Record<string, readonly PortalToolSelector[]>>;\n\treadonly hiddenToolsByAgent: Readonly<Record<string, readonly PortalToolSelector[]>>;\n}\n\nfunction parsePort(value: string | undefined): number | undefined {\n\tif (value === undefined) {\n\t\treturn undefined;\n\t}\n\tconst port = Number(value);\n\tif (!Number.isInteger(port) || port < 0 || port > 65_535) {\n\t\tthrow new Error(`Invalid --port value \"${value}\".`);\n\t}\n\treturn port;\n}\n\nexport function parsePortalServerCliArgs(argv: readonly string[]): PortalServerCliArgs {\n\tconst parsed = parseArgs({\n\t\targs: [...argv],\n\t\toptions: {\n\t\t\tagent: { multiple: true, type: 'string' },\n\t\t\t'config-dir': { type: 'string' },\n\t\t\tport: { short: 'p', type: 'string' },\n\t\t},\n\t\tstrict: true,\n\t});\n\tconst configDir = parsed.values['config-dir'];\n\tif (typeof configDir !== 'string' || configDir.length === 0) {\n\t\tthrow new Error('--config-dir <path> is required.');\n\t}\n\tconst rawAgentOverrides = parsed.values.agent;\n\tconst args = {\n\t\tagentOverrides: Array.isArray(rawAgentOverrides) ? rawAgentOverrides : [],\n\t\tconfigDir,\n\t};\n\tconst port = parsePort(parsed.values.port);\n\treturn port === undefined ? args : { ...args, port };\n}\n\nexport function applyAgentOverrides(\n\tagents: Readonly<Record<string, McpPortalAgentConfig>>,\n\toverrides: readonly string[],\n): Readonly<Record<string, McpPortalAgentConfig>> {\n\tconst nextAgents: Record<string, McpPortalAgentConfig> = { ...agents };\n\tfor (const override of overrides) {\n\t\tconst [agentId, profileName, extra] = override.split('=');\n\t\tif (\n\t\t\tagentId === undefined ||\n\t\t\tprofileName === undefined ||\n\t\t\textra !== undefined ||\n\t\t\tagentId.length === 0 ||\n\t\t\tprofileName.length === 0\n\t\t) {\n\t\t\tthrow new Error(`Invalid --agent override \"${override}\". Expected <agentId>=<profile>.`);\n\t\t}\n\t\tconst existingAgent = nextAgents[agentId];\n\t\tif (existingAgent === undefined) {\n\t\t\tthrow new Error(`Cannot override unknown MCP Portal agent \"${agentId}\".`);\n\t\t}\n\t\tnextAgents[agentId] = { ...existingAgent, profile: profileName };\n\t}\n\treturn nextAgents;\n}\n\nexport interface DeferredPort {\n\treadonly promise: Promise<number>;\n\treadonly reject: (error: Error) => void;\n\treadonly resolve: (port: number) => void;\n}\n\nfunction createDeferredPort(): DeferredPort {\n\tlet rejectPort: ((error: Error) => void) | undefined;\n\tlet resolvePort: ((port: number) => void) | undefined;\n\tconst promise = new Promise<number>((resolve, reject) => {\n\t\trejectPort = reject;\n\t\tresolvePort = resolve;\n\t});\n\treturn {\n\t\tpromise,\n\t\treject: (error) => {\n\t\t\tif (rejectPort === undefined) {\n\t\t\t\tthrow new Error('MCP Portal port rejector was not initialized.');\n\t\t\t}\n\t\t\trejectPort(error);\n\t\t},\n\t\tresolve: (port) => {\n\t\t\tif (resolvePort === undefined) {\n\t\t\t\tthrow new Error('MCP Portal port resolver was not initialized.');\n\t\t\t}\n\t\t\tresolvePort(port);\n\t\t},\n\t};\n}\n\nfunction defaultPortalServerLogger(): PortalServerLogger {\n\treturn {\n\t\tlog: (event) => {\n\t\t\tprocess.stderr.write(`${JSON.stringify(event)}\\n`);\n\t\t},\n\t};\n}\n\nexport function handlePortalServerError(props: {\n\treadonly error: Error;\n\treadonly hasListened: boolean;\n\treadonly listeningPort: DeferredPort;\n\treadonly logger: PortalServerLogger;\n}): void {\n\tprops.logger.log({\n\t\tevent: 'server_error',\n\t\tlevel: 'error',\n\t\tmessage: props.error.message,\n\t\t...(props.error.stack === undefined ? {} : { stack: props.error.stack }),\n\t});\n\tif (!props.hasListened) {\n\t\tprops.listeningPort.reject(props.error);\n\t}\n}\n\nfunction closeNodeServer(server: PortalNodeServer): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tserver.close((error) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction selectorsFromNamespaceTools(\n\tnamespaceTools: Readonly<Record<string, readonly string[]>>,\n): readonly PortalToolSelector[] {\n\treturn Object.entries(namespaceTools).flatMap(([namespace, toolNames]) =>\n\t\ttoolNames.map((toolName) => ({ namespace, toolName })),\n\t);\n}\n\nexport function buildProfilePolicyMaps(\n\tportalConfig: McpPortalConfig,\n): ProfilePolicyMaps & { readonly cacheTtlMs: number } {\n\tconst enabledNamespacesByAgent: Record<string, readonly string[]> = {};\n\tconst enabledToolsByAgent: Record<string, readonly PortalToolSelector[]> = {};\n\tconst hiddenToolsByAgent: Record<string, readonly PortalToolSelector[]> = {};\n\tconst profileTtls: number[] = [];\n\n\tfor (const [agentId, agent] of Object.entries(portalConfig.agents)) {\n\t\tconst profile: ResolvedMcpPortalProfile = resolveMcpPortalProfile(portalConfig, agent.profile);\n\t\tenabledNamespacesByAgent[agentId] = profile.enabledNamespaces;\n\t\tenabledToolsByAgent[agentId] = selectorsFromNamespaceTools(profile.enabledToolsByNamespace);\n\t\thiddenToolsByAgent[agentId] = selectorsFromNamespaceTools(profile.hiddenToolsByNamespace);\n\t\tprofileTtls.push(profile.cache.catalogTtlMs);\n\t}\n\n\treturn {\n\t\tcacheTtlMs: profileTtls.length === 0 ? 60_000 : Math.min(...profileTtls),\n\t\tenabledNamespacesByAgent,\n\t\tenabledToolsByAgent,\n\t\thiddenToolsByAgent,\n\t};\n}\n\nfunction withAgentOverrides(\n\tportalConfig: McpPortalConfig,\n\tagentOverrides: readonly string[],\n): McpPortalConfig {\n\treturn {\n\t\t...portalConfig,\n\t\tagents: applyAgentOverrides(portalConfig.agents, agentOverrides),\n\t};\n}\n\nfunction requireProxyConfig(portalConfig: McpPortalConfig): {\n\treadonly externalAuth: McpPortalExternalAuthConfig;\n\treadonly mcpProxy: McpPortalProxyConfig;\n} {\n\tif (portalConfig.externalAuth === undefined || portalConfig.mcpProxy === undefined) {\n\t\tthrow new Error(\n\t\t\t'mcp-proxy startup requires mcp-portal.config.jsonc externalAuth.masterKey and mcpProxy settings.',\n\t\t);\n\t}\n\treturn {\n\t\texternalAuth: portalConfig.externalAuth,\n\t\tmcpProxy: portalConfig.mcpProxy,\n\t};\n}\n\nexport function deriveApprovalHmacKeysFromMasterKey(props: {\n\treadonly agentIds: readonly string[];\n\treadonly masterKey: Buffer;\n}): ReadonlyMap<string, Buffer> {\n\treturn new Map(\n\t\tprops.agentIds.map((agentId) => [\n\t\t\tagentId,\n\t\t\tcreateHmac('sha256', props.masterKey).update(`mcp-portal:approval-agent:${agentId}`).digest(),\n\t\t]),\n\t);\n}\n\nfunction credentialVersionsByAgent(\n\tportalConfig: McpPortalConfig,\n): Readonly<Record<string, number>> {\n\treturn Object.fromEntries(\n\t\tObject.entries(portalConfig.agents).map(([agentId, agent]) => [\n\t\t\tagentId,\n\t\t\tagent.credentialVersion,\n\t\t]),\n\t);\n}\n\nexport async function startPortalServer(\n\tprops: StartPortalServerProps,\n): Promise<{ readonly close: () => Promise<void>; readonly port: number }> {\n\tconst logger = props.logger ?? defaultPortalServerLogger();\n\tconst serveFn = props.serveFn ?? serve;\n\tlet defaultSecretResolverPromise: Promise<SecretResolver> | undefined;\n\tconst getDefaultSecretResolver = (): Promise<SecretResolver> => {\n\t\tdefaultSecretResolverPromise ??= createServeSecretResolver(props.env);\n\t\treturn defaultSecretResolverPromise;\n\t};\n\tconst resolveSecret =\n\t\tprops.resolveSecret ??\n\t\t(async (secret: SecretValue) =>\n\t\t\tresolveSecretValue(secret, {\n\t\t\t\tenv: props.env,\n\t\t\t\tsecretResolver: await getDefaultSecretResolver(),\n\t\t\t}));\n\tconst mcpConfig = await loadMcpConfig(join(props.args.configDir, 'mcp.config.jsonc'));\n\tconst portalConfig = withAgentOverrides(\n\t\tawait loadMcpPortalConfig(join(props.args.configDir, 'mcp-portal.config.jsonc')),\n\t\tprops.args.agentOverrides,\n\t);\n\tconst proxyStartup = requireProxyConfig(portalConfig);\n\tconst masterKey = decodePortalMasterKey(await resolveSecret(proxyStartup.externalAuth.masterKey));\n\tconst hmacKeys = deriveApprovalHmacKeysFromMasterKey({\n\t\tagentIds: Object.keys(portalConfig.agents),\n\t\tmasterKey,\n\t});\n\tconst agentRecords = createPortalAgentRuntimeRecords({ hmacKeys, portalConfig });\n\tconst upstreamServers = await resolveUpstreamServers({ config: mcpConfig, resolveSecret });\n\tconst upstreamRuntime = createUpstreamMcpClientRuntime({\n\t\tadditionalRedactionValues: [masterKey.toString('base64url')],\n\t\tonCloseError: (error, context) => {\n\t\t\tlogger.log({\n\t\t\t\tagentScopeId: context.agentScopeId,\n\t\t\t\tevent: 'upstream_close_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\t...(context.namespace === undefined ? {} : { namespace: context.namespace }),\n\t\t\t});\n\t\t},\n\t\tservers: upstreamServers,\n\t});\n\tconst profilePolicyMaps = buildProfilePolicyMaps(portalConfig);\n\tconst verifyApproval = createPortalApprovalVerifier({\n\t\tauditErrorSink: (error, event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tevent: 'mcp_portal_approval_audit_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tauditSink: (event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tdecision: event.decision,\n\t\t\t\tevent: 'mcp_portal_approval',\n\t\t\t\tlevel: event.decision === 'allow' ? 'info' : 'warn',\n\t\t\t\t...('reason' in event ? { reason: event.reason } : {}),\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t\t...('verifierReason' in event ? { verifierReason: event.verifierReason } : {}),\n\t\t\t});\n\t\t},\n\t\trecords: agentRecords,\n\t});\n\tconst core = createPortalCore({\n\t\taccessPolicy: {\n\t\t\tdefaultPolicy: 'deny-all',\n\t\t\tenabledNamespacesByAgent: profilePolicyMaps.enabledNamespacesByAgent,\n\t\t\tenabledToolsByAgent: profilePolicyMaps.enabledToolsByAgent,\n\t\t\thiddenToolsByAgent: profilePolicyMaps.hiddenToolsByAgent,\n\t\t},\n\t\tapproval: (calls, identity, approvalToken) =>\n\t\t\tverifyApproval(calls, identity.agentId, approvalToken),\n\t\tcatalogTtlMs: profilePolicyMaps.cacheTtlMs,\n\t\truntime: {\n\t\t\t...upstreamRuntime,\n\t\t\tcallUpstreamTool: upstreamRuntime.callTool,\n\t\t},\n\t\tupstreamNamespaces: upstreamServers.map((server) => server.namespace),\n\t});\n\tconst app = createPortalHttpApp({\n\t\tagentBearerAuth: {\n\t\t\tauthorizationHeaderName: proxyStartup.mcpProxy.auth.headerName,\n\t\t\tcredentialVersionsByAgent: credentialVersionsByAgent(portalConfig),\n\t\t\tmasterKey,\n\t\t},\n\t\tauditSink: (event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tclientAddress: event.clientAddress,\n\t\t\t\tdecision: event.decision,\n\t\t\t\tevent: 'mcp_proxy_auth',\n\t\t\t\tlevel: event.decision === 'allow' ? 'info' : 'warn',\n\t\t\t\t...(event.reason === undefined ? {} : { reason: event.reason }),\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tauditErrorSink: (error, event) => {\n\t\t\tlogger.log({\n\t\t\t\tagentId: event.agentId,\n\t\t\t\tclientAddress: event.clientAddress,\n\t\t\t\tevent: 'mcp_proxy_auth_audit_error',\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: error.message,\n\t\t\t\ttimeMs: event.timeMs,\n\t\t\t});\n\t\t},\n\t\tcore,\n\t\tonSessionClosed: async (identity) => {\n\t\t\tawait core.invalidateSession(identity);\n\t\t},\n\t\tregisteredAgentIds: Object.keys(portalConfig.agents),\n\t\tresolveAgentIdentity: createPortalHttpAgentResolver(agentRecords),\n\t});\n\tconst listeningPort = createDeferredPort();\n\tlet hasListened = false;\n\tconst server = serveFn(\n\t\t{\n\t\t\tfetch: app.fetch,\n\t\t\thostname: proxyStartup.mcpProxy.server.host,\n\t\t\tport: props.args.port ?? proxyStartup.mcpProxy.server.port,\n\t\t},\n\t\t(info) => {\n\t\t\thasListened = true;\n\t\t\tprocess.stdout.write(`listening port=${String(info.port)}\\n`);\n\t\t\tlisteningPort.resolve(info.port);\n\t\t},\n\t);\n\tserver.on('error', (error: Error) => {\n\t\thandlePortalServerError({ error, hasListened, listeningPort, logger });\n\t});\n\tconst port = await listeningPort.promise;\n\n\treturn {\n\t\tclose: async () => {\n\t\t\tawait app.closePortalSessions();\n\t\t\tawait core.close();\n\t\t\tawait closeNodeServer(server);\n\t\t},\n\t\tport,\n\t};\n}\n"],"mappings":"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"}
|
package/dist/{upstream-mcp-client-runtime-JlsfTm7_.js → upstream-mcp-client-runtime-DbPkS6Rk.js}
RENAMED
|
@@ -413,6 +413,13 @@ function createPortalSessionManager(options) {
|
|
|
413
413
|
//#region src/upstream-mcp-client-runtime.ts
|
|
414
414
|
const defaultConnectionTimeoutMs = 3e4;
|
|
415
415
|
const defaultMaxResponseBytes = 4 * 1024 * 1024;
|
|
416
|
+
const inheritedStdioRuntimeEnvNames = [
|
|
417
|
+
"NODE_EXTRA_CA_CERTS",
|
|
418
|
+
"NODE_OPTIONS",
|
|
419
|
+
"REQUESTS_CA_BUNDLE",
|
|
420
|
+
"SSL_CERT_FILE",
|
|
421
|
+
"UV_CACHE_DIR"
|
|
422
|
+
];
|
|
416
423
|
function isObjectRecord(value) {
|
|
417
424
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
418
425
|
}
|
|
@@ -442,6 +449,24 @@ function createSdkClient() {
|
|
|
442
449
|
}
|
|
443
450
|
};
|
|
444
451
|
}
|
|
452
|
+
function inheritedStdioRuntimeEnv() {
|
|
453
|
+
const inheritedEnv = {};
|
|
454
|
+
for (const name of inheritedStdioRuntimeEnvNames) {
|
|
455
|
+
const value = process.env[name];
|
|
456
|
+
if (value !== void 0 && value.length > 0) inheritedEnv[name] = value;
|
|
457
|
+
}
|
|
458
|
+
return inheritedEnv;
|
|
459
|
+
}
|
|
460
|
+
function withStdioRuntimeEnv(server) {
|
|
461
|
+
if (server.transport !== "stdio") return server;
|
|
462
|
+
return {
|
|
463
|
+
...server,
|
|
464
|
+
env: {
|
|
465
|
+
...inheritedStdioRuntimeEnv(),
|
|
466
|
+
...server.env
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
}
|
|
445
470
|
function withRemoteHeaders(server) {
|
|
446
471
|
if (!server.headers) return server;
|
|
447
472
|
return {
|
|
@@ -610,7 +635,7 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
610
635
|
const transportKind = attempts[attemptIndex];
|
|
611
636
|
if (transportKind === void 0) throw lastError ?? /* @__PURE__ */ new Error(`Could not connect to upstream MCP namespace "${server.namespace}".`);
|
|
612
637
|
const client = createClient();
|
|
613
|
-
const transport = createTransport(transportKind === "sse" && server.transport !== "stdio" ? withRemoteHeaders(server) : server, transportKind);
|
|
638
|
+
const transport = createTransport(transportKind === "sse" && server.transport !== "stdio" ? withRemoteHeaders(server) : withStdioRuntimeEnv(server), transportKind);
|
|
614
639
|
const timeoutAbort = createRuntimeAbortSignal(void 0);
|
|
615
640
|
try {
|
|
616
641
|
await withTimeout(client.connect(transport, { signal: timeoutAbort.signal }), {
|
|
@@ -757,4 +782,4 @@ function createUpstreamMcpClientRuntime(options) {
|
|
|
757
782
|
//#endregion
|
|
758
783
|
export { createSearchIndex as i, createPortalSessionManager as n, buildToolGraph as r, createUpstreamMcpClientRuntime as t };
|
|
759
784
|
|
|
760
|
-
//# sourceMappingURL=upstream-mcp-client-runtime-
|
|
785
|
+
//# sourceMappingURL=upstream-mcp-client-runtime-DbPkS6Rk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream-mcp-client-runtime-DbPkS6Rk.js","names":[],"sources":["../src/search-index.ts","../src/tool-graph.ts","../src/portal-session.ts","../src/upstream-mcp-client-runtime.ts"],"sourcesContent":["import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject, JsonValue } from './json-schema.js';\nimport type { ToolGraph, ToolRelationship } from './tool-graph.js';\nimport { createToolSummary, type ToolSummary } from './tool-summary.js';\n\nexport interface SearchQuery {\n\treadonly limit: number;\n\treadonly namespaces?: readonly string[];\n\treadonly query?: string;\n}\n\nexport interface SearchResultSet {\n\treadonly results: readonly ToolSearchResult[];\n}\n\nexport interface SearchIndex {\n\treadonly search: (query: SearchQuery) => SearchResultSet;\n}\n\ninterface SearchEntry {\n\treadonly inputFields: readonly string[];\n\treadonly relationshipHints: readonly ToolRelationshipHint[];\n\treadonly searchText: string;\n\treadonly summary: ToolSearchResult;\n}\n\nexport interface ToolRelationshipHint {\n\treadonly field?: string;\n\treadonly reason: string;\n\treadonly sourceToolRef: string;\n\treadonly type: ToolRelationship['type'];\n}\n\nexport interface ToolSearchResult extends ToolSummary {\n\treadonly relationshipHints?: readonly ToolRelationshipHint[];\n\treadonly schemaFieldMatches?: readonly string[];\n}\n\nfunction collectSchemaText(value: JsonValue, parts: string[]): void {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tcollectSchemaText(item, parts);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'object' || value === null) {\n\t\tif (typeof value === 'string') {\n\t\t\tparts.push(value);\n\t\t}\n\t\treturn;\n\t}\n\n\tfor (const [key, childValue] of Object.entries(value)) {\n\t\tparts.push(key);\n\t\tcollectSchemaText(childValue, parts);\n\t}\n}\n\nfunction normalizeSearchText(text: string): string {\n\treturn text.toLowerCase().replace(/[_-]/g, ' ');\n}\n\nfunction buildSearchText(tool: PortalToolRecord): string {\n\tconst parts = [tool.namespace, tool.toolName, tool.title ?? '', tool.description ?? ''];\n\tcollectSchemaText(tool.inputSchema, parts);\n\tif (tool.outputSchema) {\n\t\tcollectSchemaText(tool.outputSchema, parts);\n\t}\n\n\treturn normalizeSearchText(parts.join(' '));\n}\n\nfunction propertiesFromSchema(schema: JsonObject): readonly string[] {\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction createRelationshipHints(\n\ttool: PortalToolRecord,\n\trelationships: readonly ToolRelationship[],\n): readonly ToolRelationshipHint[] {\n\tconst targetToolRef = createToolSummary(tool).toolRef;\n\n\treturn relationships\n\t\t.filter((relationship) => relationship.to.toolRef === targetToolRef)\n\t\t.map((relationship) =>\n\t\t\trelationship.field === undefined\n\t\t\t\t? {\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tfield: relationship.field,\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t},\n\t\t)\n\t\t.toSorted((left, right) => {\n\t\t\tconst typeOrder = left.type.localeCompare(right.type);\n\t\t\tif (typeOrder !== 0) {\n\t\t\t\treturn typeOrder;\n\t\t\t}\n\t\t\treturn left.sourceToolRef.localeCompare(right.sourceToolRef);\n\t\t});\n}\n\nfunction scopedSkillText(toolRef: string, graph?: ToolGraph): string {\n\tif (!graph) {\n\t\treturn '';\n\t}\n\n\treturn graph.skills\n\t\t.filter((skill) => skill.toolRefs.includes(toolRef))\n\t\t.map((skill) => [skill.title, skill.description ?? '', ...skill.tags].join(' '))\n\t\t.join(' ');\n}\n\nfunction scoreEntry(entry: SearchEntry, terms: readonly string[]): number {\n\tlet score = 0;\n\tfor (const term of terms) {\n\t\tif (entry.searchText.includes(term)) {\n\t\t\tscore += 1;\n\t\t}\n\t}\n\n\treturn score;\n}\n\nfunction compareSummaries(left: ToolSummary, right: ToolSummary): number {\n\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\tif (namespaceOrder !== 0) {\n\t\treturn namespaceOrder;\n\t}\n\n\treturn left.toolName.localeCompare(right.toolName);\n}\n\nfunction withRelationshipHints(\n\tsummary: ToolSummary,\n\trelationshipHints: readonly ToolRelationshipHint[],\n): ToolSearchResult {\n\tif (relationshipHints.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\trelationshipHints,\n\t\tsafety: summary.safety,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nfunction withSchemaFieldMatches(\n\tsummary: ToolSearchResult,\n\tschemaFieldMatches: readonly string[],\n): ToolSearchResult {\n\tif (schemaFieldMatches.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\t...(summary.relationshipHints !== undefined\n\t\t\t? { relationshipHints: summary.relationshipHints }\n\t\t\t: {}),\n\t\tsafety: summary.safety,\n\t\tschemaFieldMatches,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nexport function createSearchIndex(\n\ttools: readonly PortalToolRecord[],\n\tgraph?: ToolGraph,\n): SearchIndex {\n\tconst entries = tools\n\t\t.map((tool) => portalToolRecordSchema.parse(tool))\n\t\t.map((tool) => {\n\t\t\tconst summary = createToolSummary(tool);\n\t\t\tconst relationshipHints = createRelationshipHints(tool, graph?.relationships ?? []);\n\t\t\tconst inputFields = propertiesFromSchema(tool.inputSchema);\n\t\t\tconst relationText = relationshipHints\n\t\t\t\t.map((hint) => [hint.field ?? '', hint.reason, hint.sourceToolRef, hint.type].join(' '))\n\t\t\t\t.join(' ');\n\t\t\tconst skillText = scopedSkillText(summary.toolRef, graph);\n\n\t\t\treturn {\n\t\t\t\tinputFields,\n\t\t\t\trelationshipHints,\n\t\t\t\tsearchText: normalizeSearchText([buildSearchText(tool), relationText, skillText].join(' ')),\n\t\t\t\tsummary: withRelationshipHints(summary, relationshipHints),\n\t\t\t};\n\t\t})\n\t\t.toSorted((left, right) => compareSummaries(left.summary, right.summary));\n\n\treturn {\n\t\tsearch(query: SearchQuery): SearchResultSet {\n\t\t\tconst limit = Math.max(0, Math.floor(query.limit));\n\t\t\tconst namespaceFilter = new Set(query.namespaces ?? []);\n\t\t\tconst terms = normalizeSearchText(query.query ?? '')\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.map((term) => term.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst scoredEntries = entries\n\t\t\t\t.filter(\n\t\t\t\t\t(entry) => namespaceFilter.size === 0 || namespaceFilter.has(entry.summary.namespace),\n\t\t\t\t)\n\t\t\t\t.map((entry) => ({ entry, score: terms.length === 0 ? 1 : scoreEntry(entry, terms) }))\n\t\t\t\t.filter(({ score }) => score > 0)\n\t\t\t\t.toSorted((left, right) => {\n\t\t\t\t\tif (right.score !== left.score) {\n\t\t\t\t\t\treturn right.score - left.score;\n\t\t\t\t\t}\n\t\t\t\t\treturn compareSummaries(left.entry.summary, right.entry.summary);\n\t\t\t\t});\n\n\t\t\tconst results = scoredEntries.slice(0, limit).map(({ entry }) => {\n\t\t\t\tconst schemaFieldMatches = entry.inputFields\n\t\t\t\t\t.filter((fieldName) =>\n\t\t\t\t\t\tterms.some((term) => normalizeSearchText(fieldName).includes(term)),\n\t\t\t\t\t)\n\t\t\t\t\t.toSorted();\n\n\t\t\t\treturn withSchemaFieldMatches(entry.summary, schemaFieldMatches);\n\t\t\t});\n\n\t\t\treturn { results };\n\t\t},\n\t};\n}\n","import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject } from './json-schema.js';\nimport { encodeToolRef, type ToolIdentity } from './tool-ref.js';\n\nexport type ToolRelationshipType = 'entity' | 'schema-field' | 'skill';\n\nexport interface ToolRelationshipEndpoint extends ToolIdentity {\n\treadonly toolRef: string;\n}\n\nexport interface ToolRelationship {\n\treadonly field?: string;\n\treadonly from: ToolRelationshipEndpoint;\n\treadonly reason: string;\n\treadonly to: ToolRelationshipEndpoint;\n\treadonly type: ToolRelationshipType;\n}\n\nexport interface SkillGraphInput {\n\treadonly description?: string;\n\treadonly tags?: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ScopedSkillGraphEntry {\n\treadonly description?: string;\n\treadonly tags: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ToolGraphInput {\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface ToolGraph {\n\treadonly relationships: readonly ToolRelationship[];\n\treadonly skills: readonly ScopedSkillGraphEntry[];\n}\n\ninterface GraphTool {\n\treadonly entityNames: readonly string[];\n\treadonly inputFields: readonly string[];\n\treadonly outputFields: readonly string[];\n\treadonly record: PortalToolRecord;\n\treadonly ref: ToolRelationshipEndpoint;\n}\n\nconst genericLinkFields = new Set(['id', 'name', 'title', 'url', 'uri']);\n\nfunction compareCodePoint(left: string, right: string): number {\n\tif (left < right) {\n\t\treturn -1;\n\t}\n\tif (left > right) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nfunction objectPropertiesFromSchema(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction collectEntityNames(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst names: string[] = [];\n\tconst schemaId = schema.$id;\n\tconst title = schema.title;\n\tconst entityName = schema.entityName;\n\tif (typeof schemaId === 'string' && schemaId.length > 0) {\n\t\tnames.push(schemaId);\n\t}\n\tif (typeof title === 'string' && title.length > 0) {\n\t\tnames.push(title);\n\t}\n\tif (typeof entityName === 'string' && entityName.length > 0) {\n\t\tnames.push(entityName);\n\t}\n\n\treturn names.map((name) => name.toLowerCase()).toSorted();\n}\n\nfunction createGraphTool(tool: PortalToolRecord): GraphTool {\n\tconst record = portalToolRecordSchema.parse(tool);\n\tconst toolRef = encodeToolRef({ namespace: record.namespace, toolName: record.toolName });\n\n\treturn {\n\t\tentityNames: [\n\t\t\t...collectEntityNames(record.inputSchema),\n\t\t\t...collectEntityNames(record.outputSchema),\n\t\t].toSorted(),\n\t\tinputFields: objectPropertiesFromSchema(record.inputSchema),\n\t\toutputFields: objectPropertiesFromSchema(record.outputSchema),\n\t\trecord,\n\t\tref: {\n\t\t\tnamespace: record.namespace,\n\t\t\ttoolName: record.toolName,\n\t\t\ttoolRef,\n\t\t},\n\t};\n}\n\nfunction sharesEntity(left: GraphTool, right: GraphTool): boolean {\n\tconst rightEntities = new Set(right.entityNames);\n\treturn left.entityNames.some((entityName) => rightEntities.has(entityName));\n}\n\nfunction shouldLinkField(field: string, fromTool: GraphTool, toTool: GraphTool): boolean {\n\tif (!genericLinkFields.has(field.toLowerCase())) {\n\t\treturn true;\n\t}\n\n\treturn fromTool.record.namespace === toTool.record.namespace && sharesEntity(fromTool, toTool);\n}\n\nfunction createSchemaRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst inputFields = new Set(toTool.inputFields);\n\t\t\tfor (const field of fromTool.outputFields) {\n\t\t\t\tif (!inputFields.has(field) || !shouldLinkField(field, fromTool, toTool)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfield,\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Output field \"${field}\" matches input field \"${field}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'schema-field',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\nfunction createEntityRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef || !sharesEntity(fromTool, toTool)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\trelationships.push({\n\t\t\t\tfrom: fromTool.ref,\n\t\t\t\treason: 'Tools declare a shared schema entity through title, $id, or entityName.',\n\t\t\t\tto: toTool.ref,\n\t\t\t\ttype: 'entity',\n\t\t\t});\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction createSkillEntries(\n\tskills: readonly SkillGraphInput[],\n\tallowedToolRefs: ReadonlySet<string>,\n): readonly ScopedSkillGraphEntry[] {\n\tconst entries: ScopedSkillGraphEntry[] = [];\n\tfor (const skill of skills) {\n\t\tconst scopedToolRefs = skill.toolRefs\n\t\t\t.filter((toolRef) => allowedToolRefs.has(toolRef))\n\t\t\t.toSorted();\n\t\tif (scopedToolRefs.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tentries.push({\n\t\t\t...(skill.description !== undefined ? { description: skill.description } : {}),\n\t\t\ttags: [...(skill.tags ?? [])].toSorted(),\n\t\t\ttitle: skill.title,\n\t\t\ttoolRefs: scopedToolRefs,\n\t\t});\n\t}\n\n\treturn entries.toSorted((left, right) => left.title.localeCompare(right.title));\n}\n\nfunction createSkillRelationships(\n\tskills: readonly ScopedSkillGraphEntry[],\n\ttoolsByRef: ReadonlyMap<string, GraphTool>,\n): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const skill of skills) {\n\t\tfor (const fromToolRef of skill.toolRefs) {\n\t\t\tfor (const toToolRef of skill.toolRefs) {\n\t\t\t\tif (fromToolRef === toToolRef) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst fromTool = toolsByRef.get(fromToolRef);\n\t\t\t\tconst toTool = toolsByRef.get(toToolRef);\n\t\t\t\tif (!fromTool || !toTool) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Both tools are referenced by skill \"${skill.title}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'skill',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction compareRelationships(left: ToolRelationship, right: ToolRelationship): number {\n\tconst typeOrder = compareCodePoint(left.type, right.type);\n\tif (typeOrder !== 0) {\n\t\treturn typeOrder;\n\t}\n\n\tconst targetOrder = compareCodePoint(left.to.toolRef, right.to.toolRef);\n\tif (targetOrder !== 0) {\n\t\treturn targetOrder;\n\t}\n\n\treturn compareCodePoint(left.from.toolRef, right.from.toolRef);\n}\n\nexport function buildToolGraph(input: ToolGraphInput): ToolGraph {\n\tconst tools = input.tools\n\t\t.map((tool) => createGraphTool(tool))\n\t\t.toSorted((left, right) => compareCodePoint(left.ref.toolRef, right.ref.toolRef));\n\tconst allowedToolRefs = new Set(tools.map((tool) => tool.ref.toolRef));\n\tconst skills = createSkillEntries(input.skills ?? [], allowedToolRefs);\n\tconst toolsByRef = new Map(tools.map((tool) => [tool.ref.toolRef, tool]));\n\n\treturn {\n\t\trelationships: [\n\t\t\t...createEntityRelationships(tools),\n\t\t\t...createSchemaRelationships(tools),\n\t\t\t...createSkillRelationships(skills, toolsByRef),\n\t\t].toSorted(compareRelationships),\n\t\tskills,\n\t};\n}\n","import { createHash } from 'node:crypto';\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport {\n\tresolvePortalAccessPolicy,\n\tportalAgentScopeKey,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalToolSelector,\n} from './portal-access-policy.js';\nimport { createSearchIndex, type SearchIndex } from './search-index.js';\nimport { buildToolGraph, type SkillGraphInput, type ToolGraph } from './tool-graph.js';\n\nexport interface PortalCatalogSnapshot {\n\treadonly agentScopeId: string;\n\treadonly discoveryFailures: readonly PortalDiscoveryFailure[];\n\treadonly generatedAt: string;\n\treadonly sourceHash: string;\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface PortalDiscoveryFailure {\n\treadonly message: string;\n\treadonly namespace: string;\n}\n\nexport interface PortalSession {\n\treadonly catalog: PortalCatalogSnapshot;\n\treadonly graph: ToolGraph;\n\treadonly identity: PortalAgentIdentity;\n\treadonly searchIndex: SearchIndex;\n}\n\nexport interface PortalSessionRuntime {\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void> | void;\n\treadonly closeSession?: (scopeKey: string) => Promise<void> | void;\n\treadonly listTools: (call: {\n\t\treadonly agentScopeId: string;\n\t\treadonly namespace: string;\n\t}) => Promise<readonly Tool[]>;\n}\n\nexport interface PortalSessionManagerOptions {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly discoveryFailures?: readonly PortalDiscoveryFailure[];\n\treadonly now?: () => number;\n\treadonly runtime: PortalSessionRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalSessionManager {\n\treadonly getSession: (identity: PortalAgentIdentity) => Promise<PortalSession>;\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (identity: PortalAgentIdentity) => Promise<void>;\n}\n\ninterface CachedPortalSession {\n\treadonly expiresAt: number;\n\treadonly session: PortalSession;\n}\n\nfunction isHiddenTool(tool: PortalToolRecord, hiddenTools: readonly PortalToolSelector[]): boolean {\n\treturn hiddenTools.some(\n\t\t(hiddenTool) =>\n\t\t\thiddenTool.namespace === tool.namespace && hiddenTool.toolName === tool.toolName,\n\t);\n}\n\nfunction isEnabledTool(\n\ttool: PortalToolRecord,\n\tenabledTools: readonly PortalToolSelector[],\n): boolean {\n\tif (enabledTools.length === 0) {\n\t\treturn true;\n\t}\n\treturn enabledTools.some(\n\t\t(enabledTool) =>\n\t\t\tenabledTool.namespace === tool.namespace && enabledTool.toolName === tool.toolName,\n\t);\n}\n\nfunction portalToolFromMcpTool(namespace: string, tool: Tool): PortalToolRecord {\n\treturn portalToolRecordSchema.parse({\n\t\t...(tool.annotations !== undefined ? { annotations: tool.annotations } : {}),\n\t\t...(tool.description !== undefined ? { description: tool.description } : {}),\n\t\tinputSchema: tool.inputSchema,\n\t\tnamespace,\n\t\t...(tool.outputSchema !== undefined ? { outputSchema: tool.outputSchema } : {}),\n\t\t...(tool.title !== undefined ? { title: tool.title } : {}),\n\t\ttoolName: tool.name,\n\t});\n}\n\nfunction createSourceHash(tools: readonly PortalToolRecord[]): string {\n\treturn createHash('sha256').update(JSON.stringify(tools)).digest('hex');\n}\n\nfunction messageFromError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createPortalSessionManager(\n\toptions: PortalSessionManagerOptions,\n): PortalSessionManager {\n\tconst sessions = new Map<string, CachedPortalSession>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst getNow = options.now ?? (() => Date.now());\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn agentScopeGenerations.get(agentScopeId) ?? 0;\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tagentScopeGenerations.set(agentScopeId, generationForAgentScope(agentScopeId) + 1);\n\t}\n\n\tfunction generationForScope(scopeKey: string): number {\n\t\tconst agentScopeId = scopeKey.split('\\n', 1)[0] ?? scopeKey;\n\t\treturn (agentScopeGenerations.get(scopeKey) ?? 0) + generationForAgentScope(agentScopeId);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, generationForScope(scopeKey) + 1);\n\t}\n\n\tasync function buildSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\tconfig: options.accessPolicy,\n\t\t\tidentity,\n\t\t\tupstreamNamespaces: options.upstreamNamespaces,\n\t\t});\n\t\tconst tools: PortalToolRecord[] = [];\n\t\tconst discoveryFailures: PortalDiscoveryFailure[] = [...(options.discoveryFailures ?? [])];\n\t\tconst allowedNamespaces = policy.allowedNamespaces;\n\n\t\tconst namespaceToolGroups = await Promise.allSettled(\n\t\t\tallowedNamespaces.map(async (namespace) => ({\n\t\t\t\tmcpTools: await options.runtime.listTools({\n\t\t\t\t\tagentScopeId: portalAgentScopeKey(identity),\n\t\t\t\t\tnamespace,\n\t\t\t\t}),\n\t\t\t\tnamespace,\n\t\t\t})),\n\t\t);\n\t\tfor (const [index, namespaceToolGroup] of namespaceToolGroups.entries()) {\n\t\t\tif (namespaceToolGroup.status === 'rejected') {\n\t\t\t\tconst namespace = allowedNamespaces[index] ?? 'unknown';\n\t\t\t\tdiscoveryFailures.push({ message: messageFromError(namespaceToolGroup.reason), namespace });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { mcpTools, namespace } = namespaceToolGroup.value;\n\t\t\tfor (const mcpTool of mcpTools) {\n\t\t\t\tconst portalTool = portalToolFromMcpTool(namespace, mcpTool);\n\t\t\t\tif (\n\t\t\t\t\tisEnabledTool(portalTool, policy.enabledTools) &&\n\t\t\t\t\t!isHiddenTool(portalTool, policy.hiddenTools)\n\t\t\t\t) {\n\t\t\t\t\ttools.push(portalTool);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst sortedTools = tools.toSorted((left, right) => {\n\t\t\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\t\t\treturn namespaceOrder === 0 ? left.toolName.localeCompare(right.toolName) : namespaceOrder;\n\t\t});\n\t\tconst graph = buildToolGraph({ skills: options.skills ?? [], tools: sortedTools });\n\t\tconst catalog = {\n\t\t\tagentScopeId: identity.agentScopeId,\n\t\t\tdiscoveryFailures,\n\t\t\tgeneratedAt: new Date(getNow()).toISOString(),\n\t\t\tsourceHash: createSourceHash(sortedTools),\n\t\t\ttools: sortedTools,\n\t\t};\n\n\t\treturn {\n\t\t\tcatalog,\n\t\t\tgraph,\n\t\t\tidentity,\n\t\t\tsearchIndex: createSearchIndex(sortedTools, graph),\n\t\t};\n\t}\n\n\treturn {\n\t\tasync getSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\t\tconst key = portalAgentScopeKey(identity);\n\t\t\tconst now = getNow();\n\t\t\tconst cached = sessions.get(key);\n\t\t\tif (cached && cached.expiresAt > now) {\n\t\t\t\treturn cached.session;\n\t\t\t}\n\n\t\t\tconst generation = generationForScope(key);\n\t\t\tconst session = await buildSession(identity);\n\t\t\tif (\n\t\t\t\tgenerationForScope(key) === generation &&\n\t\t\t\tsession.catalog.discoveryFailures.length === 0\n\t\t\t) {\n\t\t\t\tsessions.set(key, { expiresAt: now + options.catalogTtlMs, session });\n\t\t\t}\n\t\t\treturn session;\n\t\t},\n\t\tasync invalidateAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tfor (const key of sessions.keys()) {\n\t\t\t\tif (key === agentScopeId || key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tsessions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(agentScopeId);\n\t\t},\n\t\tasync invalidateSession(identity: PortalAgentIdentity): Promise<void> {\n\t\t\tconst scopeKey = portalAgentScopeKey(identity);\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tsessions.delete(scopeKey);\n\t\t\tif (options.runtime.closeSession) {\n\t\t\t\tawait options.runtime.closeSession(scopeKey);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(scopeKey);\n\t\t},\n\t};\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n\tSSEClientTransport,\n\ttype SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport {\n\tStreamableHTTPClientTransport,\n\ttype StreamableHTTPClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { normalizeHeaders, type Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { ToolSchema, type Progress, type Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport type { JsonObject } from './json-schema.js';\nimport {\n\tredactThrownError,\n\tredactUpstreamCatalogValue,\n\tredactUpstreamResponse,\n} from './upstream-response-middleware.js';\n\nexport type UpstreamMcpTransportKind = 'auto-http' | 'sse' | 'stdio' | 'streamable-http';\n\ninterface BaseUpstreamMcpServer {\n\treadonly connectionTimeoutMs?: number;\n\treadonly namespace: string;\n\treadonly transport: UpstreamMcpTransportKind;\n}\n\nexport interface RemoteUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly eventSourceInit?: SSEClientTransportOptions['eventSourceInit'];\n\treadonly headers?: Readonly<Record<string, string>>;\n\treadonly requestInit?: RequestInit;\n\treadonly transport: 'auto-http' | 'sse' | 'streamable-http';\n\treadonly url: string;\n}\n\nexport interface StdioUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly args?: readonly string[];\n\treadonly command: string;\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string>>;\n\treadonly transport: 'stdio';\n}\n\nexport type NormalizedUpstreamMcpServer = RemoteUpstreamMcpServer | StdioUpstreamMcpServer;\n\nexport interface ListToolsCall {\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n}\n\nexport interface UpstreamToolCall {\n\treadonly arguments: JsonObject;\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n\treadonly onEvent?: (event: UpstreamToolEvent) => Promise<void> | void;\n\treadonly requestId?: string;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: string;\n}\n\nexport type UpstreamToolEvent =\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress: number;\n\t\t\treadonly total?: number;\n\t }\n\t// Extension event for runtimes that can source request-correlated MCP notifications.\n\t// The stock SDK callTool bridge currently emits real progress via RequestOptions.onprogress.\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t }\n\t// Extension event for runtimes that can source incremental content before the final result.\n\t| {\n\t\t\treadonly content:\n\t\t\t\t| { readonly text: string; readonly type: 'text' }\n\t\t\t\t| { readonly type: 'json'; readonly value: unknown };\n\t\t\treadonly kind: 'partial_content';\n\t };\n\nexport type UpstreamMcpProgress = Progress;\n\nexport interface UpstreamListToolsResult {\n\treadonly nextCursor?: string | undefined;\n\treadonly tools: readonly Tool[];\n}\n\nexport interface UpstreamMcpClientLike {\n\treadonly callTool: (\n\t\tparams: {\n\t\t\treadonly arguments: JsonObject;\n\t\t\treadonly name: string;\n\t\t},\n\t\tresultSchema?: unknown,\n\t\toptions?: {\n\t\t\treadonly onprogress?: (progress: UpstreamMcpProgress) => void;\n\t\t\treadonly signal?: AbortSignal;\n\t\t},\n\t) => Promise<unknown>;\n\treadonly close: () => Promise<void> | void;\n\treadonly connect: (\n\t\ttransport: unknown,\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<void>;\n\treadonly listTools: (\n\t\tparams?: { readonly cursor?: string },\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<UpstreamListToolsResult>;\n}\n\nexport interface UpstreamMcpRuntimeOptions {\n\treadonly additionalRedactionValues?: readonly string[];\n\treadonly createClient?: () => UpstreamMcpClientLike;\n\treadonly createTransport?: (\n\t\tserver: NormalizedUpstreamMcpServer,\n\t\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n\t) => unknown;\n\treadonly maxResponseBytes?: number;\n\treadonly onCloseError?: (error: Error, context: UpstreamMcpCloseErrorContext) => void;\n\treadonly servers: readonly NormalizedUpstreamMcpServer[];\n}\n\nexport interface UpstreamMcpCloseErrorContext {\n\treadonly agentScopeId: string;\n\treadonly namespace?: string;\n}\n\nexport interface UpstreamMcpClientRuntime {\n\treadonly callTool: (call: UpstreamToolCall) => Promise<unknown>;\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly closeSession: (scopeKey: string) => Promise<void>;\n\treadonly listTools: (call: ListToolsCall) => Promise<readonly Tool[]>;\n}\n\ninterface CachedClient {\n\treadonly client: UpstreamMcpClientLike;\n}\n\ninterface PendingClient {\n\treadonly generation: number;\n\treadonly promise: Promise<UpstreamMcpClientLike>;\n}\n\nconst defaultConnectionTimeoutMs = 30_000;\nconst defaultMaxResponseBytes = 4 * 1_024 * 1_024;\nconst inheritedStdioRuntimeEnvNames = [\n\t'NODE_EXTRA_CA_CERTS',\n\t'NODE_OPTIONS',\n\t'REQUESTS_CA_BUNDLE',\n\t'SSL_CERT_FILE',\n\t'UV_CACHE_DIR',\n] as const;\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTransport(value: unknown): value is Transport {\n\treturn (\n\t\tisObjectRecord(value) &&\n\t\ttypeof value.start === 'function' &&\n\t\ttypeof value.send === 'function' &&\n\t\ttypeof value.close === 'function'\n\t);\n}\n\nfunction createSdkClient(): UpstreamMcpClientLike {\n\tconst client = new Client({ name: 'mcp-portal', version: '1.0.0' });\n\treturn {\n\t\tcallTool: async (params, _resultSchema, options) =>\n\t\t\tawait client.callTool(params, undefined, options),\n\t\tclose: async () => {\n\t\t\tawait client.close();\n\t\t},\n\t\tconnect: async (transport, options) => {\n\t\t\tif (!isTransport(transport)) {\n\t\t\t\tthrow new Error('SDK MCP client requires a valid MCP transport.');\n\t\t\t}\n\t\t\tawait client.connect(transport, options);\n\t\t},\n\t\tlistTools: async (params, options) => {\n\t\t\tconst result = await client.listTools(params, options);\n\t\t\treturn {\n\t\t\t\t...(result.nextCursor !== undefined ? { nextCursor: result.nextCursor } : {}),\n\t\t\t\ttools: result.tools,\n\t\t\t};\n\t\t},\n\t};\n}\n\nfunction inheritedStdioRuntimeEnv(): Readonly<Record<string, string>> {\n\tconst inheritedEnv: Record<string, string> = {};\n\tfor (const name of inheritedStdioRuntimeEnvNames) {\n\t\tconst value = process.env[name];\n\t\tif (value !== undefined && value.length > 0) {\n\t\t\tinheritedEnv[name] = value;\n\t\t}\n\t}\n\treturn inheritedEnv;\n}\n\nfunction withStdioRuntimeEnv(server: NormalizedUpstreamMcpServer): NormalizedUpstreamMcpServer {\n\tif (server.transport !== 'stdio') {\n\t\treturn server;\n\t}\n\n\treturn {\n\t\t...server,\n\t\tenv: { ...inheritedStdioRuntimeEnv(), ...server.env },\n\t};\n}\n\nfunction withRemoteHeaders(server: RemoteUpstreamMcpServer): RemoteUpstreamMcpServer {\n\tif (!server.headers) {\n\t\treturn server;\n\t}\n\n\treturn {\n\t\t...server,\n\t\trequestInit: {\n\t\t\t...server.requestInit,\n\t\t\theaders: {\n\t\t\t\t...normalizeHeaders(server.requestInit?.headers),\n\t\t\t\t...server.headers,\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction createSdkTransport(\n\tserver: NormalizedUpstreamMcpServer,\n\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n): unknown {\n\tif (transport === 'stdio') {\n\t\tif (server.transport !== 'stdio') {\n\t\t\tthrow new Error('Stdio transport requires stdio server config.');\n\t\t}\n\n\t\treturn new StdioClientTransport({\n\t\t\t...(server.args ? { args: [...server.args] } : {}),\n\t\t\tcommand: server.command,\n\t\t\t...(server.cwd !== undefined ? { cwd: server.cwd } : {}),\n\t\t\t...(server.env ? { env: { ...server.env } } : {}),\n\t\t});\n\t}\n\n\tif (server.transport === 'stdio') {\n\t\tthrow new Error('Remote transport requires remote server config.');\n\t}\n\n\tconst remoteServer = withRemoteHeaders(server);\n\tif (transport === 'sse') {\n\t\tconst options: SSEClientTransportOptions = {};\n\t\tif (remoteServer.eventSourceInit !== undefined) {\n\t\t\toptions.eventSourceInit = remoteServer.eventSourceInit;\n\t\t}\n\t\tif (remoteServer.requestInit !== undefined) {\n\t\t\toptions.requestInit = remoteServer.requestInit;\n\t\t}\n\t\treturn new SSEClientTransport(new URL(remoteServer.url), options);\n\t}\n\n\tconst options: StreamableHTTPClientTransportOptions = {};\n\tif (remoteServer.requestInit !== undefined) {\n\t\toptions.requestInit = remoteServer.requestInit;\n\t}\n\treturn new StreamableHTTPClientTransport(new URL(remoteServer.url), options);\n}\n\nfunction cacheKey(agentScopeId: string, namespace: string): string {\n\treturn `${agentScopeId}\\n${namespace}`;\n}\n\nfunction rootAgentScopeId(agentScopeId: string): string {\n\treturn agentScopeId.split('\\n', 1)[0] ?? agentScopeId;\n}\n\nfunction transportAttempts(\n\tserver: NormalizedUpstreamMcpServer,\n): readonly Exclude<UpstreamMcpTransportKind, 'auto-http'>[] {\n\tif (server.transport === 'auto-http') {\n\t\treturn ['streamable-http', 'sse'];\n\t}\n\n\treturn [server.transport];\n}\n\nfunction redactionValuesFromServer(server: NormalizedUpstreamMcpServer): readonly string[] {\n\tif (server.transport === 'stdio') {\n\t\treturn Object.values(server.env ?? {}).filter((value) => value.length > 0);\n\t}\n\n\treturn Object.values(server.headers ?? {}).filter((value) => value.length > 0);\n}\n\nfunction timeoutMsForServer(server: NormalizedUpstreamMcpServer): number {\n\treturn server.connectionTimeoutMs ?? defaultConnectionTimeoutMs;\n}\n\nfunction assertUpstreamResponseSize(value: unknown, maxResponseBytes: number): void {\n\tconst serialized = JSON.stringify(value);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxResponseBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP upstream response exceeded ${String(maxResponseBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && error.name === 'AbortError';\n}\n\nfunction isCallerAbortError(error: unknown, signal: AbortSignal | undefined): boolean {\n\treturn signal?.aborted === true && (error === signal.reason || isAbortError(error));\n}\n\nasync function withTimeout<TResult>(\n\tpromise: Promise<TResult>,\n\tprops: {\n\t\treadonly onTimeout?: (error: Error) => void;\n\t\treadonly operation: string;\n\t\treadonly timeoutMs: number;\n\t},\n): Promise<TResult> {\n\tlet timeout: NodeJS.Timeout | undefined;\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tpromise,\n\t\t\tnew Promise<never>((_resolve, reject) => {\n\t\t\t\ttimeout = setTimeout(() => {\n\t\t\t\t\tconst error = new Error(`${props.operation} timed out after ${props.timeoutMs}ms.`);\n\t\t\t\t\tprops.onTimeout?.(error);\n\t\t\t\t\treject(error);\n\t\t\t\t}, props.timeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timeout) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n}\n\nfunction createRuntimeAbortSignal(parentSignal: AbortSignal | undefined): {\n\treadonly abortTimeout: (error: Error) => void;\n\treadonly dispose: () => void;\n\treadonly signal: AbortSignal;\n} {\n\tconst controller = new AbortController();\n\tconst abortFromParent = (): void => {\n\t\tif (!controller.signal.aborted) {\n\t\t\tcontroller.abort(parentSignal?.reason);\n\t\t}\n\t};\n\tif (parentSignal?.aborted) {\n\t\tabortFromParent();\n\t} else {\n\t\tparentSignal?.addEventListener('abort', abortFromParent, { once: true });\n\t}\n\n\treturn {\n\t\tabortTimeout: (error) => {\n\t\t\tif (!controller.signal.aborted) {\n\t\t\t\tcontroller.abort(error);\n\t\t\t}\n\t\t},\n\t\tdispose: () => {\n\t\t\tparentSignal?.removeEventListener('abort', abortFromParent);\n\t\t},\n\t\tsignal: controller.signal,\n\t};\n}\n\nasync function listAllTools(\n\tclient: UpstreamMcpClientLike,\n\tcursor: string | undefined,\n\tcollectedTools: readonly Tool[],\n\ttimeoutAbort: {\n\t\treadonly abortTimeout: (error: Error) => void;\n\t\treadonly signal: AbortSignal;\n\t},\n\ttimeoutMs: number,\n): Promise<readonly Tool[]> {\n\tconst result = await withTimeout(\n\t\tclient.listTools(cursor ? { cursor } : undefined, { signal: timeoutAbort.signal }),\n\t\t{\n\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\toperation: 'MCP listTools',\n\t\t\ttimeoutMs,\n\t\t},\n\t);\n\tconst nextTools = [...collectedTools, ...result.tools];\n\treturn result.nextCursor\n\t\t? listAllTools(client, result.nextCursor, nextTools, timeoutAbort, timeoutMs)\n\t\t: nextTools;\n}\n\nasync function closeClientAfterFailure(client: UpstreamMcpClientLike | null): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch {\n\t\t// Preserve the original upstream failure; close errors are best-effort cleanup.\n\t}\n}\n\nasync function closeClientForTeardown(\n\tclient: UpstreamMcpClientLike | null,\n\tprops: {\n\t\treadonly context: UpstreamMcpCloseErrorContext;\n\t\treadonly onCloseError?:\n\t\t\t| ((error: Error, context: UpstreamMcpCloseErrorContext) => void)\n\t\t\t| undefined;\n\t},\n): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch (error) {\n\t\tprops.onCloseError?.(redactThrownError(error), props.context);\n\t}\n}\n\nfunction closeErrorContextFromCacheKey(cacheKeyValue: string): UpstreamMcpCloseErrorContext {\n\tconst keyParts = cacheKeyValue.split('\\n');\n\tconst namespace = keyParts.length > 1 ? keyParts[keyParts.length - 1] : undefined;\n\tconst agentScopeId =\n\t\tnamespace !== undefined ? keyParts.slice(0, keyParts.length - 1).join('\\n') : cacheKeyValue;\n\treturn {\n\t\tagentScopeId,\n\t\t...(namespace !== undefined ? { namespace } : {}),\n\t};\n}\n\nfunction redactToolCatalog(\n\ttools: readonly Tool[],\n\toptions: { readonly exactValues: readonly string[] },\n): readonly Tool[] {\n\treturn tools.map((tool) => ToolSchema.parse(redactUpstreamCatalogValue(tool, options)));\n}\n\nexport function createUpstreamMcpClientRuntime(\n\toptions: UpstreamMcpRuntimeOptions,\n): UpstreamMcpClientRuntime {\n\tconst serversByNamespace = new Map(options.servers.map((server) => [server.namespace, server]));\n\tconst clients = new Map<string, CachedClient>();\n\tconst pendingClients = new Map<string, PendingClient>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst closedClients = new WeakSet<UpstreamMcpClientLike>();\n\tconst createClient = options.createClient ?? createSdkClient;\n\tconst createTransport = options.createTransport ?? createSdkTransport;\n\tconst maxResponseBytes = options.maxResponseBytes ?? defaultMaxResponseBytes;\n\tconst redactionValues = [\n\t\t...(options.additionalRedactionValues ?? []),\n\t\t...options.servers.flatMap((server) => redactionValuesFromServer(server)),\n\t];\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn (\n\t\t\tagentScopeGenerations.get(agentScopeId) ??\n\t\t\tagentScopeGenerations.get(rootAgentScopeId(agentScopeId)) ??\n\t\t\t0\n\t\t);\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tconst rootAgentScope = rootAgentScopeId(agentScopeId);\n\t\tagentScopeGenerations.set(rootAgentScope, (agentScopeGenerations.get(rootAgentScope) ?? 0) + 1);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, (agentScopeGenerations.get(scopeKey) ?? 0) + 1);\n\t}\n\n\tasync function closeClientAfterFailureOnce(client: UpstreamMcpClientLike | null): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientAfterFailure(client);\n\t}\n\n\tasync function closeClientForTeardownOnce(\n\t\tclient: UpstreamMcpClientLike | null,\n\t\tcontext: UpstreamMcpCloseErrorContext,\n\t): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientForTeardown(client, {\n\t\t\tcontext,\n\t\t\tonCloseError: options.onCloseError,\n\t\t});\n\t}\n\n\tasync function createConnectedClient(\n\t\tserver: NormalizedUpstreamMcpServer,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst attempts = transportAttempts(server);\n\t\tasync function tryAttempt(\n\t\t\tattemptIndex: number,\n\t\t\tlastError: Error | null,\n\t\t): Promise<UpstreamMcpClientLike> {\n\t\t\tconst transportKind = attempts[attemptIndex];\n\t\t\tif (transportKind === undefined) {\n\t\t\t\tthrow (\n\t\t\t\t\tlastError ??\n\t\t\t\t\tnew Error(`Could not connect to upstream MCP namespace \"${server.namespace}\".`)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst client = createClient();\n\t\t\tconst transportServer =\n\t\t\t\ttransportKind === 'sse' && server.transport !== 'stdio'\n\t\t\t\t\t? withRemoteHeaders(server)\n\t\t\t\t\t: withStdioRuntimeEnv(server);\n\t\t\tconst transport = createTransport(transportServer, transportKind);\n\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\ttry {\n\t\t\t\tawait withTimeout(client.connect(transport, { signal: timeoutAbort.signal }), {\n\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\toperation: `MCP ${transportKind} connect for namespace \"${server.namespace}\"`,\n\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t});\n\t\t\t\treturn client;\n\t\t\t} catch (error) {\n\t\t\t\tconst redactedError = redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\treturn tryAttempt(attemptIndex + 1, redactedError);\n\t\t\t} finally {\n\t\t\t\ttimeoutAbort.dispose();\n\t\t\t}\n\t\t}\n\n\t\treturn tryAttempt(0, null);\n\t}\n\n\tasync function getClient(\n\t\tagentScopeId: string,\n\t\tnamespace: string,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst key = cacheKey(agentScopeId, namespace);\n\t\tconst cachedClient = clients.get(key);\n\t\tif (cachedClient) {\n\t\t\treturn cachedClient.client;\n\t\t}\n\t\tconst pendingClient = pendingClients.get(key);\n\t\tconst generation = generationForAgentScope(agentScopeId);\n\t\tif (pendingClient && pendingClient.generation === generation) {\n\t\t\treturn pendingClient.promise;\n\t\t}\n\t\tif (pendingClient) {\n\t\t\tpendingClients.delete(key);\n\t\t\tvoid pendingClient.promise.then(closeClientAfterFailureOnce, () => undefined);\n\t\t}\n\n\t\tconst server = serversByNamespace.get(namespace);\n\t\tif (!server) {\n\t\t\tthrow new Error(`Unknown upstream MCP namespace \"${namespace}\".`);\n\t\t}\n\n\t\tconst pending = createConnectedClient(server);\n\t\tconst pendingRecord = { generation, promise: pending } satisfies PendingClient;\n\t\tpendingClients.set(key, pendingRecord);\n\t\ttry {\n\t\t\tconst client = await pending;\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tclients.set(key, { client });\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tif (clients.get(key)?.client === client) {\n\t\t\t\t\tclients.delete(key);\n\t\t\t\t}\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn client;\n\t\t} finally {\n\t\t\tif (pendingClients.get(key) === pendingRecord) {\n\t\t\t\tpendingClients.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tasync callTool(call: UpstreamToolCall): Promise<unknown> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(call.signal);\n\t\t\t\ttry {\n\t\t\t\t\tconst upstreamResult = await withTimeout(\n\t\t\t\t\t\tclient.callTool({ arguments: call.arguments, name: call.toolName }, undefined, {\n\t\t\t\t\t\t\tonprogress: (progress) => {\n\t\t\t\t\t\t\t\tvoid call.onEvent?.({\n\t\t\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t\t\t...(progress.message !== undefined ? { message: progress.message } : {}),\n\t\t\t\t\t\t\t\t\tprogress: progress.progress,\n\t\t\t\t\t\t\t\t\t...(progress.total !== undefined ? { total: progress.total } : {}),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsignal: timeoutAbort.signal,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\t\t\toperation: `MCP callTool ${call.namespace}.${call.toolName}`,\n\t\t\t\t\t\t\ttimeoutMs: server ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tassertUpstreamResponseSize(upstreamResult, maxResponseBytes);\n\t\t\t\t\treturn redactUpstreamResponse(upstreamResult, { exactValues: redactionValues });\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isCallerAbortError(error, call.signal)) {\n\t\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t}\n\t\t},\n\t\tasync closeAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync closeSession(scopeKey: string): Promise<void> {\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync listTools(call: ListToolsCall): Promise<readonly Tool[]> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\t\ttry {\n\t\t\t\t\treturn redactToolCatalog(\n\t\t\t\t\t\tawait listAllTools(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t\ttimeoutAbort,\n\t\t\t\t\t\t\tserver ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ exactValues: redactionValues },\n\t\t\t\t\t);\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-response-middleware-1MZnAD9C.d.ts","names":[],"sources":["../src/upstream-mcp-client-runtime.ts","../src/upstream-response-middleware.ts"],"mappings":";;;;;KAoBY,wBAAA;AAAA,UAEF,qBAAA;EAAA,SACA,mBAAA;EAAA,SACA,SAAA;EAAA,SACA,SAAA,EAAW,wBAAA;AAAA;AAAA,UAGJ,uBAAA,SAAgC,qBAAA;EAAA,SACvC,eAAA,GAAkB,yBAAA;EAAA,SAClB,OAAA,GAAU,QAAA,CAAS,MAAA;EAAA,SACnB,WAAA,GAAc,WAAA;EAAA,SACd,SAAA;EAAA,SACA,GAAA;AAAA;AAAA,UAGO,sBAAA,SAA+B,qBAAA;EAAA,SACtC,IAAA;EAAA,SACA,OAAA;EAAA,SACA,GAAA;EAAA,SACA,GAAA,GAAM,QAAA,CAAS,MAAA;EAAA,SACf,SAAA;AAAA;AAAA,KAGE,2BAAA,GAA8B,uBAAA,GAA0B,sBAAA;AAAA,UAEnD,aAAA;EAAA,SACP,YAAA;EAAA,SACA,SAAA;AAAA;AAAA,UAGO,gBAAA;EAAA,SACP,SAAA,EAAW,UAAA;EAAA,SACX,YAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA,IAAW,KAAA,EAAO,iBAAA,KAAsB,OAAA;EAAA,SACxC,SAAA;EAAA,SACA,MAAA,GAAS,WAAA;EAAA,SACT,QAAA;AAAA;AAAA,KAGE,iBAAA;EAAA,SAEA,IAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,KAAA;AAAA;EAAA,SAKA,IAAA;EAAA,SACA,MAAA;EAAA,SACA,MAAA;AAAA;EAAA,SAIA,OAAA;IAAA,SACK,IAAA;IAAA,SAAuB,IAAA;EAAA;IAAA,SACvB,IAAA;IAAA,SAAuB,KAAA;EAAA;EAAA,SAC5B,IAAA;AAAA;AAAA,KAGA,mBAAA,GAAsB,QAAA;AAAA,UAEjB,uBAAA;EAAA,SACP,UAAA;EAAA,SACA,KAAA,WAAgB,IAAA;AAAA;AAAA,UAGT,qBAAA;EAAA,SACP,QAAA,GACR,MAAA;IAAA,SACU,SAAA,EAAW,UAAA;IAAA,SACX,IAAA;EAAA,GAEV,YAAA,YACA,OAAA;IAAA,SACU,UAAA,IAAc,QAAA,EAAU,mBAAA;IAAA,SACxB,MAAA,GAAS,WAAA;EAAA,MAEf,OAAA;EAAA,SACI,KAAA,QAAa,OAAA;EAAA,SACb,OAAA,GACR,SAAA,WACA,OAAA;IAAA,SAAqB,MAAA,GAAS,WAAA;EAAA,MAC1B,OAAA;EAAA,SACI,SAAA,GACR,MAAA;IAAA,SAAoB,MAAA;EAAA,GACpB,OAAA;IAAA,SAAqB,MAAA,GAAS,WAAA;EAAA,MAC1B,OAAA,CAAQ,uBAAA;AAAA;AAAA,UAGG,yBAAA;EAAA,SACP,yBAAA;EAAA,SACA,YAAA,SAAqB,qBAAA;EAAA,SACrB,eAAA,IACR,MAAA,EAAQ,2BAAA,EACR,SAAA,EAAW,OAAA,CAAQ,wBAAA;EAAA,SAEX,gBAAA;EAAA,SACA,YAAA,IAAgB,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,4BAAA;EAAA,SACvC,OAAA,WAAkB,2BAAA;AAAA;AAAA,UAGX,4BAAA;EAAA,SACP,YAAA;EAAA,SACA,SAAA;AAAA;AAAA,UAGO,wBAAA;EAAA,SACP,QAAA,GAAW,IAAA,EAAM,gBAAA,KAAqB,OAAA;EAAA,SACtC,eAAA,GAAkB,YAAA,aAAyB,OAAA;EAAA,SAC3C,YAAA,GAAe,QAAA,aAAqB,OAAA;EAAA,SACpC,SAAA,GAAY,IAAA,EAAM,aAAA,KAAkB,OAAA,UAAiB,IAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"upstream-response-middleware-1MZnAD9C.d.ts","names":[],"sources":["../src/upstream-mcp-client-runtime.ts","../src/upstream-response-middleware.ts"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-vm/mcp-portal",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.74",
|
|
4
4
|
"description": "Agent-scoped MCP Portal server and TypeScript helpers for composable upstream MCP tools.",
|
|
5
5
|
"homepage": "https://github.com/ShravanSunder/agent-vm#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
70
|
"hono": "^4.12.18",
|
|
71
71
|
"zod": "^4.4.3",
|
|
72
|
-
"@agent-vm/config-contracts": "0.0.
|
|
73
|
-
"@agent-vm/secret-management": "0.0.
|
|
72
|
+
"@agent-vm/config-contracts": "0.0.74",
|
|
73
|
+
"@agent-vm/secret-management": "0.0.74"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"vitest": "^4.1.5"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-mcp-client-runtime-JlsfTm7_.js","names":[],"sources":["../src/search-index.ts","../src/tool-graph.ts","../src/portal-session.ts","../src/upstream-mcp-client-runtime.ts"],"sourcesContent":["import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject, JsonValue } from './json-schema.js';\nimport type { ToolGraph, ToolRelationship } from './tool-graph.js';\nimport { createToolSummary, type ToolSummary } from './tool-summary.js';\n\nexport interface SearchQuery {\n\treadonly limit: number;\n\treadonly namespaces?: readonly string[];\n\treadonly query?: string;\n}\n\nexport interface SearchResultSet {\n\treadonly results: readonly ToolSearchResult[];\n}\n\nexport interface SearchIndex {\n\treadonly search: (query: SearchQuery) => SearchResultSet;\n}\n\ninterface SearchEntry {\n\treadonly inputFields: readonly string[];\n\treadonly relationshipHints: readonly ToolRelationshipHint[];\n\treadonly searchText: string;\n\treadonly summary: ToolSearchResult;\n}\n\nexport interface ToolRelationshipHint {\n\treadonly field?: string;\n\treadonly reason: string;\n\treadonly sourceToolRef: string;\n\treadonly type: ToolRelationship['type'];\n}\n\nexport interface ToolSearchResult extends ToolSummary {\n\treadonly relationshipHints?: readonly ToolRelationshipHint[];\n\treadonly schemaFieldMatches?: readonly string[];\n}\n\nfunction collectSchemaText(value: JsonValue, parts: string[]): void {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tcollectSchemaText(item, parts);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (typeof value !== 'object' || value === null) {\n\t\tif (typeof value === 'string') {\n\t\t\tparts.push(value);\n\t\t}\n\t\treturn;\n\t}\n\n\tfor (const [key, childValue] of Object.entries(value)) {\n\t\tparts.push(key);\n\t\tcollectSchemaText(childValue, parts);\n\t}\n}\n\nfunction normalizeSearchText(text: string): string {\n\treturn text.toLowerCase().replace(/[_-]/g, ' ');\n}\n\nfunction buildSearchText(tool: PortalToolRecord): string {\n\tconst parts = [tool.namespace, tool.toolName, tool.title ?? '', tool.description ?? ''];\n\tcollectSchemaText(tool.inputSchema, parts);\n\tif (tool.outputSchema) {\n\t\tcollectSchemaText(tool.outputSchema, parts);\n\t}\n\n\treturn normalizeSearchText(parts.join(' '));\n}\n\nfunction propertiesFromSchema(schema: JsonObject): readonly string[] {\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction createRelationshipHints(\n\ttool: PortalToolRecord,\n\trelationships: readonly ToolRelationship[],\n): readonly ToolRelationshipHint[] {\n\tconst targetToolRef = createToolSummary(tool).toolRef;\n\n\treturn relationships\n\t\t.filter((relationship) => relationship.to.toolRef === targetToolRef)\n\t\t.map((relationship) =>\n\t\t\trelationship.field === undefined\n\t\t\t\t? {\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tfield: relationship.field,\n\t\t\t\t\t\treason: relationship.reason,\n\t\t\t\t\t\tsourceToolRef: relationship.from.toolRef,\n\t\t\t\t\t\ttype: relationship.type,\n\t\t\t\t\t},\n\t\t)\n\t\t.toSorted((left, right) => {\n\t\t\tconst typeOrder = left.type.localeCompare(right.type);\n\t\t\tif (typeOrder !== 0) {\n\t\t\t\treturn typeOrder;\n\t\t\t}\n\t\t\treturn left.sourceToolRef.localeCompare(right.sourceToolRef);\n\t\t});\n}\n\nfunction scopedSkillText(toolRef: string, graph?: ToolGraph): string {\n\tif (!graph) {\n\t\treturn '';\n\t}\n\n\treturn graph.skills\n\t\t.filter((skill) => skill.toolRefs.includes(toolRef))\n\t\t.map((skill) => [skill.title, skill.description ?? '', ...skill.tags].join(' '))\n\t\t.join(' ');\n}\n\nfunction scoreEntry(entry: SearchEntry, terms: readonly string[]): number {\n\tlet score = 0;\n\tfor (const term of terms) {\n\t\tif (entry.searchText.includes(term)) {\n\t\t\tscore += 1;\n\t\t}\n\t}\n\n\treturn score;\n}\n\nfunction compareSummaries(left: ToolSummary, right: ToolSummary): number {\n\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\tif (namespaceOrder !== 0) {\n\t\treturn namespaceOrder;\n\t}\n\n\treturn left.toolName.localeCompare(right.toolName);\n}\n\nfunction withRelationshipHints(\n\tsummary: ToolSummary,\n\trelationshipHints: readonly ToolRelationshipHint[],\n): ToolSearchResult {\n\tif (relationshipHints.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\trelationshipHints,\n\t\tsafety: summary.safety,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nfunction withSchemaFieldMatches(\n\tsummary: ToolSearchResult,\n\tschemaFieldMatches: readonly string[],\n): ToolSearchResult {\n\tif (schemaFieldMatches.length === 0) {\n\t\treturn summary;\n\t}\n\n\treturn {\n\t\t...(summary.description !== undefined ? { description: summary.description } : {}),\n\t\tinput: summary.input,\n\t\tnamespace: summary.namespace,\n\t\t...(summary.output !== undefined ? { output: summary.output } : {}),\n\t\t...(summary.relationshipHints !== undefined\n\t\t\t? { relationshipHints: summary.relationshipHints }\n\t\t\t: {}),\n\t\tsafety: summary.safety,\n\t\tschemaFieldMatches,\n\t\t...(summary.title !== undefined ? { title: summary.title } : {}),\n\t\ttoolName: summary.toolName,\n\t\ttoolRef: summary.toolRef,\n\t};\n}\n\nexport function createSearchIndex(\n\ttools: readonly PortalToolRecord[],\n\tgraph?: ToolGraph,\n): SearchIndex {\n\tconst entries = tools\n\t\t.map((tool) => portalToolRecordSchema.parse(tool))\n\t\t.map((tool) => {\n\t\t\tconst summary = createToolSummary(tool);\n\t\t\tconst relationshipHints = createRelationshipHints(tool, graph?.relationships ?? []);\n\t\t\tconst inputFields = propertiesFromSchema(tool.inputSchema);\n\t\t\tconst relationText = relationshipHints\n\t\t\t\t.map((hint) => [hint.field ?? '', hint.reason, hint.sourceToolRef, hint.type].join(' '))\n\t\t\t\t.join(' ');\n\t\t\tconst skillText = scopedSkillText(summary.toolRef, graph);\n\n\t\t\treturn {\n\t\t\t\tinputFields,\n\t\t\t\trelationshipHints,\n\t\t\t\tsearchText: normalizeSearchText([buildSearchText(tool), relationText, skillText].join(' ')),\n\t\t\t\tsummary: withRelationshipHints(summary, relationshipHints),\n\t\t\t};\n\t\t})\n\t\t.toSorted((left, right) => compareSummaries(left.summary, right.summary));\n\n\treturn {\n\t\tsearch(query: SearchQuery): SearchResultSet {\n\t\t\tconst limit = Math.max(0, Math.floor(query.limit));\n\t\t\tconst namespaceFilter = new Set(query.namespaces ?? []);\n\t\t\tconst terms = normalizeSearchText(query.query ?? '')\n\t\t\t\t.split(/\\s+/)\n\t\t\t\t.map((term) => term.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst scoredEntries = entries\n\t\t\t\t.filter(\n\t\t\t\t\t(entry) => namespaceFilter.size === 0 || namespaceFilter.has(entry.summary.namespace),\n\t\t\t\t)\n\t\t\t\t.map((entry) => ({ entry, score: terms.length === 0 ? 1 : scoreEntry(entry, terms) }))\n\t\t\t\t.filter(({ score }) => score > 0)\n\t\t\t\t.toSorted((left, right) => {\n\t\t\t\t\tif (right.score !== left.score) {\n\t\t\t\t\t\treturn right.score - left.score;\n\t\t\t\t\t}\n\t\t\t\t\treturn compareSummaries(left.entry.summary, right.entry.summary);\n\t\t\t\t});\n\n\t\t\tconst results = scoredEntries.slice(0, limit).map(({ entry }) => {\n\t\t\t\tconst schemaFieldMatches = entry.inputFields\n\t\t\t\t\t.filter((fieldName) =>\n\t\t\t\t\t\tterms.some((term) => normalizeSearchText(fieldName).includes(term)),\n\t\t\t\t\t)\n\t\t\t\t\t.toSorted();\n\n\t\t\t\treturn withSchemaFieldMatches(entry.summary, schemaFieldMatches);\n\t\t\t});\n\n\t\t\treturn { results };\n\t\t},\n\t};\n}\n","import { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport type { JsonObject } from './json-schema.js';\nimport { encodeToolRef, type ToolIdentity } from './tool-ref.js';\n\nexport type ToolRelationshipType = 'entity' | 'schema-field' | 'skill';\n\nexport interface ToolRelationshipEndpoint extends ToolIdentity {\n\treadonly toolRef: string;\n}\n\nexport interface ToolRelationship {\n\treadonly field?: string;\n\treadonly from: ToolRelationshipEndpoint;\n\treadonly reason: string;\n\treadonly to: ToolRelationshipEndpoint;\n\treadonly type: ToolRelationshipType;\n}\n\nexport interface SkillGraphInput {\n\treadonly description?: string;\n\treadonly tags?: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ScopedSkillGraphEntry {\n\treadonly description?: string;\n\treadonly tags: readonly string[];\n\treadonly title: string;\n\treadonly toolRefs: readonly string[];\n}\n\nexport interface ToolGraphInput {\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface ToolGraph {\n\treadonly relationships: readonly ToolRelationship[];\n\treadonly skills: readonly ScopedSkillGraphEntry[];\n}\n\ninterface GraphTool {\n\treadonly entityNames: readonly string[];\n\treadonly inputFields: readonly string[];\n\treadonly outputFields: readonly string[];\n\treadonly record: PortalToolRecord;\n\treadonly ref: ToolRelationshipEndpoint;\n}\n\nconst genericLinkFields = new Set(['id', 'name', 'title', 'url', 'uri']);\n\nfunction compareCodePoint(left: string, right: string): number {\n\tif (left < right) {\n\t\treturn -1;\n\t}\n\tif (left > right) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nfunction objectPropertiesFromSchema(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst properties = schema.properties;\n\tif (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {\n\t\treturn [];\n\t}\n\n\treturn Object.keys(properties).toSorted();\n}\n\nfunction collectEntityNames(schema: JsonObject | undefined): readonly string[] {\n\tif (!schema) {\n\t\treturn [];\n\t}\n\n\tconst names: string[] = [];\n\tconst schemaId = schema.$id;\n\tconst title = schema.title;\n\tconst entityName = schema.entityName;\n\tif (typeof schemaId === 'string' && schemaId.length > 0) {\n\t\tnames.push(schemaId);\n\t}\n\tif (typeof title === 'string' && title.length > 0) {\n\t\tnames.push(title);\n\t}\n\tif (typeof entityName === 'string' && entityName.length > 0) {\n\t\tnames.push(entityName);\n\t}\n\n\treturn names.map((name) => name.toLowerCase()).toSorted();\n}\n\nfunction createGraphTool(tool: PortalToolRecord): GraphTool {\n\tconst record = portalToolRecordSchema.parse(tool);\n\tconst toolRef = encodeToolRef({ namespace: record.namespace, toolName: record.toolName });\n\n\treturn {\n\t\tentityNames: [\n\t\t\t...collectEntityNames(record.inputSchema),\n\t\t\t...collectEntityNames(record.outputSchema),\n\t\t].toSorted(),\n\t\tinputFields: objectPropertiesFromSchema(record.inputSchema),\n\t\toutputFields: objectPropertiesFromSchema(record.outputSchema),\n\t\trecord,\n\t\tref: {\n\t\t\tnamespace: record.namespace,\n\t\t\ttoolName: record.toolName,\n\t\t\ttoolRef,\n\t\t},\n\t};\n}\n\nfunction sharesEntity(left: GraphTool, right: GraphTool): boolean {\n\tconst rightEntities = new Set(right.entityNames);\n\treturn left.entityNames.some((entityName) => rightEntities.has(entityName));\n}\n\nfunction shouldLinkField(field: string, fromTool: GraphTool, toTool: GraphTool): boolean {\n\tif (!genericLinkFields.has(field.toLowerCase())) {\n\t\treturn true;\n\t}\n\n\treturn fromTool.record.namespace === toTool.record.namespace && sharesEntity(fromTool, toTool);\n}\n\nfunction createSchemaRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst inputFields = new Set(toTool.inputFields);\n\t\t\tfor (const field of fromTool.outputFields) {\n\t\t\t\tif (!inputFields.has(field) || !shouldLinkField(field, fromTool, toTool)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfield,\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Output field \"${field}\" matches input field \"${field}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'schema-field',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn relationships;\n}\n\nfunction createEntityRelationships(tools: readonly GraphTool[]): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const fromTool of tools) {\n\t\tfor (const toTool of tools) {\n\t\t\tif (fromTool.ref.toolRef === toTool.ref.toolRef || !sharesEntity(fromTool, toTool)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\trelationships.push({\n\t\t\t\tfrom: fromTool.ref,\n\t\t\t\treason: 'Tools declare a shared schema entity through title, $id, or entityName.',\n\t\t\t\tto: toTool.ref,\n\t\t\t\ttype: 'entity',\n\t\t\t});\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction createSkillEntries(\n\tskills: readonly SkillGraphInput[],\n\tallowedToolRefs: ReadonlySet<string>,\n): readonly ScopedSkillGraphEntry[] {\n\tconst entries: ScopedSkillGraphEntry[] = [];\n\tfor (const skill of skills) {\n\t\tconst scopedToolRefs = skill.toolRefs\n\t\t\t.filter((toolRef) => allowedToolRefs.has(toolRef))\n\t\t\t.toSorted();\n\t\tif (scopedToolRefs.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tentries.push({\n\t\t\t...(skill.description !== undefined ? { description: skill.description } : {}),\n\t\t\ttags: [...(skill.tags ?? [])].toSorted(),\n\t\t\ttitle: skill.title,\n\t\t\ttoolRefs: scopedToolRefs,\n\t\t});\n\t}\n\n\treturn entries.toSorted((left, right) => left.title.localeCompare(right.title));\n}\n\nfunction createSkillRelationships(\n\tskills: readonly ScopedSkillGraphEntry[],\n\ttoolsByRef: ReadonlyMap<string, GraphTool>,\n): readonly ToolRelationship[] {\n\tconst relationships: ToolRelationship[] = [];\n\tfor (const skill of skills) {\n\t\tfor (const fromToolRef of skill.toolRefs) {\n\t\t\tfor (const toToolRef of skill.toolRefs) {\n\t\t\t\tif (fromToolRef === toToolRef) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst fromTool = toolsByRef.get(fromToolRef);\n\t\t\t\tconst toTool = toolsByRef.get(toToolRef);\n\t\t\t\tif (!fromTool || !toTool) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\trelationships.push({\n\t\t\t\t\tfrom: fromTool.ref,\n\t\t\t\t\treason: `Both tools are referenced by skill \"${skill.title}\".`,\n\t\t\t\t\tto: toTool.ref,\n\t\t\t\t\ttype: 'skill',\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn relationships;\n}\n\nfunction compareRelationships(left: ToolRelationship, right: ToolRelationship): number {\n\tconst typeOrder = compareCodePoint(left.type, right.type);\n\tif (typeOrder !== 0) {\n\t\treturn typeOrder;\n\t}\n\n\tconst targetOrder = compareCodePoint(left.to.toolRef, right.to.toolRef);\n\tif (targetOrder !== 0) {\n\t\treturn targetOrder;\n\t}\n\n\treturn compareCodePoint(left.from.toolRef, right.from.toolRef);\n}\n\nexport function buildToolGraph(input: ToolGraphInput): ToolGraph {\n\tconst tools = input.tools\n\t\t.map((tool) => createGraphTool(tool))\n\t\t.toSorted((left, right) => compareCodePoint(left.ref.toolRef, right.ref.toolRef));\n\tconst allowedToolRefs = new Set(tools.map((tool) => tool.ref.toolRef));\n\tconst skills = createSkillEntries(input.skills ?? [], allowedToolRefs);\n\tconst toolsByRef = new Map(tools.map((tool) => [tool.ref.toolRef, tool]));\n\n\treturn {\n\t\trelationships: [\n\t\t\t...createEntityRelationships(tools),\n\t\t\t...createSchemaRelationships(tools),\n\t\t\t...createSkillRelationships(skills, toolsByRef),\n\t\t].toSorted(compareRelationships),\n\t\tskills,\n\t};\n}\n","import { createHash } from 'node:crypto';\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport { portalToolRecordSchema, type PortalToolRecord } from './catalog-types.js';\nimport {\n\tresolvePortalAccessPolicy,\n\tportalAgentScopeKey,\n\ttype PortalAccessPolicyConfig,\n\ttype PortalAgentIdentity,\n\ttype PortalToolSelector,\n} from './portal-access-policy.js';\nimport { createSearchIndex, type SearchIndex } from './search-index.js';\nimport { buildToolGraph, type SkillGraphInput, type ToolGraph } from './tool-graph.js';\n\nexport interface PortalCatalogSnapshot {\n\treadonly agentScopeId: string;\n\treadonly discoveryFailures: readonly PortalDiscoveryFailure[];\n\treadonly generatedAt: string;\n\treadonly sourceHash: string;\n\treadonly tools: readonly PortalToolRecord[];\n}\n\nexport interface PortalDiscoveryFailure {\n\treadonly message: string;\n\treadonly namespace: string;\n}\n\nexport interface PortalSession {\n\treadonly catalog: PortalCatalogSnapshot;\n\treadonly graph: ToolGraph;\n\treadonly identity: PortalAgentIdentity;\n\treadonly searchIndex: SearchIndex;\n}\n\nexport interface PortalSessionRuntime {\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void> | void;\n\treadonly closeSession?: (scopeKey: string) => Promise<void> | void;\n\treadonly listTools: (call: {\n\t\treadonly agentScopeId: string;\n\t\treadonly namespace: string;\n\t}) => Promise<readonly Tool[]>;\n}\n\nexport interface PortalSessionManagerOptions {\n\treadonly accessPolicy: PortalAccessPolicyConfig;\n\treadonly catalogTtlMs: number;\n\treadonly discoveryFailures?: readonly PortalDiscoveryFailure[];\n\treadonly now?: () => number;\n\treadonly runtime: PortalSessionRuntime;\n\treadonly skills?: readonly SkillGraphInput[];\n\treadonly upstreamNamespaces: readonly string[];\n}\n\nexport interface PortalSessionManager {\n\treadonly getSession: (identity: PortalAgentIdentity) => Promise<PortalSession>;\n\treadonly invalidateAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly invalidateSession: (identity: PortalAgentIdentity) => Promise<void>;\n}\n\ninterface CachedPortalSession {\n\treadonly expiresAt: number;\n\treadonly session: PortalSession;\n}\n\nfunction isHiddenTool(tool: PortalToolRecord, hiddenTools: readonly PortalToolSelector[]): boolean {\n\treturn hiddenTools.some(\n\t\t(hiddenTool) =>\n\t\t\thiddenTool.namespace === tool.namespace && hiddenTool.toolName === tool.toolName,\n\t);\n}\n\nfunction isEnabledTool(\n\ttool: PortalToolRecord,\n\tenabledTools: readonly PortalToolSelector[],\n): boolean {\n\tif (enabledTools.length === 0) {\n\t\treturn true;\n\t}\n\treturn enabledTools.some(\n\t\t(enabledTool) =>\n\t\t\tenabledTool.namespace === tool.namespace && enabledTool.toolName === tool.toolName,\n\t);\n}\n\nfunction portalToolFromMcpTool(namespace: string, tool: Tool): PortalToolRecord {\n\treturn portalToolRecordSchema.parse({\n\t\t...(tool.annotations !== undefined ? { annotations: tool.annotations } : {}),\n\t\t...(tool.description !== undefined ? { description: tool.description } : {}),\n\t\tinputSchema: tool.inputSchema,\n\t\tnamespace,\n\t\t...(tool.outputSchema !== undefined ? { outputSchema: tool.outputSchema } : {}),\n\t\t...(tool.title !== undefined ? { title: tool.title } : {}),\n\t\ttoolName: tool.name,\n\t});\n}\n\nfunction createSourceHash(tools: readonly PortalToolRecord[]): string {\n\treturn createHash('sha256').update(JSON.stringify(tools)).digest('hex');\n}\n\nfunction messageFromError(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function createPortalSessionManager(\n\toptions: PortalSessionManagerOptions,\n): PortalSessionManager {\n\tconst sessions = new Map<string, CachedPortalSession>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst getNow = options.now ?? (() => Date.now());\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn agentScopeGenerations.get(agentScopeId) ?? 0;\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tagentScopeGenerations.set(agentScopeId, generationForAgentScope(agentScopeId) + 1);\n\t}\n\n\tfunction generationForScope(scopeKey: string): number {\n\t\tconst agentScopeId = scopeKey.split('\\n', 1)[0] ?? scopeKey;\n\t\treturn (agentScopeGenerations.get(scopeKey) ?? 0) + generationForAgentScope(agentScopeId);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, generationForScope(scopeKey) + 1);\n\t}\n\n\tasync function buildSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\tconst policy = resolvePortalAccessPolicy({\n\t\t\tconfig: options.accessPolicy,\n\t\t\tidentity,\n\t\t\tupstreamNamespaces: options.upstreamNamespaces,\n\t\t});\n\t\tconst tools: PortalToolRecord[] = [];\n\t\tconst discoveryFailures: PortalDiscoveryFailure[] = [...(options.discoveryFailures ?? [])];\n\t\tconst allowedNamespaces = policy.allowedNamespaces;\n\n\t\tconst namespaceToolGroups = await Promise.allSettled(\n\t\t\tallowedNamespaces.map(async (namespace) => ({\n\t\t\t\tmcpTools: await options.runtime.listTools({\n\t\t\t\t\tagentScopeId: portalAgentScopeKey(identity),\n\t\t\t\t\tnamespace,\n\t\t\t\t}),\n\t\t\t\tnamespace,\n\t\t\t})),\n\t\t);\n\t\tfor (const [index, namespaceToolGroup] of namespaceToolGroups.entries()) {\n\t\t\tif (namespaceToolGroup.status === 'rejected') {\n\t\t\t\tconst namespace = allowedNamespaces[index] ?? 'unknown';\n\t\t\t\tdiscoveryFailures.push({ message: messageFromError(namespaceToolGroup.reason), namespace });\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { mcpTools, namespace } = namespaceToolGroup.value;\n\t\t\tfor (const mcpTool of mcpTools) {\n\t\t\t\tconst portalTool = portalToolFromMcpTool(namespace, mcpTool);\n\t\t\t\tif (\n\t\t\t\t\tisEnabledTool(portalTool, policy.enabledTools) &&\n\t\t\t\t\t!isHiddenTool(portalTool, policy.hiddenTools)\n\t\t\t\t) {\n\t\t\t\t\ttools.push(portalTool);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst sortedTools = tools.toSorted((left, right) => {\n\t\t\tconst namespaceOrder = left.namespace.localeCompare(right.namespace);\n\t\t\treturn namespaceOrder === 0 ? left.toolName.localeCompare(right.toolName) : namespaceOrder;\n\t\t});\n\t\tconst graph = buildToolGraph({ skills: options.skills ?? [], tools: sortedTools });\n\t\tconst catalog = {\n\t\t\tagentScopeId: identity.agentScopeId,\n\t\t\tdiscoveryFailures,\n\t\t\tgeneratedAt: new Date(getNow()).toISOString(),\n\t\t\tsourceHash: createSourceHash(sortedTools),\n\t\t\ttools: sortedTools,\n\t\t};\n\n\t\treturn {\n\t\t\tcatalog,\n\t\t\tgraph,\n\t\t\tidentity,\n\t\t\tsearchIndex: createSearchIndex(sortedTools, graph),\n\t\t};\n\t}\n\n\treturn {\n\t\tasync getSession(identity: PortalAgentIdentity): Promise<PortalSession> {\n\t\t\tconst key = portalAgentScopeKey(identity);\n\t\t\tconst now = getNow();\n\t\t\tconst cached = sessions.get(key);\n\t\t\tif (cached && cached.expiresAt > now) {\n\t\t\t\treturn cached.session;\n\t\t\t}\n\n\t\t\tconst generation = generationForScope(key);\n\t\t\tconst session = await buildSession(identity);\n\t\t\tif (\n\t\t\t\tgenerationForScope(key) === generation &&\n\t\t\t\tsession.catalog.discoveryFailures.length === 0\n\t\t\t) {\n\t\t\t\tsessions.set(key, { expiresAt: now + options.catalogTtlMs, session });\n\t\t\t}\n\t\t\treturn session;\n\t\t},\n\t\tasync invalidateAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tfor (const key of sessions.keys()) {\n\t\t\t\tif (key === agentScopeId || key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tsessions.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(agentScopeId);\n\t\t},\n\t\tasync invalidateSession(identity: PortalAgentIdentity): Promise<void> {\n\t\t\tconst scopeKey = portalAgentScopeKey(identity);\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tsessions.delete(scopeKey);\n\t\t\tif (options.runtime.closeSession) {\n\t\t\t\tawait options.runtime.closeSession(scopeKey);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait options.runtime.closeAgentScope(scopeKey);\n\t\t},\n\t};\n}\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport {\n\tSSEClientTransport,\n\ttype SSEClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport {\n\tStreamableHTTPClientTransport,\n\ttype StreamableHTTPClientTransportOptions,\n} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { normalizeHeaders, type Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { ToolSchema, type Progress, type Tool } from '@modelcontextprotocol/sdk/types.js';\n\nimport type { JsonObject } from './json-schema.js';\nimport {\n\tredactThrownError,\n\tredactUpstreamCatalogValue,\n\tredactUpstreamResponse,\n} from './upstream-response-middleware.js';\n\nexport type UpstreamMcpTransportKind = 'auto-http' | 'sse' | 'stdio' | 'streamable-http';\n\ninterface BaseUpstreamMcpServer {\n\treadonly connectionTimeoutMs?: number;\n\treadonly namespace: string;\n\treadonly transport: UpstreamMcpTransportKind;\n}\n\nexport interface RemoteUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly eventSourceInit?: SSEClientTransportOptions['eventSourceInit'];\n\treadonly headers?: Readonly<Record<string, string>>;\n\treadonly requestInit?: RequestInit;\n\treadonly transport: 'auto-http' | 'sse' | 'streamable-http';\n\treadonly url: string;\n}\n\nexport interface StdioUpstreamMcpServer extends BaseUpstreamMcpServer {\n\treadonly args?: readonly string[];\n\treadonly command: string;\n\treadonly cwd?: string;\n\treadonly env?: Readonly<Record<string, string>>;\n\treadonly transport: 'stdio';\n}\n\nexport type NormalizedUpstreamMcpServer = RemoteUpstreamMcpServer | StdioUpstreamMcpServer;\n\nexport interface ListToolsCall {\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n}\n\nexport interface UpstreamToolCall {\n\treadonly arguments: JsonObject;\n\treadonly agentScopeId: string;\n\treadonly namespace: string;\n\treadonly onEvent?: (event: UpstreamToolEvent) => Promise<void> | void;\n\treadonly requestId?: string;\n\treadonly signal?: AbortSignal;\n\treadonly toolName: string;\n}\n\nexport type UpstreamToolEvent =\n\t| {\n\t\t\treadonly kind: 'progress';\n\t\t\treadonly message?: string;\n\t\t\treadonly progress: number;\n\t\t\treadonly total?: number;\n\t }\n\t// Extension event for runtimes that can source request-correlated MCP notifications.\n\t// The stock SDK callTool bridge currently emits real progress via RequestOptions.onprogress.\n\t| {\n\t\t\treadonly kind: 'upstream_notification';\n\t\t\treadonly method: string;\n\t\t\treadonly params: unknown;\n\t }\n\t// Extension event for runtimes that can source incremental content before the final result.\n\t| {\n\t\t\treadonly content:\n\t\t\t\t| { readonly text: string; readonly type: 'text' }\n\t\t\t\t| { readonly type: 'json'; readonly value: unknown };\n\t\t\treadonly kind: 'partial_content';\n\t };\n\nexport type UpstreamMcpProgress = Progress;\n\nexport interface UpstreamListToolsResult {\n\treadonly nextCursor?: string | undefined;\n\treadonly tools: readonly Tool[];\n}\n\nexport interface UpstreamMcpClientLike {\n\treadonly callTool: (\n\t\tparams: {\n\t\t\treadonly arguments: JsonObject;\n\t\t\treadonly name: string;\n\t\t},\n\t\tresultSchema?: unknown,\n\t\toptions?: {\n\t\t\treadonly onprogress?: (progress: UpstreamMcpProgress) => void;\n\t\t\treadonly signal?: AbortSignal;\n\t\t},\n\t) => Promise<unknown>;\n\treadonly close: () => Promise<void> | void;\n\treadonly connect: (\n\t\ttransport: unknown,\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<void>;\n\treadonly listTools: (\n\t\tparams?: { readonly cursor?: string },\n\t\toptions?: { readonly signal?: AbortSignal },\n\t) => Promise<UpstreamListToolsResult>;\n}\n\nexport interface UpstreamMcpRuntimeOptions {\n\treadonly additionalRedactionValues?: readonly string[];\n\treadonly createClient?: () => UpstreamMcpClientLike;\n\treadonly createTransport?: (\n\t\tserver: NormalizedUpstreamMcpServer,\n\t\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n\t) => unknown;\n\treadonly maxResponseBytes?: number;\n\treadonly onCloseError?: (error: Error, context: UpstreamMcpCloseErrorContext) => void;\n\treadonly servers: readonly NormalizedUpstreamMcpServer[];\n}\n\nexport interface UpstreamMcpCloseErrorContext {\n\treadonly agentScopeId: string;\n\treadonly namespace?: string;\n}\n\nexport interface UpstreamMcpClientRuntime {\n\treadonly callTool: (call: UpstreamToolCall) => Promise<unknown>;\n\treadonly closeAgentScope: (agentScopeId: string) => Promise<void>;\n\treadonly closeSession: (scopeKey: string) => Promise<void>;\n\treadonly listTools: (call: ListToolsCall) => Promise<readonly Tool[]>;\n}\n\ninterface CachedClient {\n\treadonly client: UpstreamMcpClientLike;\n}\n\ninterface PendingClient {\n\treadonly generation: number;\n\treadonly promise: Promise<UpstreamMcpClientLike>;\n}\n\nconst defaultConnectionTimeoutMs = 30_000;\nconst defaultMaxResponseBytes = 4 * 1_024 * 1_024;\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isTransport(value: unknown): value is Transport {\n\treturn (\n\t\tisObjectRecord(value) &&\n\t\ttypeof value.start === 'function' &&\n\t\ttypeof value.send === 'function' &&\n\t\ttypeof value.close === 'function'\n\t);\n}\n\nfunction createSdkClient(): UpstreamMcpClientLike {\n\tconst client = new Client({ name: 'mcp-portal', version: '1.0.0' });\n\treturn {\n\t\tcallTool: async (params, _resultSchema, options) =>\n\t\t\tawait client.callTool(params, undefined, options),\n\t\tclose: async () => {\n\t\t\tawait client.close();\n\t\t},\n\t\tconnect: async (transport, options) => {\n\t\t\tif (!isTransport(transport)) {\n\t\t\t\tthrow new Error('SDK MCP client requires a valid MCP transport.');\n\t\t\t}\n\t\t\tawait client.connect(transport, options);\n\t\t},\n\t\tlistTools: async (params, options) => {\n\t\t\tconst result = await client.listTools(params, options);\n\t\t\treturn {\n\t\t\t\t...(result.nextCursor !== undefined ? { nextCursor: result.nextCursor } : {}),\n\t\t\t\ttools: result.tools,\n\t\t\t};\n\t\t},\n\t};\n}\n\nfunction withRemoteHeaders(server: RemoteUpstreamMcpServer): RemoteUpstreamMcpServer {\n\tif (!server.headers) {\n\t\treturn server;\n\t}\n\n\treturn {\n\t\t...server,\n\t\trequestInit: {\n\t\t\t...server.requestInit,\n\t\t\theaders: {\n\t\t\t\t...normalizeHeaders(server.requestInit?.headers),\n\t\t\t\t...server.headers,\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction createSdkTransport(\n\tserver: NormalizedUpstreamMcpServer,\n\ttransport: Exclude<UpstreamMcpTransportKind, 'auto-http'>,\n): unknown {\n\tif (transport === 'stdio') {\n\t\tif (server.transport !== 'stdio') {\n\t\t\tthrow new Error('Stdio transport requires stdio server config.');\n\t\t}\n\n\t\treturn new StdioClientTransport({\n\t\t\t...(server.args ? { args: [...server.args] } : {}),\n\t\t\tcommand: server.command,\n\t\t\t...(server.cwd !== undefined ? { cwd: server.cwd } : {}),\n\t\t\t...(server.env ? { env: { ...server.env } } : {}),\n\t\t});\n\t}\n\n\tif (server.transport === 'stdio') {\n\t\tthrow new Error('Remote transport requires remote server config.');\n\t}\n\n\tconst remoteServer = withRemoteHeaders(server);\n\tif (transport === 'sse') {\n\t\tconst options: SSEClientTransportOptions = {};\n\t\tif (remoteServer.eventSourceInit !== undefined) {\n\t\t\toptions.eventSourceInit = remoteServer.eventSourceInit;\n\t\t}\n\t\tif (remoteServer.requestInit !== undefined) {\n\t\t\toptions.requestInit = remoteServer.requestInit;\n\t\t}\n\t\treturn new SSEClientTransport(new URL(remoteServer.url), options);\n\t}\n\n\tconst options: StreamableHTTPClientTransportOptions = {};\n\tif (remoteServer.requestInit !== undefined) {\n\t\toptions.requestInit = remoteServer.requestInit;\n\t}\n\treturn new StreamableHTTPClientTransport(new URL(remoteServer.url), options);\n}\n\nfunction cacheKey(agentScopeId: string, namespace: string): string {\n\treturn `${agentScopeId}\\n${namespace}`;\n}\n\nfunction rootAgentScopeId(agentScopeId: string): string {\n\treturn agentScopeId.split('\\n', 1)[0] ?? agentScopeId;\n}\n\nfunction transportAttempts(\n\tserver: NormalizedUpstreamMcpServer,\n): readonly Exclude<UpstreamMcpTransportKind, 'auto-http'>[] {\n\tif (server.transport === 'auto-http') {\n\t\treturn ['streamable-http', 'sse'];\n\t}\n\n\treturn [server.transport];\n}\n\nfunction redactionValuesFromServer(server: NormalizedUpstreamMcpServer): readonly string[] {\n\tif (server.transport === 'stdio') {\n\t\treturn Object.values(server.env ?? {}).filter((value) => value.length > 0);\n\t}\n\n\treturn Object.values(server.headers ?? {}).filter((value) => value.length > 0);\n}\n\nfunction timeoutMsForServer(server: NormalizedUpstreamMcpServer): number {\n\treturn server.connectionTimeoutMs ?? defaultConnectionTimeoutMs;\n}\n\nfunction assertUpstreamResponseSize(value: unknown, maxResponseBytes: number): void {\n\tconst serialized = JSON.stringify(value);\n\tif (serialized === undefined) {\n\t\treturn;\n\t}\n\tconst byteLength = Buffer.byteLength(serialized, 'utf8');\n\tif (byteLength > maxResponseBytes) {\n\t\tthrow new Error(\n\t\t\t`MCP upstream response exceeded ${String(maxResponseBytes)} bytes (${String(byteLength)} bytes).`,\n\t\t);\n\t}\n}\n\nfunction isAbortError(error: unknown): boolean {\n\treturn error instanceof Error && error.name === 'AbortError';\n}\n\nfunction isCallerAbortError(error: unknown, signal: AbortSignal | undefined): boolean {\n\treturn signal?.aborted === true && (error === signal.reason || isAbortError(error));\n}\n\nasync function withTimeout<TResult>(\n\tpromise: Promise<TResult>,\n\tprops: {\n\t\treadonly onTimeout?: (error: Error) => void;\n\t\treadonly operation: string;\n\t\treadonly timeoutMs: number;\n\t},\n): Promise<TResult> {\n\tlet timeout: NodeJS.Timeout | undefined;\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tpromise,\n\t\t\tnew Promise<never>((_resolve, reject) => {\n\t\t\t\ttimeout = setTimeout(() => {\n\t\t\t\t\tconst error = new Error(`${props.operation} timed out after ${props.timeoutMs}ms.`);\n\t\t\t\t\tprops.onTimeout?.(error);\n\t\t\t\t\treject(error);\n\t\t\t\t}, props.timeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timeout) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n}\n\nfunction createRuntimeAbortSignal(parentSignal: AbortSignal | undefined): {\n\treadonly abortTimeout: (error: Error) => void;\n\treadonly dispose: () => void;\n\treadonly signal: AbortSignal;\n} {\n\tconst controller = new AbortController();\n\tconst abortFromParent = (): void => {\n\t\tif (!controller.signal.aborted) {\n\t\t\tcontroller.abort(parentSignal?.reason);\n\t\t}\n\t};\n\tif (parentSignal?.aborted) {\n\t\tabortFromParent();\n\t} else {\n\t\tparentSignal?.addEventListener('abort', abortFromParent, { once: true });\n\t}\n\n\treturn {\n\t\tabortTimeout: (error) => {\n\t\t\tif (!controller.signal.aborted) {\n\t\t\t\tcontroller.abort(error);\n\t\t\t}\n\t\t},\n\t\tdispose: () => {\n\t\t\tparentSignal?.removeEventListener('abort', abortFromParent);\n\t\t},\n\t\tsignal: controller.signal,\n\t};\n}\n\nasync function listAllTools(\n\tclient: UpstreamMcpClientLike,\n\tcursor: string | undefined,\n\tcollectedTools: readonly Tool[],\n\ttimeoutAbort: {\n\t\treadonly abortTimeout: (error: Error) => void;\n\t\treadonly signal: AbortSignal;\n\t},\n\ttimeoutMs: number,\n): Promise<readonly Tool[]> {\n\tconst result = await withTimeout(\n\t\tclient.listTools(cursor ? { cursor } : undefined, { signal: timeoutAbort.signal }),\n\t\t{\n\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\toperation: 'MCP listTools',\n\t\t\ttimeoutMs,\n\t\t},\n\t);\n\tconst nextTools = [...collectedTools, ...result.tools];\n\treturn result.nextCursor\n\t\t? listAllTools(client, result.nextCursor, nextTools, timeoutAbort, timeoutMs)\n\t\t: nextTools;\n}\n\nasync function closeClientAfterFailure(client: UpstreamMcpClientLike | null): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch {\n\t\t// Preserve the original upstream failure; close errors are best-effort cleanup.\n\t}\n}\n\nasync function closeClientForTeardown(\n\tclient: UpstreamMcpClientLike | null,\n\tprops: {\n\t\treadonly context: UpstreamMcpCloseErrorContext;\n\t\treadonly onCloseError?:\n\t\t\t| ((error: Error, context: UpstreamMcpCloseErrorContext) => void)\n\t\t\t| undefined;\n\t},\n): Promise<void> {\n\tif (!client) {\n\t\treturn;\n\t}\n\ttry {\n\t\tawait client.close();\n\t} catch (error) {\n\t\tprops.onCloseError?.(redactThrownError(error), props.context);\n\t}\n}\n\nfunction closeErrorContextFromCacheKey(cacheKeyValue: string): UpstreamMcpCloseErrorContext {\n\tconst keyParts = cacheKeyValue.split('\\n');\n\tconst namespace = keyParts.length > 1 ? keyParts[keyParts.length - 1] : undefined;\n\tconst agentScopeId =\n\t\tnamespace !== undefined ? keyParts.slice(0, keyParts.length - 1).join('\\n') : cacheKeyValue;\n\treturn {\n\t\tagentScopeId,\n\t\t...(namespace !== undefined ? { namespace } : {}),\n\t};\n}\n\nfunction redactToolCatalog(\n\ttools: readonly Tool[],\n\toptions: { readonly exactValues: readonly string[] },\n): readonly Tool[] {\n\treturn tools.map((tool) => ToolSchema.parse(redactUpstreamCatalogValue(tool, options)));\n}\n\nexport function createUpstreamMcpClientRuntime(\n\toptions: UpstreamMcpRuntimeOptions,\n): UpstreamMcpClientRuntime {\n\tconst serversByNamespace = new Map(options.servers.map((server) => [server.namespace, server]));\n\tconst clients = new Map<string, CachedClient>();\n\tconst pendingClients = new Map<string, PendingClient>();\n\tconst agentScopeGenerations = new Map<string, number>();\n\tconst closedClients = new WeakSet<UpstreamMcpClientLike>();\n\tconst createClient = options.createClient ?? createSdkClient;\n\tconst createTransport = options.createTransport ?? createSdkTransport;\n\tconst maxResponseBytes = options.maxResponseBytes ?? defaultMaxResponseBytes;\n\tconst redactionValues = [\n\t\t...(options.additionalRedactionValues ?? []),\n\t\t...options.servers.flatMap((server) => redactionValuesFromServer(server)),\n\t];\n\n\tfunction generationForAgentScope(agentScopeId: string): number {\n\t\treturn (\n\t\t\tagentScopeGenerations.get(agentScopeId) ??\n\t\t\tagentScopeGenerations.get(rootAgentScopeId(agentScopeId)) ??\n\t\t\t0\n\t\t);\n\t}\n\n\tfunction incrementAgentScopeGeneration(agentScopeId: string): void {\n\t\tconst rootAgentScope = rootAgentScopeId(agentScopeId);\n\t\tagentScopeGenerations.set(rootAgentScope, (agentScopeGenerations.get(rootAgentScope) ?? 0) + 1);\n\t}\n\n\tfunction incrementScopeGeneration(scopeKey: string): void {\n\t\tagentScopeGenerations.set(scopeKey, (agentScopeGenerations.get(scopeKey) ?? 0) + 1);\n\t}\n\n\tasync function closeClientAfterFailureOnce(client: UpstreamMcpClientLike | null): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientAfterFailure(client);\n\t}\n\n\tasync function closeClientForTeardownOnce(\n\t\tclient: UpstreamMcpClientLike | null,\n\t\tcontext: UpstreamMcpCloseErrorContext,\n\t): Promise<void> {\n\t\tif (!client || closedClients.has(client)) {\n\t\t\treturn;\n\t\t}\n\t\tclosedClients.add(client);\n\t\tawait closeClientForTeardown(client, {\n\t\t\tcontext,\n\t\t\tonCloseError: options.onCloseError,\n\t\t});\n\t}\n\n\tasync function createConnectedClient(\n\t\tserver: NormalizedUpstreamMcpServer,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst attempts = transportAttempts(server);\n\t\tasync function tryAttempt(\n\t\t\tattemptIndex: number,\n\t\t\tlastError: Error | null,\n\t\t): Promise<UpstreamMcpClientLike> {\n\t\t\tconst transportKind = attempts[attemptIndex];\n\t\t\tif (transportKind === undefined) {\n\t\t\t\tthrow (\n\t\t\t\t\tlastError ??\n\t\t\t\t\tnew Error(`Could not connect to upstream MCP namespace \"${server.namespace}\".`)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst client = createClient();\n\t\t\tconst transportServer =\n\t\t\t\ttransportKind === 'sse' && server.transport !== 'stdio'\n\t\t\t\t\t? withRemoteHeaders(server)\n\t\t\t\t\t: server;\n\t\t\tconst transport = createTransport(transportServer, transportKind);\n\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\ttry {\n\t\t\t\tawait withTimeout(client.connect(transport, { signal: timeoutAbort.signal }), {\n\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\toperation: `MCP ${transportKind} connect for namespace \"${server.namespace}\"`,\n\t\t\t\t\ttimeoutMs: timeoutMsForServer(server),\n\t\t\t\t});\n\t\t\t\treturn client;\n\t\t\t} catch (error) {\n\t\t\t\tconst redactedError = redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\treturn tryAttempt(attemptIndex + 1, redactedError);\n\t\t\t} finally {\n\t\t\t\ttimeoutAbort.dispose();\n\t\t\t}\n\t\t}\n\n\t\treturn tryAttempt(0, null);\n\t}\n\n\tasync function getClient(\n\t\tagentScopeId: string,\n\t\tnamespace: string,\n\t): Promise<UpstreamMcpClientLike> {\n\t\tconst key = cacheKey(agentScopeId, namespace);\n\t\tconst cachedClient = clients.get(key);\n\t\tif (cachedClient) {\n\t\t\treturn cachedClient.client;\n\t\t}\n\t\tconst pendingClient = pendingClients.get(key);\n\t\tconst generation = generationForAgentScope(agentScopeId);\n\t\tif (pendingClient && pendingClient.generation === generation) {\n\t\t\treturn pendingClient.promise;\n\t\t}\n\t\tif (pendingClient) {\n\t\t\tpendingClients.delete(key);\n\t\t\tvoid pendingClient.promise.then(closeClientAfterFailureOnce, () => undefined);\n\t\t}\n\n\t\tconst server = serversByNamespace.get(namespace);\n\t\tif (!server) {\n\t\t\tthrow new Error(`Unknown upstream MCP namespace \"${namespace}\".`);\n\t\t}\n\n\t\tconst pending = createConnectedClient(server);\n\t\tconst pendingRecord = { generation, promise: pending } satisfies PendingClient;\n\t\tpendingClients.set(key, pendingRecord);\n\t\ttry {\n\t\t\tconst client = await pending;\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tclients.set(key, { client });\n\t\t\tif (generationForAgentScope(agentScopeId) !== generation) {\n\t\t\t\tif (clients.get(key)?.client === client) {\n\t\t\t\t\tclients.delete(key);\n\t\t\t\t}\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`MCP client for agent scope \"${rootAgentScopeId(agentScopeId)}\" was invalidated.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn client;\n\t\t} finally {\n\t\t\tif (pendingClients.get(key) === pendingRecord) {\n\t\t\t\tpendingClients.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tasync callTool(call: UpstreamToolCall): Promise<unknown> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(call.signal);\n\t\t\t\ttry {\n\t\t\t\t\tconst upstreamResult = await withTimeout(\n\t\t\t\t\t\tclient.callTool({ arguments: call.arguments, name: call.toolName }, undefined, {\n\t\t\t\t\t\t\tonprogress: (progress) => {\n\t\t\t\t\t\t\t\tvoid call.onEvent?.({\n\t\t\t\t\t\t\t\t\tkind: 'progress',\n\t\t\t\t\t\t\t\t\t...(progress.message !== undefined ? { message: progress.message } : {}),\n\t\t\t\t\t\t\t\t\tprogress: progress.progress,\n\t\t\t\t\t\t\t\t\t...(progress.total !== undefined ? { total: progress.total } : {}),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsignal: timeoutAbort.signal,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tonTimeout: timeoutAbort.abortTimeout,\n\t\t\t\t\t\t\toperation: `MCP callTool ${call.namespace}.${call.toolName}`,\n\t\t\t\t\t\t\ttimeoutMs: server ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tassertUpstreamResponseSize(upstreamResult, maxResponseBytes);\n\t\t\t\t\treturn redactUpstreamResponse(upstreamResult, { exactValues: redactionValues });\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isCallerAbortError(error, call.signal)) {\n\t\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t}\n\t\t},\n\t\tasync closeAgentScope(agentScopeId: string): Promise<void> {\n\t\t\tincrementAgentScopeGeneration(agentScopeId);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== agentScopeId && !key.startsWith(`${agentScopeId}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync closeSession(scopeKey: string): Promise<void> {\n\t\t\tincrementScopeGeneration(scopeKey);\n\t\t\tconst closePromises: Promise<void>[] = [];\n\t\t\tfor (const [key, cachedClient] of clients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tclients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tcloseClientForTeardownOnce(cachedClient.client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t);\n\t\t\t}\n\t\t\tfor (const [key, pendingClient] of pendingClients.entries()) {\n\t\t\t\tif (key !== scopeKey && !key.startsWith(`${scopeKey}\\n`)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpendingClients.delete(key);\n\t\t\t\tclosePromises.push(\n\t\t\t\t\tpendingClient.promise.then(\n\t\t\t\t\t\t(client) => closeClientForTeardownOnce(client, closeErrorContextFromCacheKey(key)),\n\t\t\t\t\t\t() => undefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(closePromises);\n\t\t},\n\t\tasync listTools(call: ListToolsCall): Promise<readonly Tool[]> {\n\t\t\tconst key = cacheKey(call.agentScopeId, call.namespace);\n\t\t\tlet client: UpstreamMcpClientLike | null = null;\n\t\t\ttry {\n\t\t\t\tclient = await getClient(call.agentScopeId, call.namespace);\n\t\t\t\tconst server = serversByNamespace.get(call.namespace);\n\t\t\t\tconst timeoutAbort = createRuntimeAbortSignal(undefined);\n\t\t\t\ttry {\n\t\t\t\t\treturn redactToolCatalog(\n\t\t\t\t\t\tawait listAllTools(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t[],\n\t\t\t\t\t\t\ttimeoutAbort,\n\t\t\t\t\t\t\tserver ? timeoutMsForServer(server) : defaultConnectionTimeoutMs,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ exactValues: redactionValues },\n\t\t\t\t\t);\n\t\t\t\t} finally {\n\t\t\t\t\ttimeoutAbort.dispose();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tclients.delete(key);\n\t\t\t\tawait closeClientAfterFailureOnce(client);\n\t\t\t\tthrow redactThrownError(error, { exactValues: redactionValues });\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|