@copilotkit/runtime 1.56.5-canary.1777972218 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/agent/index.cjs +8 -41
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +27 -54
  4. package/dist/agent/index.d.cts.map +1 -1
  5. package/dist/agent/index.d.mts +27 -54
  6. package/dist/agent/index.d.mts.map +1 -1
  7. package/dist/agent/index.mjs +10 -43
  8. package/dist/agent/index.mjs.map +1 -1
  9. package/dist/package.cjs +1 -1
  10. package/dist/package.mjs +1 -1
  11. package/dist/v2/index.cjs +0 -2
  12. package/dist/v2/index.d.cts +5 -6
  13. package/dist/v2/index.d.mts +5 -6
  14. package/dist/v2/index.mjs +1 -2
  15. package/dist/v2/runtime/core/runtime.d.cts +0 -1
  16. package/dist/v2/runtime/core/runtime.d.cts.map +1 -1
  17. package/dist/v2/runtime/core/runtime.d.mts +0 -1
  18. package/dist/v2/runtime/core/runtime.d.mts.map +1 -1
  19. package/dist/v2/runtime/handlers/intelligence/run.cjs +0 -4
  20. package/dist/v2/runtime/handlers/intelligence/run.cjs.map +1 -1
  21. package/dist/v2/runtime/handlers/intelligence/run.mjs +0 -4
  22. package/dist/v2/runtime/handlers/intelligence/run.mjs.map +1 -1
  23. package/dist/v2/runtime/handlers/shared/agent-utils.cjs.map +1 -1
  24. package/dist/v2/runtime/handlers/shared/agent-utils.mjs.map +1 -1
  25. package/dist/v2/runtime/index.d.cts +1 -3
  26. package/dist/v2/runtime/index.d.cts.map +1 -1
  27. package/dist/v2/runtime/index.d.mts +1 -3
  28. package/dist/v2/runtime/index.d.mts.map +1 -1
  29. package/dist/v2/runtime/intelligence-platform/client.cjs +0 -53
  30. package/dist/v2/runtime/intelligence-platform/client.cjs.map +1 -1
  31. package/dist/v2/runtime/intelligence-platform/client.d.cts +0 -41
  32. package/dist/v2/runtime/intelligence-platform/client.d.cts.map +1 -1
  33. package/dist/v2/runtime/intelligence-platform/client.d.mts +0 -41
  34. package/dist/v2/runtime/intelligence-platform/client.d.mts.map +1 -1
  35. package/dist/v2/runtime/intelligence-platform/client.mjs +0 -53
  36. package/dist/v2/runtime/intelligence-platform/client.mjs.map +1 -1
  37. package/package.json +2 -2
  38. package/src/agent/__tests__/mcp-clients.test.ts +25 -11
  39. package/src/agent/__tests__/mcp-servers-integration.test.ts +1 -485
  40. package/src/agent/index.ts +62 -139
  41. package/src/v2/runtime/handlers/intelligence/run.ts +0 -9
  42. package/src/v2/runtime/handlers/shared/agent-utils.ts +0 -1
  43. package/src/v2/runtime/index.ts +0 -5
  44. package/src/v2/runtime/intelligence-platform/client.ts +0 -68
  45. package/dist/agent/mcp-transport.cjs +0 -94
  46. package/dist/agent/mcp-transport.cjs.map +0 -1
  47. package/dist/agent/mcp-transport.d.cts +0 -51
  48. package/dist/agent/mcp-transport.d.cts.map +0 -1
  49. package/dist/agent/mcp-transport.d.mts +0 -52
  50. package/dist/agent/mcp-transport.d.mts.map +0 -1
  51. package/dist/agent/mcp-transport.mjs +0 -92
  52. package/dist/agent/mcp-transport.mjs.map +0 -1
  53. package/dist/v2/runtime/intelligence-platform/index.d.cts +0 -2
  54. package/dist/v2/runtime/intelligence-platform/index.d.mts +0 -2
  55. package/src/agent/mcp-transport.ts +0 -190
  56. package/src/v2/runtime/intelligence-platform/__tests__/intelligence-mcp-helper.test.ts +0 -190
