@letta-ai/letta-agent-sdk 0.5.4 → 0.5.6

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 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,32 @@ 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 stdio MCP servers as session options. The SDK starts them in the session
127
+ cwd, namespaces their tools as `mcp__<server>__<tool>`, and exposes them through
128
+ Letta Code's external-tool protocol. Servers are closed with the session.
129
+
130
+ ```ts
131
+ await using session = client.createSession(agentId, {
132
+ cwd: process.cwd(),
133
+ mcpServers: [
134
+ {
135
+ name: "filesystem",
136
+ command: "npx",
137
+ args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()],
138
+ },
139
+ ],
140
+ });
141
+ ```
142
+
143
+ MCP stdio processes require the Node package entry; they are not available from
144
+ `@letta-ai/letta-agent-sdk/client` in browser or React Native environments. For
145
+ a simple smoke test, the official `@modelcontextprotocol/server-everything`
146
+ package runs over stdio with `npx -y @modelcontextprotocol/server-everything`.
147
+
130
148
  ### Managed Cloud sandbox repositories
131
149
 
132
150
  Cloud sessions can clone up to 10 GitHub repositories into the managed
@@ -66,6 +66,7 @@ export declare class AppServerSession extends RemoteClientSessionCore {
66
66
  private readonly remoteOptions;
67
67
  private ownedConnection;
68
68
  private externalTools;
69
+ private mcpBridge;
69
70
  private removeExternalToolHandler;
70
71
  private removeControlRequestHandler;
71
72
  constructor(remoteOptions: AppServerSessionOptions, mode: AppServerSessionMode);
@@ -1 +1 @@
1
- {"version":3,"file":"app-server-session.d.ts","sourceRoot":"","sources":["../src/app-server-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-server-session.d.ts","sourceRoot":"","sources":["../src/app-server-session.ts"],"names":[],"mappings":"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"}
@@ -8615,6 +8615,20 @@ 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 || servers.length === 0) {
8622
+ return { tools: [], close: async () => {
8623
+ return;
8624
+ } };
8625
+ }
8626
+ if (!connector) {
8627
+ throw new Error("MCP stdio 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
+
8618
8632
  // src/remote-session-protocol.ts
8619
8633
  var FAILURE_STOP_REASONS = new Set([
8620
8634
  "error",
@@ -9021,6 +9035,7 @@ function normalizeSendMessage(message) {
9021
9035
  class RemoteTurnCoordinator {
9022
9036
  label;
9023
9037
  requestTimeoutMs;
9038
+ autoHandlesToolApprovals;
9024
9039
  onDeviceStatus;
9025
9040
  streamQueue = [];
9026
9041
  streamResolvers = [];
@@ -9034,6 +9049,7 @@ class RemoteTurnCoordinator {
9034
9049
  constructor(config) {
9035
9050
  this.label = config.label;
9036
9051
  this.requestTimeoutMs = config.requestTimeoutMs;
9052
+ this.autoHandlesToolApprovals = config.autoHandlesToolApprovals === true;
9037
9053
  this.onDeviceStatus = config.onDeviceStatus;
9038
9054
  }
9039
9055
  get activeTurnStartedAt() {
@@ -9210,6 +9226,8 @@ class RemoteTurnCoordinator {
9210
9226
  if (!hadTurnEvidence)
9211
9227
  return;
9212
9228
  if (status === "WAITING_ON_APPROVAL") {
9229
+ if (this.autoHandlesToolApprovals)
9230
+ return;
9213
9231
  this.completeActiveTurn({
9214
9232
  runtime: active.runtime,
9215
9233
  stopReason: "requires_approval",
@@ -9447,6 +9465,7 @@ class RemoteClientSessionCore {
9447
9465
  this.turns = new RemoteTurnCoordinator({
9448
9466
  label: config.label,
9449
9467
  requestTimeoutMs: config.requestTimeoutMs,
9468
+ autoHandlesToolApprovals: mode.kind === "session" && typeof mode.options.canUseTool === "function",
9450
9469
  onDeviceStatus: (status) => this.emitDeviceStatus(status)
9451
9470
  });
9452
9471
  }
@@ -10212,37 +10231,72 @@ function runtimeScopeFromMessage(message) {
10212
10231
  }
10213
10232
  return null;
10214
10233
  }
10215
- function registerAppServerControlRequestHandler(config) {
10216
- return config.client.onMessage((rawMessage, channel) => {
10217
- const message = rawMessage;
10218
- if (channel !== "control" || message.type !== "control_request")
10219
- return;
10220
- respondToAppServerControlRequest(config, message).catch(() => {});
10221
- });
10222
- }
10223
- async function respondToAppServerControlRequest(config, message) {
10224
- const runtime = runtimeScopeFromMessage(message) ?? config.getRuntime();
10225
- if (!runtime)
10226
- return;
10227
- const requestId = typeof message.request_id === "string" ? message.request_id : undefined;
10234
+ var MAX_CACHED_TOOL_APPROVALS = 256;
10235
+ function parseToolApprovalRequest(message, fallbackRuntime) {
10236
+ const runtime = runtimeScopeFromMessage(message) ?? fallbackRuntime;
10237
+ const requestId = typeof message.request_id === "string" ? message.request_id : null;
10228
10238
  const request = message.request;
10229
- if (!requestId || !request || typeof request !== "object")
10230
- return;
10239
+ if (!runtime || !requestId || !request || typeof request !== "object")
10240
+ return null;
10231
10241
  const requestRecord = request;
10232
10242
  if (requestRecord.subtype !== "can_use_tool")
10233
- return;
10243
+ return null;
10234
10244
  const toolName = typeof requestRecord.tool_name === "string" ? requestRecord.tool_name : "unknown";
10235
10245
  const toolInput = requestRecord.input && typeof requestRecord.input === "object" && !Array.isArray(requestRecord.input) ? requestRecord.input : {};
10236
- const decision = await resolveAppServerToolApproval(config.getOptions(), toolName, toolInput, buildCanUseToolContext(requestRecord, requestId));
10237
- config.client.input({
10246
+ return {
10247
+ key: JSON.stringify([runtime.agent_id, runtime.conversation_id, requestId]),
10238
10248
  runtime,
10249
+ requestId,
10250
+ toolName,
10251
+ toolInput,
10252
+ context: buildCanUseToolContext(requestRecord, requestId)
10253
+ };
10254
+ }
10255
+ function sendToolApprovalResponse(client, request, decision) {
10256
+ client.input({
10257
+ runtime: request.runtime,
10239
10258
  payload: {
10240
10259
  kind: "approval_response",
10241
- request_id: requestId,
10260
+ request_id: request.requestId,
10242
10261
  decision: toAppServerApprovalDecision(decision)
10243
10262
  }
10244
10263
  });
10245
10264
  }
10265
+ function registerAppServerControlRequestHandler(config) {
10266
+ const approvals = new Map;
10267
+ return config.client.onMessage((rawMessage, channel) => {
10268
+ const message = rawMessage;
10269
+ if (channel !== "control" || message.type !== "control_request")
10270
+ return;
10271
+ const request = parseToolApprovalRequest(message, config.getRuntime());
10272
+ if (!request)
10273
+ return;
10274
+ const cached = approvals.get(request.key);
10275
+ if (cached) {
10276
+ if (cached.sent) {
10277
+ cached.decision.then((decision) => sendToolApprovalResponse(config.client, cached.request, decision)).catch(() => {
10278
+ return;
10279
+ });
10280
+ }
10281
+ return;
10282
+ }
10283
+ if (approvals.size >= MAX_CACHED_TOOL_APPROVALS) {
10284
+ const oldest = approvals.keys().next().value;
10285
+ if (oldest !== undefined)
10286
+ approvals.delete(oldest);
10287
+ }
10288
+ const entry = {
10289
+ decision: resolveAppServerToolApproval(config.getOptions(), request.toolName, request.toolInput, request.context),
10290
+ sent: false,
10291
+ request
10292
+ };
10293
+ approvals.set(request.key, entry);
10294
+ entry.decision.then((decision) => {
10295
+ entry.sent = true;
10296
+ sendToolApprovalResponse(config.client, request, decision);
10297
+ }).catch(() => approvals.delete(request.key));
10298
+ });
10299
+ }
10246
10300
 
10247
10301
  class AppServerRuntimeController {
10248
10302
  client;
@@ -10363,6 +10417,7 @@ class AppServerSession extends RemoteClientSessionCore {
10363
10417
  remoteOptions;
10364
10418
  ownedConnection = null;
10365
10419
  externalTools = new Map;
10420
+ mcpBridge = null;
10366
10421
  removeExternalToolHandler = null;
10367
10422
  removeControlRequestHandler = null;
10368
10423
  constructor(remoteOptions, mode) {
@@ -10389,6 +10444,14 @@ class AppServerSession extends RemoteClientSessionCore {
10389
10444
  ...this.remoteOptions.WebSocket ? { WebSocket: this.remoteOptions.WebSocket } : {},
10390
10445
  ...this.remoteOptions.requestTimeoutMs !== undefined ? { requestTimeoutMs: this.remoteOptions.requestTimeoutMs } : {}
10391
10446
  }));
10447
+ const options = this.currentOptions();
10448
+ this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
10449
+ cwd: options.cwd,
10450
+ reservedToolNames: this.externalTools.keys()
10451
+ });
10452
+ for (const tool of this.mcpBridge.tools) {
10453
+ this.externalTools.set(tool.name, tool);
10454
+ }
10392
10455
  this.removeControlRequestHandler = registerAppServerControlRequestHandler({
10393
10456
  client,
10394
10457
  getRuntime: () => this.runtime,
@@ -10418,6 +10481,8 @@ class AppServerSession extends RemoteClientSessionCore {
10418
10481
  this.removeExternalToolHandler = null;
10419
10482
  this.removeControlRequestHandler?.();
10420
10483
  this.removeControlRequestHandler = null;
10484
+ this.mcpBridge?.close();
10485
+ this.mcpBridge = null;
10421
10486
  client.close();
10422
10487
  throw error;
10423
10488
  }
@@ -10427,6 +10492,8 @@ class AppServerSession extends RemoteClientSessionCore {
10427
10492
  this.removeExternalToolHandler = null;
10428
10493
  this.removeControlRequestHandler?.();
10429
10494
  this.removeControlRequestHandler = null;
10495
+ this.mcpBridge?.close();
10496
+ this.mcpBridge = null;
10430
10497
  this.ownedConnection?.close();
10431
10498
  this.ownedConnection = null;
10432
10499
  }
@@ -10464,7 +10531,7 @@ class AppServerSession extends RemoteClientSessionCore {
10464
10531
  if (options.skillSources !== undefined) {
10465
10532
  command.skill_sources = [...new Set(options.skillSources)];
10466
10533
  }
10467
- const groups = externalToolGroups(options.tools);
10534
+ const groups = externalToolGroups([...this.externalTools.values()]);
10468
10535
  if (groups)
10469
10536
  command.external_tools = groups;
10470
10537
  if (this.mode.kind === "create-agent") {
@@ -11084,6 +11151,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11084
11151
  removeExternalToolHandler = null;
11085
11152
  removeControlRequestHandler = null;
11086
11153
  externalTools = new Map;
11154
+ mcpBridge = null;
11087
11155
  managedSandbox = null;
11088
11156
  sandboxRefreshTimer = null;
11089
11157
  sandboxRefreshInFlight = null;
@@ -11131,6 +11199,14 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11131
11199
  }),
11132
11200
  requestTimeoutMs: this.cloudOptions.requestTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS
11133
11201
  }));
11202
+ const options = this.currentOptions();
11203
+ this.mcpBridge = await connectMcpServers("mcpServers" in options ? options.mcpServers : undefined, {
11204
+ cwd: options.cwd,
11205
+ reservedToolNames: this.externalTools.keys()
11206
+ });
11207
+ for (const tool of this.mcpBridge.tools) {
11208
+ this.externalTools.set(tool.name, tool);
11209
+ }
11134
11210
  this.removeControlRequestHandler = registerAppServerControlRequestHandler({
11135
11211
  client,
11136
11212
  getRuntime: () => this.runtime,
@@ -11162,6 +11238,8 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11162
11238
  this.removeExternalToolHandler = null;
11163
11239
  this.removeControlRequestHandler?.();
11164
11240
  this.removeControlRequestHandler = null;
11241
+ this.mcpBridge?.close();
11242
+ this.mcpBridge = null;
11165
11243
  client.close();
11166
11244
  await this.cleanupManagedSandbox();
11167
11245
  await this.cleanupSessionRepositories(resolved.runtime.agent_id, resolved.runtime.conversation_id);
@@ -11188,7 +11266,7 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11188
11266
  if (options.skillSources !== undefined) {
11189
11267
  command.skill_sources = [...new Set(options.skillSources)];
11190
11268
  }
11191
- const groups = externalToolGroups(options.tools);
11269
+ const groups = externalToolGroups([...this.externalTools.values()]);
11192
11270
  if (groups)
11193
11271
  command.external_tools = groups;
11194
11272
  return await client.runtimeStart(command);
@@ -11214,6 +11292,8 @@ class CloudEnvironmentSession extends RemoteClientSessionCore {
11214
11292
  this.removeExternalToolHandler = null;
11215
11293
  this.removeControlRequestHandler?.();
11216
11294
  this.removeControlRequestHandler = null;
11295
+ this.mcpBridge?.close();
11296
+ this.mcpBridge = null;
11217
11297
  this.cleanupManagedSandbox();
11218
11298
  if (this.runtime?.agent_id) {
11219
11299
  this.cleanupSessionRepositories(this.runtime.agent_id, this.runtime.conversation_id);
@@ -12169,4 +12249,4 @@ export {
12169
12249
  CloudManagedSandboxExpiredError
12170
12250
  };
12171
12251
 
12172
- //# debugId=A7FA3320F5313CB664756E2164756E21
12252
+ //# debugId=6301765BD48499AE64756E2164756E21