@letta-ai/letta-agent-sdk 0.5.5 → 0.5.7
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/README.md +43 -8
- package/dist/app-server-session.d.ts +4 -0
- package/dist/app-server-session.d.ts.map +1 -1
- package/dist/client-entry.js +120 -8
- package/dist/client-entry.js.map +8 -7
- package/dist/cloud-session.d.ts +4 -0
- package/dist/cloud-session.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17021 -29
- package/dist/index.js.map +11 -8
- package/dist/mcp-runtime.d.ts +17 -0
- package/dist/mcp-runtime.d.ts.map +1 -0
- package/dist/mcp.d.ts +9 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/remote-client-session-core.d.ts +1 -0
- package/dist/remote-client-session-core.d.ts.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/app-server-session.ts +46 -3
- package/src/cloud-session.ts +44 -3
- package/src/index.ts +9 -0
- package/src/mcp-runtime.ts +58 -0
- package/src/mcp.ts +213 -0
- package/src/remote-client-session-core.ts +5 -0
- package/src/types.ts +42 -0
- package/src/validation.ts +31 -0
package/README.md
CHANGED
|
@@ -10,14 +10,6 @@ Build applications with stateful agents powered by the [Letta agent harness](htt
|
|
|
10
10
|
npm install @letta-ai/letta-agent-sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
The `0.4.x` SDK line requires the matching single-socket
|
|
14
|
-
`@letta-ai/letta-code` app-server release. Release `letta-code` first, then
|
|
15
|
-
replace the SDK's package dependency with that published version before
|
|
16
|
-
publishing `0.4.0`; the development branch intentionally does not name an
|
|
17
|
-
unpublished package version.
|
|
18
|
-
|
|
19
|
-
Local execution requires Node.js 22.19 or newer.
|
|
20
|
-
|
|
21
13
|
## Quick start
|
|
22
14
|
|
|
23
15
|
```ts
|
|
@@ -127,6 +119,49 @@ await using session = client.createSession(agentId, {
|
|
|
127
119
|
});
|
|
128
120
|
```
|
|
129
121
|
|
|
122
|
+
Local execution (embedded Letta Code harness / app server) requires Node.js 22.19 or newer.
|
|
123
|
+
|
|
124
|
+
### MCP tools
|
|
125
|
+
|
|
126
|
+
Pass MCP servers by name in session options. The SDK supports local stdio,
|
|
127
|
+
Streamable HTTP, and legacy SSE transports. It namespaces discovered tools as
|
|
128
|
+
`mcp__<server>__<tool>` and exposes them through Letta Code's external-tool
|
|
129
|
+
protocol.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
await using session = client.createSession(agentId, {
|
|
133
|
+
cwd: process.cwd(),
|
|
134
|
+
mcpServers: {
|
|
135
|
+
filesystem: {
|
|
136
|
+
command: "npx",
|
|
137
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()],
|
|
138
|
+
},
|
|
139
|
+
exa: {
|
|
140
|
+
type: "http",
|
|
141
|
+
url: "https://mcp.exa.ai/mcp",
|
|
142
|
+
},
|
|
143
|
+
github: {
|
|
144
|
+
type: "http",
|
|
145
|
+
url: "https://api.githubcopilot.com/mcp/",
|
|
146
|
+
headers: {
|
|
147
|
+
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
allowedTools: ["mcp__filesystem__*", "mcp__exa__*", "mcp__github__list_issues"],
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Connections start concurrently during session initialization. A failed server
|
|
156
|
+
is skipped without dropping healthy servers. OAuth is host-managed, matching
|
|
157
|
+
the Claude Agent SDK: complete OAuth in your application and provide the access
|
|
158
|
+
token through `headers`. The SDK does not open an interactive browser flow.
|
|
159
|
+
|
|
160
|
+
MCP connections run in the Node SDK process and close with the session. This
|
|
161
|
+
includes MCP used by remote and Cloud sessions: stdio servers see the SDK host
|
|
162
|
+
filesystem, not a managed sandbox. MCP is unavailable from the portable
|
|
163
|
+
`@letta-ai/letta-agent-sdk/client` browser and React Native entry point.
|
|
164
|
+
|
|
130
165
|
### Managed Cloud sandbox repositories
|
|
131
166
|
|
|
132
167
|
Cloud sessions can clone up to 10 GitHub repositories into the managed
|
|
@@ -66,12 +66,16 @@ export declare class AppServerSession extends RemoteClientSessionCore {
|
|
|
66
66
|
private readonly remoteOptions;
|
|
67
67
|
private ownedConnection;
|
|
68
68
|
private externalTools;
|
|
69
|
+
private mcpBridge;
|
|
70
|
+
private mcpCleanup;
|
|
69
71
|
private removeExternalToolHandler;
|
|
70
72
|
private removeControlRequestHandler;
|
|
71
73
|
constructor(remoteOptions: AppServerSessionOptions, mode: AppServerSessionMode);
|
|
72
74
|
protected shouldEnableMemfs(options: LettaCodeClientSessionOptions | CreateAgentOptions): boolean;
|
|
73
75
|
protected initializeRuntimeController(): Promise<RuntimeSessionInit>;
|
|
74
76
|
protected onCoreClose(): void;
|
|
77
|
+
protected onCoreDisposed(): Promise<void>;
|
|
78
|
+
private closeMcpBridge;
|
|
75
79
|
private resolveAppServerUrl;
|
|
76
80
|
private startRuntime;
|
|
77
81
|
private buildRuntimeStartCommand;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-server-session.d.ts","sourceRoot":"","sources":["../src/app-server-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,gCAAgC,EAEtC,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"app-server-session.d.ts","sourceRoot":"","sources":["../src/app-server-session.ts"],"names":[],"mappings":"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"}
|
package/dist/client-entry.js
CHANGED
|
@@ -8615,6 +8615,35 @@ function buildCanUseToolContext(request, requestId) {
|
|
|
8615
8615
|
return context;
|
|
8616
8616
|
}
|
|
8617
8617
|
|
|
8618
|
+
// src/mcp-runtime.ts
|
|
8619
|
+
var connector = null;
|
|
8620
|
+
async function connectMcpServers(servers, options = {}) {
|
|
8621
|
+
if (!servers || Object.keys(servers).length === 0) {
|
|
8622
|
+
return { tools: [], close: async () => {
|
|
8623
|
+
return;
|
|
8624
|
+
} };
|
|
8625
|
+
}
|
|
8626
|
+
if (!connector) {
|
|
8627
|
+
throw new Error("MCP servers require the Node package entry '@letta-ai/letta-agent-sdk'; they are not available from '@letta-ai/letta-agent-sdk/client'.");
|
|
8628
|
+
}
|
|
8629
|
+
return connector(servers, options);
|
|
8630
|
+
}
|
|
8631
|
+
function expandMcpToolWildcards(allowedTools, mcpTools) {
|
|
8632
|
+
if (allowedTools === undefined)
|
|
8633
|
+
return;
|
|
8634
|
+
const available = [...mcpTools];
|
|
8635
|
+
const expanded = [];
|
|
8636
|
+
for (const entry of allowedTools) {
|
|
8637
|
+
if (entry.startsWith("mcp__") && entry.endsWith("*")) {
|
|
8638
|
+
const prefix = entry.slice(0, -1);
|
|
8639
|
+
expanded.push(...available.filter((name) => name.startsWith(prefix)));
|
|
8640
|
+
} else {
|
|
8641
|
+
expanded.push(entry);
|
|
8642
|
+
}
|
|
8643
|
+
}
|
|
8644
|
+
return [...new Set(expanded)];
|
|
8645
|
+
}
|
|
8646
|
+
|
|
8618
8647
|
// src/remote-session-protocol.ts
|
|
8619
8648
|
var FAILURE_STOP_REASONS = new Set([
|
|
8620
8649
|
"error",
|
|
@@ -9822,6 +9851,7 @@ class RemoteClientSessionCore {
|
|
|
9822
9851
|
}
|
|
9823
9852
|
async[Symbol.asyncDispose]() {
|
|
9824
9853
|
this.close();
|
|
9854
|
+
await this.onCoreDisposed();
|
|
9825
9855
|
}
|
|
9826
9856
|
async changeDeviceState(updates) {
|
|
9827
9857
|
if (!this.initialized) {
|
|
@@ -9863,6 +9893,7 @@ class RemoteClientSessionCore {
|
|
|
9863
9893
|
async afterRuntimeInitialized() {}
|
|
9864
9894
|
async beforeTurn() {}
|
|
9865
9895
|
onCoreClose() {}
|
|
9896
|
+
async onCoreDisposed() {}
|
|
9866
9897
|
currentOptions() {
|
|
9867
9898
|
return this.mode.options;
|
|
9868
9899
|
}
|
|
@@ -10112,7 +10143,8 @@ function createExternalToolCallHandler(externalTools) {
|
|
|
10112
10143
|
...part.text !== undefined ? { text: part.text } : {},
|
|
10113
10144
|
...part.data !== undefined ? { data: part.data } : {},
|
|
10114
10145
|
...part.mimeType !== undefined ? { mimeType: part.mimeType } : {}
|
|
10115
|
-
}))
|
|
10146
|
+
})),
|
|
10147
|
+
...result.isError === true ? { is_error: true } : {}
|
|
10116
10148
|
};
|
|
10117
10149
|
};
|
|
10118
10150
|
}
|
|
@@ -10403,6 +10435,8 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10403
10435
|
remoteOptions;
|
|
10404
10436
|
ownedConnection = null;
|
|
10405
10437
|
externalTools = new Map;
|
|
10438
|
+
mcpBridge = null;
|
|
10439
|
+
mcpCleanup = Promise.resolve();
|
|
10406
10440
|
removeExternalToolHandler = null;
|
|
10407
10441
|
removeControlRequestHandler = null;
|
|
10408
10442
|
constructor(remoteOptions, mode) {
|
|
@@ -10422,6 +10456,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10422
10456
|
return options.memfs !== false;
|
|
10423
10457
|
}
|
|
10424
10458
|
async initializeRuntimeController() {
|
|
10459
|
+
await this.mcpCleanup;
|
|
10425
10460
|
const url = await this.resolveAppServerUrl();
|
|
10426
10461
|
const client = applyUniqueRequestIds(createAppServerClient({
|
|
10427
10462
|
url,
|
|
@@ -10429,6 +10464,14 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10429
10464
|
...this.remoteOptions.WebSocket ? { WebSocket: this.remoteOptions.WebSocket } : {},
|
|
10430
10465
|
...this.remoteOptions.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.remoteOptions.requestTimeoutMs } : {}
|
|
10431
10466
|
}));
|
|
10467
|
+
const options = this.currentOptions();
|
|
10468
|
+
this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
|
|
10469
|
+
cwd: options.cwd,
|
|
10470
|
+
reservedToolNames: this.externalTools.keys()
|
|
10471
|
+
});
|
|
10472
|
+
for (const tool of this.mcpBridge.tools) {
|
|
10473
|
+
this.externalTools.set(tool.name, tool);
|
|
10474
|
+
}
|
|
10432
10475
|
this.removeControlRequestHandler = registerAppServerControlRequestHandler({
|
|
10433
10476
|
client,
|
|
10434
10477
|
getRuntime: () => this.runtime,
|
|
@@ -10445,12 +10488,15 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10445
10488
|
}
|
|
10446
10489
|
const tools = agentToolNames(response.agent);
|
|
10447
10490
|
const skillSources = this.currentOptions().skillSources;
|
|
10491
|
+
const mcpToolNames = this.mcpBridge?.tools.map((tool) => tool.name) ?? [];
|
|
10492
|
+
const allowedTools = expandMcpToolWildcards(this.currentOptions().allowedTools, mcpToolNames);
|
|
10493
|
+
const availableTools = tools === undefined && mcpToolNames.length === 0 ? undefined : [...tools ?? [], ...mcpToolNames];
|
|
10448
10494
|
return {
|
|
10449
|
-
controller: new AppServerRuntimeController(client, this.remoteOptions,
|
|
10495
|
+
controller: new AppServerRuntimeController(client, this.remoteOptions, allowedTools),
|
|
10450
10496
|
runtime: response.runtime,
|
|
10451
10497
|
model: typeof response.agent?.model === "string" ? response.agent.model : "",
|
|
10452
10498
|
modelSettings: objectRecord(response.agent?.model_settings) ?? null,
|
|
10453
|
-
...
|
|
10499
|
+
...availableTools !== undefined ? { tools: availableTools } : {},
|
|
10454
10500
|
...skillSources !== undefined ? { skillSources: [...skillSources] } : {}
|
|
10455
10501
|
};
|
|
10456
10502
|
} catch (error) {
|
|
@@ -10458,6 +10504,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10458
10504
|
this.removeExternalToolHandler = null;
|
|
10459
10505
|
this.removeControlRequestHandler?.();
|
|
10460
10506
|
this.removeControlRequestHandler = null;
|
|
10507
|
+
await this.closeMcpBridge();
|
|
10461
10508
|
client.close();
|
|
10462
10509
|
throw error;
|
|
10463
10510
|
}
|
|
@@ -10467,9 +10514,20 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10467
10514
|
this.removeExternalToolHandler = null;
|
|
10468
10515
|
this.removeControlRequestHandler?.();
|
|
10469
10516
|
this.removeControlRequestHandler = null;
|
|
10517
|
+
this.mcpCleanup = this.closeMcpBridge();
|
|
10470
10518
|
this.ownedConnection?.close();
|
|
10471
10519
|
this.ownedConnection = null;
|
|
10472
10520
|
}
|
|
10521
|
+
async onCoreDisposed() {
|
|
10522
|
+
await this.mcpCleanup;
|
|
10523
|
+
}
|
|
10524
|
+
closeMcpBridge() {
|
|
10525
|
+
const bridge = this.mcpBridge;
|
|
10526
|
+
this.mcpBridge = null;
|
|
10527
|
+
for (const tool of bridge?.tools ?? [])
|
|
10528
|
+
this.externalTools.delete(tool.name);
|
|
10529
|
+
return bridge?.close() ?? Promise.resolve();
|
|
10530
|
+
}
|
|
10473
10531
|
async resolveAppServerUrl() {
|
|
10474
10532
|
if (this.remoteOptions.url) {
|
|
10475
10533
|
return this.remoteOptions.url;
|
|
@@ -10504,7 +10562,7 @@ class AppServerSession extends RemoteClientSessionCore {
|
|
|
10504
10562
|
if (options.skillSources !== undefined) {
|
|
10505
10563
|
command.skill_sources = [...new Set(options.skillSources)];
|
|
10506
10564
|
}
|
|
10507
|
-
const groups = externalToolGroups(
|
|
10565
|
+
const groups = externalToolGroups([...this.externalTools.values()]);
|
|
10508
10566
|
if (groups)
|
|
10509
10567
|
command.external_tools = groups;
|
|
10510
10568
|
if (this.mode.kind === "create-agent") {
|
|
@@ -11124,6 +11182,8 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11124
11182
|
removeExternalToolHandler = null;
|
|
11125
11183
|
removeControlRequestHandler = null;
|
|
11126
11184
|
externalTools = new Map;
|
|
11185
|
+
mcpBridge = null;
|
|
11186
|
+
mcpCleanup = Promise.resolve();
|
|
11127
11187
|
managedSandbox = null;
|
|
11128
11188
|
sandboxRefreshTimer = null;
|
|
11129
11189
|
sandboxRefreshInFlight = null;
|
|
@@ -11145,6 +11205,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11145
11205
|
this.externalTools = externalToolsByName(tools);
|
|
11146
11206
|
}
|
|
11147
11207
|
async initializeRuntimeController() {
|
|
11208
|
+
await this.mcpCleanup;
|
|
11148
11209
|
const resolved = await this.resolveRuntime();
|
|
11149
11210
|
const connection = await this.resolveConnectionForRuntime(resolved.runtime).catch(async (error) => {
|
|
11150
11211
|
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
@@ -11171,6 +11232,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11171
11232
|
}),
|
|
11172
11233
|
requestTimeoutMs: this.cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
|
|
11173
11234
|
}));
|
|
11235
|
+
const options = this.currentOptions();
|
|
11236
|
+
this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
|
|
11237
|
+
cwd: options.cwd,
|
|
11238
|
+
reservedToolNames: this.externalTools.keys()
|
|
11239
|
+
});
|
|
11240
|
+
for (const tool of this.mcpBridge.tools) {
|
|
11241
|
+
this.externalTools.set(tool.name, tool);
|
|
11242
|
+
}
|
|
11174
11243
|
this.removeControlRequestHandler = registerAppServerControlRequestHandler({
|
|
11175
11244
|
client,
|
|
11176
11245
|
getRuntime: () => this.runtime,
|
|
@@ -11187,14 +11256,17 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11187
11256
|
}
|
|
11188
11257
|
const tools = agentToolNames(response.agent);
|
|
11189
11258
|
const skillSources = this.currentOptions().skillSources;
|
|
11259
|
+
const mcpToolNames = this.mcpBridge?.tools.map((tool) => tool.name) ?? [];
|
|
11260
|
+
const allowedTools = expandMcpToolWildcards(this.currentOptions().allowedTools, mcpToolNames);
|
|
11261
|
+
const availableTools = tools === undefined && mcpToolNames.length === 0 ? undefined : [...tools ?? [], ...mcpToolNames];
|
|
11190
11262
|
return {
|
|
11191
11263
|
controller: new AppServerRuntimeController(client, {
|
|
11192
11264
|
requestTimeoutMs: this.cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
|
|
11193
|
-
},
|
|
11265
|
+
}, allowedTools),
|
|
11194
11266
|
runtime: response.runtime,
|
|
11195
11267
|
model: typeof response.agent?.model === "string" ? response.agent.model : "",
|
|
11196
11268
|
modelSettings: response.agent?.model_settings ?? null,
|
|
11197
|
-
...
|
|
11269
|
+
...availableTools !== undefined ? { tools: availableTools } : {},
|
|
11198
11270
|
...skillSources !== undefined ? { skillSources: [...skillSources] } : {}
|
|
11199
11271
|
};
|
|
11200
11272
|
} catch (error) {
|
|
@@ -11202,6 +11274,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11202
11274
|
this.removeExternalToolHandler = null;
|
|
11203
11275
|
this.removeControlRequestHandler?.();
|
|
11204
11276
|
this.removeControlRequestHandler = null;
|
|
11277
|
+
await this.closeMcpBridge();
|
|
11205
11278
|
client.close();
|
|
11206
11279
|
await this.cleanupManagedSandbox();
|
|
11207
11280
|
await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
|
|
@@ -11228,7 +11301,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11228
11301
|
if (options.skillSources !== undefined) {
|
|
11229
11302
|
command.skill_sources = [...new Set(options.skillSources)];
|
|
11230
11303
|
}
|
|
11231
|
-
const groups = externalToolGroups(
|
|
11304
|
+
const groups = externalToolGroups([...this.externalTools.values()]);
|
|
11232
11305
|
if (groups)
|
|
11233
11306
|
command.external_tools = groups;
|
|
11234
11307
|
return await client.runtimeStart(command);
|
|
@@ -11254,11 +11327,22 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
|
|
|
11254
11327
|
this.removeExternalToolHandler = null;
|
|
11255
11328
|
this.removeControlRequestHandler?.();
|
|
11256
11329
|
this.removeControlRequestHandler = null;
|
|
11330
|
+
this.mcpCleanup = this.closeMcpBridge();
|
|
11257
11331
|
this.cleanupManagedSandbox();
|
|
11258
11332
|
if (this.runtime?.agent_id) {
|
|
11259
11333
|
this.cleanupSessionRepositories(this.runtime.agent_id, this.runtime.conversation_id);
|
|
11260
11334
|
}
|
|
11261
11335
|
}
|
|
11336
|
+
async onCoreDisposed() {
|
|
11337
|
+
await this.mcpCleanup;
|
|
11338
|
+
}
|
|
11339
|
+
closeMcpBridge() {
|
|
11340
|
+
const bridge = this.mcpBridge;
|
|
11341
|
+
this.mcpBridge = null;
|
|
11342
|
+
for (const tool of bridge?.tools ?? [])
|
|
11343
|
+
this.externalTools.delete(tool.name);
|
|
11344
|
+
return bridge?.close() ?? Promise.resolve();
|
|
11345
|
+
}
|
|
11262
11346
|
async resolveRuntime() {
|
|
11263
11347
|
let agentId = this.cloudMode.agentId;
|
|
11264
11348
|
let conversationId = this.cloudMode.conversationId;
|
|
@@ -11779,8 +11863,36 @@ function validateReasoningEffort(value) {
|
|
|
11779
11863
|
throw new Error(`Invalid reasoningEffort '${String(value)}'. Valid values: ${VALID_REASONING_EFFORTS.join(", ")}`);
|
|
11780
11864
|
}
|
|
11781
11865
|
}
|
|
11866
|
+
function validateMcpServers(servers) {
|
|
11867
|
+
if (servers === undefined)
|
|
11868
|
+
return;
|
|
11869
|
+
if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
|
|
11870
|
+
throw new Error("Invalid mcpServers. Expected an object keyed by server name.");
|
|
11871
|
+
}
|
|
11872
|
+
for (const [name, config] of Object.entries(servers)) {
|
|
11873
|
+
if (name.length === 0) {
|
|
11874
|
+
throw new Error("Invalid mcpServers. Server names must be non-empty.");
|
|
11875
|
+
}
|
|
11876
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) {
|
|
11877
|
+
throw new Error(`Invalid MCP server '${name}'. Expected a configuration object.`);
|
|
11878
|
+
}
|
|
11879
|
+
if (config.type === "http" || config.type === "sse") {
|
|
11880
|
+
if (typeof config.url !== "string" || config.url.length === 0) {
|
|
11881
|
+
throw new Error(`Invalid MCP server '${name}'. Expected a non-empty url.`);
|
|
11882
|
+
}
|
|
11883
|
+
continue;
|
|
11884
|
+
}
|
|
11885
|
+
if (config.type !== undefined && config.type !== "stdio") {
|
|
11886
|
+
throw new Error(`Invalid MCP server '${name}' type '${String(config.type)}'. Valid values: stdio, http, sse.`);
|
|
11887
|
+
}
|
|
11888
|
+
if (typeof config.command !== "string" || config.command.length === 0) {
|
|
11889
|
+
throw new Error(`Invalid MCP server '${name}'. Expected a non-empty command.`);
|
|
11890
|
+
}
|
|
11891
|
+
}
|
|
11892
|
+
}
|
|
11782
11893
|
function validateCreateSessionOptions(options) {
|
|
11783
11894
|
validateSkillSources(options.skillSources);
|
|
11895
|
+
validateMcpServers(options.mcpServers);
|
|
11784
11896
|
validateReasoningEffort(options.reasoningEffort);
|
|
11785
11897
|
validateDreamingOptions(options.dreaming);
|
|
11786
11898
|
validateApprovalRecoveryOptions(options);
|
|
@@ -12209,4 +12321,4 @@ export {
|
|
|
12209
12321
|
CloudManagedSandboxExpiredError
|
|
12210
12322
|
};
|
|
12211
12323
|
|
|
12212
|
-
//# debugId=
|
|
12324
|
+
//# debugId=713A28441574387164756E2164756E21
|