@@ -1,6 +1,8 @@
1
- import type {
1
+ import {
2
+ AbstractAgent,
2
3
  BaseEvent,
3
4
  RunAgentInput,
5
+ EventType,
4
6
  Message,
5
7
  ReasoningEndEvent,
6
8
  ReasoningMessageContentEvent,
@@ -18,9 +20,9 @@ import type {
18
20
  StateSnapshotEvent,
19
21
  StateDeltaEvent,
20
22
  } from "@ag-ui/client";
21
- import { AbstractAgent, EventType } from "@ag-ui/client";
22
23
  import type { AgentCapabilities } from "@ag-ui/core";
23
- import type {
24
+ import {
25
+ streamText,
24
26
  LanguageModel,
25
27
  ModelMessage,
26
28
  AssistantModelMessage,
@@ -32,31 +34,29 @@ import type {
32
34
  TextPart,
33
35
  ImagePart,
34
36
  FilePart,
37
+ tool as createVercelAISDKTool,
35
38
  ToolChoice,
36
39
  ToolSet,
40
+ stepCountIs,
37
41
  } from "ai";
38
- import { streamText, tool as createVercelAISDKTool, stepCountIs } from "ai";
39
- import { createMCPClient } from "@ai-sdk/mcp";
40
- import type { MCPClient } from "@ai-sdk/mcp";
42
+ import { experimental_createMCPClient as createMCPClient } from "@ai-sdk/mcp";
41
43
  import { Observable } from "rxjs";
42
44
  import { createOpenAI } from "@ai-sdk/openai";
43
45
  import { createAnthropic } from "@ai-sdk/anthropic";
44
46
  import { createGoogleGenerativeAI } from "@ai-sdk/google";
45
47
  import { createVertex } from "@ai-sdk/google-vertex";
46
- import { logger, safeParseToolArgs } from "@copilotkit/shared";
48
+ import { safeParseToolArgs } from "@copilotkit/shared";
47
49
  import { z } from "zod";
48
50
  import type { StandardSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
49
51
  import { schemaToJsonSchema } from "@copilotkit/shared";
50
52
  import { jsonSchema as aiJsonSchema } from "ai";
51
53
  import { convertAISDKStream } from "./converters/aisdk";
52
54
  import { convertTanStackStream } from "./converters/tanstack";
53
- import type { StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
54
55
  import {
55
- CopilotKitMCPTransport,
56
- MCPHeaderResolverError,
57
- type MCPRequestContext,
58
- type MCPRuntimeUser,
59
- } from "./mcp-transport";
56
+ StreamableHTTPClientTransport,
57
+ StreamableHTTPClientTransportOptions,
58
+ } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
59
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
60
60
  import { randomUUID } from "@copilotkit/shared";
61
61
 
62
62
  /**
@@ -113,114 +113,58 @@ export type BuiltInAgentModel =
113
113
  */
114
114
  export type ModelSpecifier = string | LanguageModel;
115
115
 
116
- // MCPRequestContext and MCPHeaderResolverError now live in mcp-transport.ts.
117
- // Re-export so existing imports of these symbols from agent/index continue to
118
- // work.
119
- export { MCPHeaderResolverError, type MCPRequestContext };
120
-
121
116
  /**
122
- * MCP Client configuration for HTTP transport.
117
+ * MCP Client configuration for HTTP transport
123
118
  */
124
119
  export interface MCPClientConfigHTTP {
125
- /** Type of MCP client */
126
- type: "http";
127
- /** URL of the MCP server */
128
- url: string;
129
120
  /**
130
- * Optional transport options for the underlying
131
- * `StreamableHTTPClientTransport`. Pre-existing escape hatch for advanced
132
- * use cases (custom `fetch`, `requestInit`, OAuth `authProvider`, etc.).
121
+ * Type of MCP client
133
122
  */
134
- options?: StreamableHTTPClientTransportOptions;
123
+ type: "http";
135
124
  /**
136
- * Static HTTP headers, merged into every outbound request to this server.
137
- * For per-call values, use {@link MCPClientConfigHTTP.getHeaders} instead.
125
+ * URL of the MCP server
138
126
  */
139
- headers?: Record<string, string>;
127
+ url: string;
140
128
  /**
141
- * Per-call header resolver. Invoked on **every** outbound HTTP request to
142
- * this server (initialize, tools/list, tools/call, SSE reconnects). The
143
- * returned headers are merged on top of `headers` and any
144
- * `options.requestInit.headers`, so a resolver can override either.
145
- *
146
- * Throwing from the resolver causes the agent run to emit `RUN_ERROR`
147
- * carrying a {@link MCPHeaderResolverError}.
129
+ * Optional transport options for HTTP client
148
130
  */
149
- getHeaders?: (
150
- ctx: MCPRequestContext,
151
- ) => Record<string, string> | Promise<Record<string, string>>;
152
- /** If true, the server is skipped at run-start when `agent.user` is unset. */
153
- requiresUser?: boolean;
131
+ options?: StreamableHTTPClientTransportOptions;
154
132
  }
155
133
 
156
134
  /**
157
- * MCP Client configuration for SSE transport.
135
+ * MCP Client configuration for SSE transport
158
136
  */
159
137
  export interface MCPClientConfigSSE {
160
- /** Type of MCP client */
138
+ /**
139
+ * Type of MCP client
140
+ */
161
141
  type: "sse";
162
- /** URL of the MCP server */
142
+ /**
143
+ * URL of the MCP server
144
+ */
163
145
  url: string;
164
- /** Optional HTTP headers (e.g., for authentication). */
146
+ /**
147
+ * Optional HTTP headers (e.g., for authentication)
148
+ */
165
149
  headers?: Record<string, string>;
166
150
  }
167
151
 
168
152
  /**
169
- * MCP Client configuration.
153
+ * MCP Client configuration
170
154
  */
171
155
  export type MCPClientConfig = MCPClientConfigHTTP | MCPClientConfigSSE;
172
156
 
173
157
  /**
174
- * A user-managed MCP client that provides tools to the agent. Structural
175
- * alias for `@ai-sdk/mcp`'s `MCPClient.tools` slice pass any value built by
176
- * `createMCPClient()` directly, or supply a custom `{ tools(): ... }` object
177
- * for tests/caching layers.
178
- *
179
- * Unlike `mcpServers`, the agent does NOT create or close these clients. The
180
- * user controls the full lifecycle.
181
- */
182
- export type MCPClientProvider = Pick<MCPClient, "tools">;
183
-
184
- /**
185
- * Open an MCP client for the given server config.
158
+ * A user-managed MCP client that provides tools to the agent.
159
+ * The user is responsible for creating, configuring, and closing the client.
160
+ * Compatible with the return type of @ai-sdk/mcp's createMCPClient().
186
161
  *
187
- * - HTTP always goes through {@link CopilotKitMCPTransport} (preserves the
188
- * pre-existing `options` escape hatch and adds per-call `getHeaders`
189
- * resolution).
190
- * - SSE goes through `@ai-sdk/mcp`'s `createMCPClient`, whose built-in
191
- * `SseMCPTransport` correctly applies static `headers` on every outbound
192
- * request.
162
+ * Unlike mcpServers, the agent does NOT create or close these clients.
163
+ * This allows persistent connections, custom auth, and tool caching.
193
164
  */
194
- async function openMcpClient(
195
- config: MCPClientConfig,
196
- context: {
197
- requestHeaders: Record<string, string>;
198
- input: RunAgentInput;
199
- user?: MCPRuntimeUser;
200
- },
201
- ): Promise<MCPClient> {
202
- if (config.type === "http") {
203
- const transport = new CopilotKitMCPTransport({
204
- url: config.url,
205
- headers: config.headers,
206
- getHeaders: config.getHeaders,
207
- options: config.options,
208
- requestHeaders: context.requestHeaders,
209
- input: context.input,
210
- user: context.user,
211
- });
212
- return createMCPClient({ transport });
213
- }
214
-
215
- // SSE: hand to Vercel's transport. Static `headers` are applied via the
216
- // SseMCPTransport's common-header pipeline.
217
- return createMCPClient({
218
- transport: {
219
- type: "sse",
220
- url: config.url,
221
- headers: config.headers,
222
- },
223
- });
165
+ export interface MCPClientProvider {
166
+ /** Return tools to be merged into the agent's tool set. */
167
+ tools(): Promise<ToolSet>;
224
168
  }
225
169
 
226
170
  /**
@@ -907,21 +851,6 @@ function isFactoryConfig(
907
851
 
908
852
  export class BuiltInAgent extends AbstractAgent {
909
853
  private abortController?: AbortController;
910
- /**
911
- * Headers populated per-request by the runtime's
912
- * `extractForwardableHeaders` (the incoming request's `Authorization` +
913
- * every `x-*` header, lower-cased). Available to MCP header resolvers via
914
- * {@link MCPRequestContext.requestHeaders}; kept here as a plain field so
915
- * the runtime's `configureAgentForRequest` feature-detect activates.
916
- */
917
- public headers: Record<string, string> = {};
918
- /**
919
- * End-user identity for the current request, populated by the runtime by
920
- * invoking `identifyUser(request)` (Intelligence mode). Surfaced to MCP
921
- * header resolvers via {@link MCPRequestContext.user}; remains undefined
922
- * for runs that aren't going through a runtime with `identifyUser` set.
923
- */
924
- public user?: { id: string; name: string };
925
854
 
926
855
  constructor(private config: BuiltInAgentConfiguration) {
927
856
  super();
@@ -1175,7 +1104,7 @@ export class BuiltInAgent extends AbstractAgent {
1175
1104
  }
1176
1105
 
1177
1106
  // Set up MCP clients if configured and process the stream
1178
- const mcpClients: MCPClient[] = [];
1107
+ const mcpClients: Array<{ close: () => Promise<void> }> = [];
1179
1108
 
1180
1109
  (async () => {
1181
1110
  let terminalEventEmitted = false;
@@ -1260,39 +1189,33 @@ export class BuiltInAgent extends AbstractAgent {
1260
1189
 
1261
1190
  // Initialize MCP clients and get their tools
1262
1191
  if (this.config.mcpServers && this.config.mcpServers.length > 0) {
1263
- // Snapshot the agent's per-run state (forwarded headers + user)
1264
- // once at run-start. Resolvers see this immutable snapshot for the
1265
- // lifetime of the run, including any reconnections fired after the
1266
- // initial run completes.
1267
- const requestHeaders: Record<string, string> = { ...this.headers };
1268
- const user = this.user ? { ...this.user } : undefined;
1269
-
1270
1192
  for (const serverConfig of this.config.mcpServers) {
1271
- if (
1272
- serverConfig.type === "http" &&
1273
- serverConfig.requiresUser &&
1274
- !user
1275
- ) {
1276
- logger.warn(
1277
- { url: serverConfig.url },
1278
- "Skipping MCP server: requiresUser is set but no user is resolved for this run",
1193
+ let transport;
1194
+
1195
+ if (serverConfig.type === "http") {
1196
+ const url = new URL(serverConfig.url);
1197
+ transport = new StreamableHTTPClientTransport(
1198
+ url,
1199
+ serverConfig.options,
1200
+ );
1201
+ } else if (serverConfig.type === "sse") {
1202
+ transport = new SSEClientTransport(
1203
+ new URL(serverConfig.url),
1204
+ serverConfig.headers,
1279
1205
  );
1280
- continue;
1281
1206
  }
1282
1207
 
1283
- const mcpClient = await openMcpClient(serverConfig, {
1284
- requestHeaders,
1285
- input,
1286
- user,
1287
- });
1288
- mcpClients.push(mcpClient);
1208
+ if (transport) {
1209
+ const mcpClient = await createMCPClient({ transport });
1210
+ mcpClients.push(mcpClient);
1289
1211
 
1290
- // Get tools from this MCP server and merge with existing tools
1291
- const mcpTools = await mcpClient.tools();
1292
- streamTextParams.tools = {
1293
- ...streamTextParams.tools,
1294
- ...mcpTools,
1295
- } as ToolSet;
1212
+ // Get tools from this MCP server and merge with existing tools
1213
+ const mcpTools = await mcpClient.tools();
1214
+ streamTextParams.tools = {
1215
+ ...streamTextParams.tools,
1216
+ ...mcpTools,
1217
+ } as ToolSet;
1218
+ }
1296
1219
  }
1297
1220
  }
1298
1221
 
@@ -80,15 +80,6 @@ export async function handleIntelligenceRun({
80
80
  }
81
81
  const userId = user.id;
82
82
 
83
- // Surface the resolved user on the agent so MCP header resolvers (and any
84
- // other per-run consumer) can read it via context. Snapshotted by the
85
- // BuiltInAgent at run-start; runs that don't go through this Intelligence
86
- // path leave `agent.user` undefined.
87
- (agent as unknown as { user?: { id: string; name: string } }).user = {
88
- id: user.id,
89
- name: user.name,
90
- };
91
-
92
83
  try {
93
84
  const { thread, created } = await runtime.intelligence.getOrCreateThread({
94
85
  threadId: input.threadId,
@@ -13,7 +13,6 @@ import { logger } from "@copilotkit/shared";
13
13
  type MiddlewareCapableAgent = AbstractAgent & {
14
14
  use?: (middleware: unknown) => void;
15
15
  headers?: Record<string, string>;
16
- user?: { id: string; name: string };
17
16
  };
18
17
 
19
18
  export interface RunAgentParameters {
@@ -19,11 +19,6 @@ export {
19
19
  type UpdateThreadRequest,
20
20
  } from "./intelligence-platform";
21
21
 
22
- // Re-export `@ai-sdk/mcp` stable types so consumers don't need to depend on
23
- // it directly to type their MCP wiring. `MCPClient` is the value users pass
24
- // into `mcpClients`; `MCPTransport` is the contract for custom transports.
25
- export type { MCPClient, MCPTransport } from "@ai-sdk/mcp";
26
-
27
22
  // Export framework-agnostic fetch handler
28
23
  export { createCopilotRuntimeHandler } from "./core/fetch-handler";
29
24
  export type {
@@ -1,12 +1,4 @@
1
1
  import { logger } from "@copilotkit/shared";
2
- import type { MCPClientConfigHTTP } from "../../../agent";
3
-
4
- // Header name carrying the per-call end-user identity that the CopilotKit
5
- // Intelligence `/mcp` endpoint requires. Encapsulated inside the helper so
6
- // users of `intelligence.toMCPServer()` never need to know the wire-level
7
- // header name — they configure `identifyUser` once on the runtime and the
8
- // helper does the rest.
9
- const INTELLIGENCE_USER_ID_HEADER = "x-cpki-user-id";
10
2
 
11
3
  /**
12
4
  * Error thrown when an Intelligence platform HTTP request returns a non-2xx
@@ -382,66 +374,6 @@ export class CopilotKitIntelligence {
382
374
  return this.#apiKey;
383
375
  }
384
376
 
385
- /**
386
- * Build an MCP-server config pre-wired for this Intelligence platform
387
- * connection. Drop the result into a `BuiltInAgent`'s `mcpServers` to give
388
- * the agent access to Intel's bash + thread tools with both auth axes
389
- * correctly populated:
390
- *
391
- * - `Authorization: Bearer <apiKey>` is stamped on every outbound request
392
- * from this Intelligence client's project key.
393
- * - `X-Cpki-User-Id` is read fresh per call from the agent's resolved user,
394
- * which is populated by the runtime's `identifyUser` callback. The
395
- * helper does not surface the header name to user code.
396
- *
397
- * @example
398
- * ```ts
399
- * const intelligence = new CopilotKitIntelligence({
400
- * apiUrl: "https://api.copilotkit.ai",
401
- * wsUrl: "wss://api.copilotkit.ai",
402
- * apiKey: process.env.INTELLIGENCE_API_KEY!,
403
- * });
404
- *
405
- * const runtime = new CopilotRuntime({
406
- * intelligence,
407
- * identifyUser: (request) => resolveUserFromSession(request),
408
- * agents: {
409
- * myAgent: new BuiltInAgent({
410
- * model: "openai/gpt-4o",
411
- * mcpServers: [intelligence.toMCPServer()],
412
- * }),
413
- * },
414
- * });
415
- * ```
416
- *
417
- * The resolver throws if no user is present — typically the runtime is
418
- * misconfigured (no `identifyUser`) or `identifyUser` returned an invalid
419
- * id. Silent fallthrough to an empty user-id would collapse every browser
420
- * session for this project into one shared bash sandbox, which is the
421
- * very isolation guarantee the per-call header exists to enforce.
422
- */
423
- toMCPServer(): MCPClientConfigHTTP {
424
- const apiKey = this.#apiKey;
425
- const url = `${this.#apiUrl}/mcp`;
426
- return {
427
- type: "http",
428
- url,
429
- headers: { Authorization: `Bearer ${apiKey}` },
430
- requiresUser: true,
431
- getHeaders: ({ user }) => {
432
- const userId = user?.id?.trim();
433
- if (!userId) {
434
- throw new Error(
435
- "CopilotKitIntelligence.toMCPServer(): no user resolved for this run. " +
436
- "Configure `identifyUser` on the CopilotRuntime so the agent " +
437
- "knows which end-user each MCP call is on behalf of.",
438
- );
439
- }
440
- return { [INTELLIGENCE_USER_ID_HEADER]: userId };
441
- },
442
- };
443
- }
444
-
445
377
  async #request<T>(method: string, path: string, body?: unknown): Promise<T> {
446
378
  const url = `${this.#apiUrl}${path}`;
447
379
 
@@ -1,94 +0,0 @@
1
- require("reflect-metadata");
2
- const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
- let _modelcontextprotocol_sdk_client_streamableHttp_js = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
4
-
5
- //#region src/agent/mcp-transport.ts
6
- /**
7
- * Thrown when an MCP {@link MCPClientConfigHTTP.getHeaders} resolver throws.
8
- * Wraps the underlying error so `RUN_ERROR` carries clear attribution instead
9
- * of a generic transport failure. The original error is preserved on the
10
- * standard ES2022 `Error.cause` chain.
11
- */
12
- var MCPHeaderResolverError = class extends Error {
13
- constructor(message, cause) {
14
- super(message, { cause });
15
- this.name = "MCPHeaderResolverError";
16
- }
17
- };
18
- /**
19
- * MCP transport for CopilotKit's BuiltInAgent that adds per-call header
20
- * resolution on top of the standard Streamable HTTP transport.
21
- *
22
- * Implements `@ai-sdk/mcp`'s {@link MCPTransport} interface so it can be
23
- * passed straight to `createMCPClient({ transport })`. Internally delegates
24
- * to `@modelcontextprotocol/sdk`'s `StreamableHTTPClientTransport` with a
25
- * wrapped `fetch` that runs the static-header + per-call resolver pipeline
26
- * before each outbound request.
27
- */
28
- var CopilotKitMCPTransport = class {
29
- constructor(options) {
30
- const transportOptions = {
31
- ...options.options,
32
- fetch: buildWrappedFetch(options)
33
- };
34
- this.inner = new _modelcontextprotocol_sdk_client_streamableHttp_js.StreamableHTTPClientTransport(new URL(options.url), transportOptions);
35
- }
36
- get onclose() {
37
- return this.inner.onclose;
38
- }
39
- set onclose(handler) {
40
- this.inner.onclose = handler;
41
- }
42
- get onerror() {
43
- return this.inner.onerror;
44
- }
45
- set onerror(handler) {
46
- this.inner.onerror = handler;
47
- }
48
- get onmessage() {
49
- return this.inner.onmessage;
50
- }
51
- set onmessage(handler) {
52
- this.inner.onmessage = handler;
53
- }
54
- start() {
55
- return this.inner.start();
56
- }
57
- send(message) {
58
- return this.inner.send(message);
59
- }
60
- close() {
61
- return this.inner.close();
62
- }
63
- };
64
- function buildWrappedFetch(options) {
65
- const { headers: staticHeaders, getHeaders, requestHeaders, input, url: mcpServerUrl, user, options: transportOptions } = options;
66
- const baseFetch = transportOptions?.fetch ?? globalThis.fetch;
67
- return async (fetchUrl, init) => {
68
- const merged = new Headers(init?.headers);
69
- if (staticHeaders) for (const [key, value] of Object.entries(staticHeaders)) merged.set(key, value);
70
- if (getHeaders) {
71
- let resolved;
72
- try {
73
- resolved = await getHeaders({
74
- requestHeaders,
75
- input,
76
- mcpServerUrl,
77
- user
78
- });
79
- } catch (err) {
80
- throw new MCPHeaderResolverError(`MCP header resolver for ${mcpServerUrl} threw: ${err instanceof Error ? err.message : String(err)}`, err);
81
- }
82
- for (const [key, value] of Object.entries(resolved)) merged.set(key, value);
83
- }
84
- return baseFetch(fetchUrl, {
85
- ...init,
86
- headers: merged
87
- });
88
- };
89
- }
90
-
91
- //#endregion
92
- exports.CopilotKitMCPTransport = CopilotKitMCPTransport;
93
- exports.MCPHeaderResolverError = MCPHeaderResolverError;
94
- //# sourceMappingURL=mcp-transport.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-transport.cjs","names":["StreamableHTTPClientTransport"],"sources":["../../src/agent/mcp-transport.ts"],"sourcesContent":["import type { RunAgentInput } from \"@ag-ui/client\";\nimport type { JSONRPCMessage, MCPTransport } from \"@ai-sdk/mcp\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { StreamableHTTPClientTransportOptions } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { FetchLike } from \"@modelcontextprotocol/sdk/shared/transport.js\";\n\n/**\n * The end-user identity resolved by the runtime's `identifyUser` callback for\n * the current request. Surfaced on {@link MCPRequestContext} so MCP header\n * resolvers can read it without re-doing auth work.\n */\nexport interface MCPRuntimeUser {\n id: string;\n name: string;\n}\n\n/**\n * Context handed to {@link MCPClientConfigHTTP.getHeaders} on every outbound\n * MCP HTTP request. The resolver is invoked fresh per request — initialize,\n * tools/list, tools/call, and reconnects — so values it depends on are never\n * cached across calls.\n */\nexport interface MCPRequestContext {\n /**\n * Headers forwarded onto the agent for this run. Populated by the runtime's\n * `extractForwardableHeaders` (`authorization` + every `x-*` header from the\n * incoming HTTP request). Keys are lower-cased.\n */\n requestHeaders: Record<string, string>;\n /** The {@link RunAgentInput} the agent is currently running. */\n input: RunAgentInput;\n /** URL of the MCP server this request is going to. */\n mcpServerUrl: string;\n /**\n * The end-user identity for this run, resolved by the runtime's\n * `identifyUser` callback (only populated when the agent is run via a\n * `CopilotRuntime` configured with `identifyUser`). Snapshotted at\n * run-start.\n */\n user?: MCPRuntimeUser;\n}\n\n/**\n * Thrown when an MCP {@link MCPClientConfigHTTP.getHeaders} resolver throws.\n * Wraps the underlying error so `RUN_ERROR` carries clear attribution instead\n * of a generic transport failure. The original error is preserved on the\n * standard ES2022 `Error.cause` chain.\n */\nexport class MCPHeaderResolverError extends Error {\n constructor(message: string, cause: unknown) {\n super(message, { cause });\n this.name = \"MCPHeaderResolverError\";\n }\n}\n\nexport interface CopilotKitMCPTransportOptions {\n /** URL of the MCP server. */\n url: string;\n /** Static HTTP headers, merged into every outbound request. */\n headers?: Record<string, string>;\n /**\n * Per-call header resolver. Invoked on **every** outbound HTTP request to\n * this server (initialize, tools/list, tools/call, reconnects). Returned\n * headers are merged on top of `headers`, so a resolver can override either.\n */\n getHeaders?: (\n ctx: MCPRequestContext,\n ) => Record<string, string> | Promise<Record<string, string>>;\n /**\n * Pre-existing escape hatch: low-level options for the underlying\n * `StreamableHTTPClientTransport`. Forwarded as-is, except `fetch` is\n * wrapped so static `headers` and `getHeaders` resolution still apply.\n */\n options?: StreamableHTTPClientTransportOptions;\n /** Snapshot of the agent's per-run forwarded headers, captured at run-start. */\n requestHeaders: Record<string, string>;\n /** RunAgentInput for the current run, exposed to the resolver via context. */\n input: RunAgentInput;\n /** Per-run end-user identity from the runtime's `identifyUser`, if set. */\n user?: MCPRuntimeUser;\n}\n\n/**\n * MCP transport for CopilotKit's BuiltInAgent that adds per-call header\n * resolution on top of the standard Streamable HTTP transport.\n *\n * Implements `@ai-sdk/mcp`'s {@link MCPTransport} interface so it can be\n * passed straight to `createMCPClient({ transport })`. Internally delegates\n * to `@modelcontextprotocol/sdk`'s `StreamableHTTPClientTransport` with a\n * wrapped `fetch` that runs the static-header + per-call resolver pipeline\n * before each outbound request.\n */\nexport class CopilotKitMCPTransport implements MCPTransport {\n private readonly inner: StreamableHTTPClientTransport;\n\n constructor(options: CopilotKitMCPTransportOptions) {\n const transportOptions: StreamableHTTPClientTransportOptions = {\n ...options.options,\n fetch: buildWrappedFetch(options),\n };\n this.inner = new StreamableHTTPClientTransport(\n new URL(options.url),\n transportOptions,\n );\n }\n\n get onclose(): (() => void) | undefined {\n return this.inner.onclose;\n }\n set onclose(handler: (() => void) | undefined) {\n this.inner.onclose = handler;\n }\n\n get onerror(): ((error: Error) => void) | undefined {\n return this.inner.onerror;\n }\n set onerror(handler: ((error: Error) => void) | undefined) {\n this.inner.onerror = handler;\n }\n\n get onmessage(): ((message: JSONRPCMessage) => void) | undefined {\n return this.inner.onmessage as\n | ((message: JSONRPCMessage) => void)\n | undefined;\n }\n set onmessage(handler: ((message: JSONRPCMessage) => void) | undefined) {\n this.inner.onmessage = handler as\n | ((message: JSONRPCMessage) => void)\n | undefined;\n }\n\n start(): Promise<void> {\n return this.inner.start();\n }\n\n send(message: JSONRPCMessage): Promise<void> {\n return this.inner.send(message as Parameters<typeof this.inner.send>[0]);\n }\n\n close(): Promise<void> {\n return this.inner.close();\n }\n}\n\nfunction buildWrappedFetch(options: CopilotKitMCPTransportOptions): FetchLike {\n const {\n headers: staticHeaders,\n getHeaders,\n requestHeaders,\n input,\n url: mcpServerUrl,\n user,\n options: transportOptions,\n } = options;\n const baseFetch: FetchLike = transportOptions?.fetch ?? globalThis.fetch;\n\n return async (fetchUrl, init) => {\n // SDK passes a Headers instance via init.headers — start fresh from it so\n // we don't mutate the SDK's object, then layer headers on top via .set()\n // (last write wins).\n const merged = new Headers(init?.headers);\n if (staticHeaders) {\n for (const [key, value] of Object.entries(staticHeaders)) {\n merged.set(key, value);\n }\n }\n if (getHeaders) {\n let resolved: Record<string, string>;\n try {\n resolved = await getHeaders({\n requestHeaders,\n input,\n mcpServerUrl,\n user,\n });\n } catch (err) {\n throw new MCPHeaderResolverError(\n `MCP header resolver for ${mcpServerUrl} threw: ${\n err instanceof Error ? err.message : String(err)\n }`,\n err,\n );\n }\n for (const [key, value] of Object.entries(resolved)) {\n merged.set(key, value);\n }\n }\n return baseFetch(fetchUrl, { ...init, headers: merged });\n };\n}\n"],"mappings":";;;;;;;;;;;AAgDA,IAAa,yBAAb,cAA4C,MAAM;CAChD,YAAY,SAAiB,OAAgB;AAC3C,QAAM,SAAS,EAAE,OAAO,CAAC;AACzB,OAAK,OAAO;;;;;;;;;;;;;AAyChB,IAAa,yBAAb,MAA4D;CAG1D,YAAY,SAAwC;EAClD,MAAM,mBAAyD;GAC7D,GAAG,QAAQ;GACX,OAAO,kBAAkB,QAAQ;GAClC;AACD,OAAK,QAAQ,IAAIA,iFACf,IAAI,IAAI,QAAQ,IAAI,EACpB,iBACD;;CAGH,IAAI,UAAoC;AACtC,SAAO,KAAK,MAAM;;CAEpB,IAAI,QAAQ,SAAmC;AAC7C,OAAK,MAAM,UAAU;;CAGvB,IAAI,UAAgD;AAClD,SAAO,KAAK,MAAM;;CAEpB,IAAI,QAAQ,SAA+C;AACzD,OAAK,MAAM,UAAU;;CAGvB,IAAI,YAA6D;AAC/D,SAAO,KAAK,MAAM;;CAIpB,IAAI,UAAU,SAA0D;AACtE,OAAK,MAAM,YAAY;;CAKzB,QAAuB;AACrB,SAAO,KAAK,MAAM,OAAO;;CAG3B,KAAK,SAAwC;AAC3C,SAAO,KAAK,MAAM,KAAK,QAAiD;;CAG1E,QAAuB;AACrB,SAAO,KAAK,MAAM,OAAO;;;AAI7B,SAAS,kBAAkB,SAAmD;CAC5E,MAAM,EACJ,SAAS,eACT,YACA,gBACA,OACA,KAAK,cACL,MACA,SAAS,qBACP;CACJ,MAAM,YAAuB,kBAAkB,SAAS,WAAW;AAEnE,QAAO,OAAO,UAAU,SAAS;EAI/B,MAAM,SAAS,IAAI,QAAQ,MAAM,QAAQ;AACzC,MAAI,cACF,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,cAAc,CACtD,QAAO,IAAI,KAAK,MAAM;AAG1B,MAAI,YAAY;GACd,IAAI;AACJ,OAAI;AACF,eAAW,MAAM,WAAW;KAC1B;KACA;KACA;KACA;KACD,CAAC;YACK,KAAK;AACZ,UAAM,IAAI,uBACR,2BAA2B,aAAa,UACtC,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,IAElD,IACD;;AAEH,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,CACjD,QAAO,IAAI,KAAK,MAAM;;AAG1B,SAAO,UAAU,UAAU;GAAE,GAAG;GAAM,SAAS;GAAQ,CAAC"}
@@ -1,51 +0,0 @@
1
-
2
- import { RunAgentInput } from "@ag-ui/client";
3
- import { StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
-
5
- //#region src/agent/mcp-transport.d.ts
6
- /**
7
- * The end-user identity resolved by the runtime's `identifyUser` callback for
8
- * the current request. Surfaced on {@link MCPRequestContext} so MCP header
9
- * resolvers can read it without re-doing auth work.
10
- */
11
- interface MCPRuntimeUser {
12
- id: string;
13
- name: string;
14
- }
15
- /**
16
- * Context handed to {@link MCPClientConfigHTTP.getHeaders} on every outbound
17
- * MCP HTTP request. The resolver is invoked fresh per request — initialize,
18
- * tools/list, tools/call, and reconnects — so values it depends on are never
19
- * cached across calls.
20
- */
21
- interface MCPRequestContext {
22
- /**
23
- * Headers forwarded onto the agent for this run. Populated by the runtime's
24
- * `extractForwardableHeaders` (`authorization` + every `x-*` header from the
25
- * incoming HTTP request). Keys are lower-cased.
26
- */
27
- requestHeaders: Record<string, string>;
28
- /** The {@link RunAgentInput} the agent is currently running. */
29
- input: RunAgentInput;
30
- /** URL of the MCP server this request is going to. */
31
- mcpServerUrl: string;
32
- /**
33
- * The end-user identity for this run, resolved by the runtime's
34
- * `identifyUser` callback (only populated when the agent is run via a
35
- * `CopilotRuntime` configured with `identifyUser`). Snapshotted at
36
- * run-start.
37
- */
38
- user?: MCPRuntimeUser;
39
- }
40
- /**
41
- * Thrown when an MCP {@link MCPClientConfigHTTP.getHeaders} resolver throws.
42
- * Wraps the underlying error so `RUN_ERROR` carries clear attribution instead
43
- * of a generic transport failure. The original error is preserved on the
44
- * standard ES2022 `Error.cause` chain.
45
- */
46
- declare class MCPHeaderResolverError extends Error {
47
- constructor(message: string, cause: unknown);
48
- }
49
- //#endregion
50
- export { MCPHeaderResolverError, MCPRequestContext };
51
- //# sourceMappingURL=mcp-transport.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-transport.d.cts","names":[],"sources":["../../src/agent/mcp-transport.ts"],"mappings":";;;;;;AAWA;;;;UAAiB,cAAA;EACf,EAAA;EACA,IAAA;AAAA;;;;;;;UASe,iBAAA;EAQf;;;;;EAFA,cAAA,EAAgB,MAAA;EAWK;EATrB,KAAA,EAAO,aAAA;EAkB2B;EAhBlC,YAAA;EAgB+C;;;;;;EAT/C,IAAA,GAAO,cAAA;AAAA;;;;;;;cASI,sBAAA,SAA+B,KAAA;cAC9B,OAAA,UAAiB,KAAA;AAAA"}
@@ -1,52 +0,0 @@
1
- import "reflect-metadata";
2
- import { RunAgentInput } from "@ag-ui/client";
3
- import "@ai-sdk/mcp";
4
- import { StreamableHTTPClientTransportOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
-
6
- //#region src/agent/mcp-transport.d.ts
7
- /**
8
- * The end-user identity resolved by the runtime's `identifyUser` callback for
9
- * the current request. Surfaced on {@link MCPRequestContext} so MCP header
10
- * resolvers can read it without re-doing auth work.
11
- */
12
- interface MCPRuntimeUser {
13
- id: string;
14
- name: string;
15
- }
16
- /**
17
- * Context handed to {@link MCPClientConfigHTTP.getHeaders} on every outbound
18
- * MCP HTTP request. The resolver is invoked fresh per request — initialize,
19
- * tools/list, tools/call, and reconnects — so values it depends on are never
20
- * cached across calls.
21
- */
22
- interface MCPRequestContext {
23
- /**
24
- * Headers forwarded onto the agent for this run. Populated by the runtime's
25
- * `extractForwardableHeaders` (`authorization` + every `x-*` header from the
26
- * incoming HTTP request). Keys are lower-cased.
27
- */
28
- requestHeaders: Record<string, string>;
29
- /** The {@link RunAgentInput} the agent is currently running. */
30
- input: RunAgentInput;
31
- /** URL of the MCP server this request is going to. */
32
- mcpServerUrl: string;
33
- /**
34
- * The end-user identity for this run, resolved by the runtime's
35
- * `identifyUser` callback (only populated when the agent is run via a
36
- * `CopilotRuntime` configured with `identifyUser`). Snapshotted at
37
- * run-start.
38
- */
39
- user?: MCPRuntimeUser;
40
- }
41
- /**
42
- * Thrown when an MCP {@link MCPClientConfigHTTP.getHeaders} resolver throws.
43
- * Wraps the underlying error so `RUN_ERROR` carries clear attribution instead
44
- * of a generic transport failure. The original error is preserved on the
45
- * standard ES2022 `Error.cause` chain.
46
- */
47
- declare class MCPHeaderResolverError extends Error {
48
- constructor(message: string, cause: unknown);
49
- }
50
- //#endregion
51
- export { MCPHeaderResolverError, MCPRequestContext };
52
- //# sourceMappingURL=mcp-transport.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-transport.d.mts","names":[],"sources":["../../src/agent/mcp-transport.ts"],"mappings":";;;;;;;;AAWA;;;UAAiB,cAAA;EACf,EAAA;EACA,IAAA;AAAA;;;;;;;UASe,iBAAA;EAMC;;;;;EAAhB,cAAA,EAAgB,MAAA;EAWK;EATrB,KAAA,EAAO,aAAA;EAkBI;EAhBX,YAAA;;;;;;;EAOA,IAAA,GAAO,cAAA;AAAA;;;;;;;cASI,sBAAA,SAA+B,KAAA;cAC9B,OAAA,UAAiB,KAAA;AAAA"}