@letta-ai/letta-code 0.31.10 → 0.31.11

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/letta.js CHANGED
@@ -5400,7 +5400,7 @@ var package_default;
5400
5400
  var init_package = __esm(() => {
5401
5401
  package_default = {
5402
5402
  name: "@letta-ai/letta-code",
5403
- version: "0.31.10",
5403
+ version: "0.31.11",
5404
5404
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5405
5405
  type: "module",
5406
5406
  packageManager: "bun@1.3.10",
@@ -5781,6 +5781,15 @@ function isLoopbackUrl(value, options = {}) {
5781
5781
  }
5782
5782
 
5783
5783
  // src/backend/api/metadata.ts
5784
+ function getFeedbackClientType(env = process.env) {
5785
+ if (env.LETTA_DESKTOP_MODE === "1") {
5786
+ return "desktop";
5787
+ }
5788
+ if (env.LETTA_RUNTIME_ENVIRONMENT_DEVICE_ID) {
5789
+ return "chat.letta.com";
5790
+ }
5791
+ return "cli";
5792
+ }
5784
5793
  async function getBalanceMetadata() {
5785
5794
  return apiRequest("GET", "/v1/metadata/balance");
5786
5795
  }
@@ -90861,6 +90870,9 @@ function createSharedReminderState() {
90861
90870
  hasSentSecretsInfo: false,
90862
90871
  pendingSecretsInfoRefresh: false,
90863
90872
  lastSentSecretNamesKey: null,
90873
+ hasSentMcpServersInfo: false,
90874
+ lastSentMcpServerNamesKey: null,
90875
+ lastMcpServersFetchedAtMs: null,
90864
90876
  lastNotifiedPermissionMode: null,
90865
90877
  turnCount: 0,
90866
90878
  pendingReflectionTrigger: false,
@@ -90877,6 +90889,8 @@ function markPostCompactionContextRemindersPending(state) {
90877
90889
  state.hasSentSessionContext = false;
90878
90890
  state.pendingSessionContextReason ??= "post_compaction";
90879
90891
  state.hasSentSecretsInfo = false;
90892
+ state.hasSentMcpServersInfo = false;
90893
+ state.lastMcpServersFetchedAtMs = null;
90880
90894
  state.lastNotifiedPermissionMode = null;
90881
90895
  }
90882
90896
  function syncReminderStateFromContextTracker(state, contextTracker) {
@@ -113434,8 +113448,7 @@ var init_skills3 = __esm(() => {
113434
113448
  init_skill_sources();
113435
113449
  LOCAL_AGENT_EXCLUDED_BUNDLED_SKILLS = new Set([
113436
113450
  "image-generation",
113437
- "managing-shared-memory",
113438
- "using-cloud-mcp"
113451
+ "managing-shared-memory"
113439
113452
  ]);
113440
113453
  PROJECT_SKILLS_DIR = join24(".agents", "skills");
113441
113454
  GLOBAL_SKILLS_DIR = join24(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
@@ -185677,6 +185690,8 @@ function buildChannelFeedbackPayload(submission) {
185677
185690
  return withDefinedValues2({
185678
185691
  message: submission.message,
185679
185692
  feature: CHANNEL_FEEDBACK_FEATURE,
185693
+ submission_source: "slash_command",
185694
+ client_type: process.env.LETTA_DESKTOP_MODE === "1" ? "desktop" : "cli",
185680
185695
  version: getVersion(),
185681
185696
  platform: process.platform,
185682
185697
  channel: submission.channel,
@@ -199431,330 +199446,6 @@ var init_channels = __esm(() => {
199431
199446
  };
199432
199447
  });
199433
199448
 
199434
- // src/backend/api/mcp-servers.ts
199435
- function getString(record3, key2) {
199436
- const value = record3[key2];
199437
- return typeof value === "string" ? value : null;
199438
- }
199439
- function parseAgentConnectedMcpServer(value) {
199440
- if (!isRecord(value)) {
199441
- return null;
199442
- }
199443
- const id2 = getString(value, "id");
199444
- const serverName = getString(value, "server_name");
199445
- const serverType = getString(value, "mcp_server_type");
199446
- if (!id2 || !serverName || !serverType) {
199447
- return null;
199448
- }
199449
- const target2 = getString(value, "server_url") ?? [
199450
- getString(value, "command"),
199451
- ...Array.isArray(value.args) ? value.args : []
199452
- ].filter((item) => typeof item === "string").join(" ");
199453
- return { id: id2, serverName, serverType, target: target2 };
199454
- }
199455
- function parseAgentConnectedMcpTool(value) {
199456
- if (!isRecord(value)) {
199457
- return null;
199458
- }
199459
- const id2 = getString(value, "id");
199460
- const name = getString(value, "name");
199461
- if (!id2 || !name) {
199462
- return null;
199463
- }
199464
- const description = getString(value, "description");
199465
- return { id: id2, name, description };
199466
- }
199467
- function parseAgentMcpToolRunResult(value) {
199468
- if (!isRecord(value)) {
199469
- throw new Error("MCP tool run returned an invalid response");
199470
- }
199471
- const status = getString(value, "status") ?? "unknown";
199472
- return {
199473
- status,
199474
- funcReturn: value.func_return,
199475
- stdout: value.stdout,
199476
- stderr: value.stderr
199477
- };
199478
- }
199479
- function withTimeout(promise, timeoutMs, label) {
199480
- let timer;
199481
- const timeout = new Promise((_4, reject2) => {
199482
- timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
199483
- });
199484
- return Promise.race([promise, timeout]).finally(() => {
199485
- if (timer !== undefined)
199486
- clearTimeout(timer);
199487
- });
199488
- }
199489
- function listServerMcpServers(client, timeoutMs = 1e4) {
199490
- return withTimeout(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
199491
- }
199492
- async function listAgentConnectedMcpServers(client, agentId, timeoutMs = 1e4) {
199493
- const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent-connected MCP servers");
199494
- if (!Array.isArray(result2)) {
199495
- return [];
199496
- }
199497
- return result2.map(parseAgentConnectedMcpServer).filter((server2) => server2 !== null);
199498
- }
199499
- async function listAgentConnectedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
199500
- const result2 = await withTimeout(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent-connected MCP server tools");
199501
- if (!Array.isArray(result2)) {
199502
- return [];
199503
- }
199504
- return result2.map(parseAgentConnectedMcpTool).filter((tool) => tool !== null);
199505
- }
199506
- async function runAgentConnectedMcpTool(params) {
199507
- const result2 = await withTimeout(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { args: params.args }), params.timeoutMs ?? 60000, "Running agent-connected MCP tool");
199508
- return parseAgentMcpToolRunResult(result2);
199509
- }
199510
- async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
199511
- const result2 = await withTimeout(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
199512
- if (!Array.isArray(result2))
199513
- return [];
199514
- return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
199515
- }
199516
- async function loadServerMcpEntries(client, timeoutMs = 15000) {
199517
- const servers = await listServerMcpServers(client, timeoutMs);
199518
- return Promise.all(servers.map(async (server2) => {
199519
- try {
199520
- const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
199521
- return { server: server2, tools };
199522
- } catch (cause) {
199523
- return {
199524
- server: server2,
199525
- tools: [],
199526
- toolsError: cause instanceof Error ? cause.message : String(cause)
199527
- };
199528
- }
199529
- }));
199530
- }
199531
- function parseMcpMetadata(tool) {
199532
- const metadata = tool.metadata_;
199533
- const mcp = metadata?.mcp;
199534
- if (typeof mcp !== "object" || mcp === null)
199535
- return null;
199536
- const { server_id, server_name } = mcp;
199537
- return {
199538
- ...typeof server_id === "string" && { serverId: server_id },
199539
- ...typeof server_name === "string" && { serverName: server_name }
199540
- };
199541
- }
199542
- async function listAgentMcpAttachments(client, agentId) {
199543
- const attachments = [];
199544
- for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
199545
- if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
199546
- continue;
199547
- attachments.push({
199548
- toolId: tool.id,
199549
- toolName: tool.name,
199550
- ...parseMcpMetadata(tool)
199551
- });
199552
- }
199553
- return attachments;
199554
- }
199555
- function attachmentsForEntry(entry, attachments) {
199556
- return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
199557
- }
199558
- function attachedToolNamesForEntry(entry, attachments) {
199559
- return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
199560
- }
199561
- async function registerServerMcpTool(client, serverName, toolName) {
199562
- const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
199563
- if (typeof result2?.id !== "string") {
199564
- throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
199565
- }
199566
- return { id: result2.id };
199567
- }
199568
- async function attachServerMcpTools(client, agentId, serverName, toolNames) {
199569
- await Promise.all(toolNames.map(async (toolName) => {
199570
- const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
199571
- await client.agents.tools.attach(id2, { agent_id: agentId });
199572
- }));
199573
- }
199574
- async function detachServerMcpTools(client, agentId, toolIds) {
199575
- await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
199576
- }
199577
- function refreshServerMcpServer(client, mcpServerId, agentId) {
199578
- return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
199579
- }
199580
- function planServerMcpToggle(entry, attachments) {
199581
- const attached = attachmentsForEntry(entry, attachments);
199582
- if (attached.length > 0) {
199583
- return {
199584
- action: "detach",
199585
- toolIds: attached.map((attachment) => attachment.toolId)
199586
- };
199587
- }
199588
- return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
199589
- }
199590
- function describeServerMcpTarget(server2) {
199591
- if ("server_url" in server2 && server2.server_url) {
199592
- return server2.server_url;
199593
- }
199594
- if ("command" in server2 && server2.command) {
199595
- return [server2.command, ...server2.args ?? []].join(" ");
199596
- }
199597
- return "";
199598
- }
199599
- var init_mcp_servers2 = () => {};
199600
-
199601
- // src/cli/subcommands/cloud-mcp.ts
199602
- import { parseArgs as parseArgs4 } from "node:util";
199603
- function printUsage4(stdout = console.log) {
199604
- stdout(`
199605
- Usage:
199606
- letta cloud-mcp list [--agent <id>]
199607
- letta cloud-mcp tools <mcp-server-id> [--agent <id>]
199608
- letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]
199609
-
199610
- Actions:
199611
- list List MCP servers connected to the agent
199612
- tools List registered tools for one connected MCP server
199613
- run Run one registered MCP tool through the agent-scoped server route
199614
-
199615
- Aliases:
199616
- list-servers, list_servers Alias for list
199617
- list-tools, list_tools Alias for tools
199618
- call, run-tool, run_tool Alias for run
199619
-
199620
- Options:
199621
- --agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
199622
- --agent-id <id> Alias for --agent
199623
- --args '<json>' JSON object passed as MCP tool arguments for run
199624
- -h, --help Show this help
199625
-
199626
- Notes:
199627
- - Output is JSON only.
199628
- - Requires a signed-in Letta Cloud agent with server-side MCP support.
199629
- - Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
199630
- `.trim());
199631
- }
199632
- function parseCloudMcpArgs(argv) {
199633
- return parseArgs4({
199634
- args: argv,
199635
- options: {
199636
- help: { type: "boolean", short: "h" },
199637
- agent: { type: "string" },
199638
- "agent-id": { type: "string" },
199639
- args: { type: "string" }
199640
- },
199641
- strict: true,
199642
- allowPositionals: true
199643
- });
199644
- }
199645
- function stringValue3(value) {
199646
- return typeof value === "string" ? value : undefined;
199647
- }
199648
- function resolveCloudMcpAgentId(agent, agentId, env4 = process.env) {
199649
- return (agent || agentId || env4.LETTA_AGENT_ID || env4.AGENT_ID || "").trim();
199650
- }
199651
- function parseToolArgs(value) {
199652
- const raw2 = stringValue3(value);
199653
- if (!raw2) {
199654
- return {};
199655
- }
199656
- let parsed;
199657
- try {
199658
- parsed = JSON.parse(raw2);
199659
- } catch (error4) {
199660
- const message = error4 instanceof Error ? error4.message : String(error4);
199661
- throw new Error(`Invalid --args JSON: ${message}`);
199662
- }
199663
- if (!isRecord(parsed)) {
199664
- throw new Error("Invalid --args JSON: expected a JSON object");
199665
- }
199666
- return parsed;
199667
- }
199668
- function printJson(stdout, result2) {
199669
- stdout(JSON.stringify(result2, null, 2));
199670
- }
199671
- async function defaultGetClient() {
199672
- const client = await getClient();
199673
- return client;
199674
- }
199675
- async function runCloudMcpSubcommand(argv, deps = {}) {
199676
- const stdout = deps.stdout ?? console.log;
199677
- const stderr = deps.stderr ?? console.error;
199678
- let parsed;
199679
- try {
199680
- parsed = parseCloudMcpArgs(argv);
199681
- } catch (error4) {
199682
- const message = error4 instanceof Error ? error4.message : String(error4);
199683
- stderr(`Error: ${message}`);
199684
- printUsage4(stdout);
199685
- return 1;
199686
- }
199687
- const [action3, mcpServerId, toolId] = parsed.positionals;
199688
- if (parsed.values.help || !action3 || action3 === "help") {
199689
- printUsage4(stdout);
199690
- return 0;
199691
- }
199692
- const isAvailable = deps.isServerSideMcpAvailable ?? (() => getBackend().capabilities.serverSideToolManagement);
199693
- if (!isAvailable()) {
199694
- stderr("Server-side MCP requires a signed-in Letta Cloud agent; the local backend does not support it.");
199695
- return 1;
199696
- }
199697
- const agentId = resolveCloudMcpAgentId(stringValue3(parsed.values.agent), stringValue3(parsed.values["agent-id"]));
199698
- if (!agentId) {
199699
- stderr("Agent id required: pass --agent <id> or set LETTA_AGENT_ID/AGENT_ID.");
199700
- return 1;
199701
- }
199702
- await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
199703
- const client = await (deps.getClient ?? defaultGetClient)();
199704
- try {
199705
- if (action3 === "list" || action3 === "list-servers" || action3 === "list_servers") {
199706
- printJson(stdout, {
199707
- agent_id: agentId,
199708
- servers: await listAgentConnectedMcpServers(client, agentId)
199709
- });
199710
- return 0;
199711
- }
199712
- if (action3 === "tools" || action3 === "list-tools" || action3 === "list_tools") {
199713
- if (!mcpServerId) {
199714
- stderr("Usage: letta cloud-mcp tools <mcp-server-id> [--agent <id>]");
199715
- return 1;
199716
- }
199717
- printJson(stdout, {
199718
- agent_id: agentId,
199719
- mcp_server_id: mcpServerId,
199720
- tools: await listAgentConnectedMcpTools(client, agentId, mcpServerId)
199721
- });
199722
- return 0;
199723
- }
199724
- if (action3 === "run" || action3 === "call" || action3 === "run-tool" || action3 === "run_tool") {
199725
- if (!mcpServerId || !toolId) {
199726
- stderr("Usage: letta cloud-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]");
199727
- return 1;
199728
- }
199729
- printJson(stdout, {
199730
- agent_id: agentId,
199731
- mcp_server_id: mcpServerId,
199732
- tool_id: toolId,
199733
- result: await runAgentConnectedMcpTool({
199734
- client,
199735
- agentId,
199736
- mcpServerId,
199737
- toolId,
199738
- args: parseToolArgs(parsed.values.args)
199739
- })
199740
- });
199741
- return 0;
199742
- }
199743
- stderr(`Unknown cloud-mcp action: ${action3}`);
199744
- printUsage4(stdout);
199745
- return 1;
199746
- } catch (error4) {
199747
- stderr(error4 instanceof Error ? error4.message : String(error4));
199748
- return 1;
199749
- }
199750
- }
199751
- var init_cloud_mcp = __esm(() => {
199752
- init_backend2();
199753
- init_client2();
199754
- init_mcp_servers2();
199755
- init_settings_manager();
199756
- });
199757
-
199758
199449
  // src/auth/openai-oauth.ts
199759
199450
  import http3 from "node:http";
199760
199451
  function renderOAuthPage(options) {
@@ -200878,7 +200569,7 @@ var init_connect_normalize = __esm(() => {
200878
200569
  // src/cli/subcommands/connect.ts
200879
200570
  import { createInterface as createInterface6 } from "node:readline/promises";
200880
200571
  import { Writable } from "node:stream";
200881
- import { parseArgs as parseArgs5 } from "node:util";
200572
+ import { parseArgs as parseArgs4 } from "node:util";
200882
200573
  function readStringOption(value) {
200883
200574
  if (typeof value === "string") {
200884
200575
  return value;
@@ -200970,7 +200661,7 @@ async function runConnectSubcommand(argv, deps = {}) {
200970
200661
  const io = { ...DEFAULT_DEPS2, ...deps };
200971
200662
  let parsed;
200972
200663
  try {
200973
- parsed = parseArgs5({
200664
+ parsed = parseArgs4({
200974
200665
  args: argv,
200975
200666
  options: CONNECT_OPTIONS,
200976
200667
  strict: true,
@@ -210180,8 +209871,8 @@ var init_cron_task_ref = __esm(async () => {
210180
209871
  });
210181
209872
 
210182
209873
  // src/cli/subcommands/cron.ts
210183
- import { parseArgs as parseArgs6 } from "node:util";
210184
- function printUsage5() {
209874
+ import { parseArgs as parseArgs5 } from "node:util";
209875
+ function printUsage4() {
210185
209876
  console.log(`
210186
209877
  Usage:
210187
209878
  letta cron add --prompt <text> --every <interval> [options]
@@ -210235,7 +209926,7 @@ Output is JSON.
210235
209926
  `.trim());
210236
209927
  }
210237
209928
  function parseCronArgs(argv) {
210238
- return parseArgs6({
209929
+ return parseArgs5({
210239
209930
  args: argv,
210240
209931
  options: CRON_OPTIONS,
210241
209932
  strict: true,
@@ -210791,12 +210482,12 @@ async function runCronSubcommand(argv) {
210791
210482
  parsed = parseCronArgs(argv);
210792
210483
  } catch (err) {
210793
210484
  console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
210794
- printUsage5();
210485
+ printUsage4();
210795
210486
  return 1;
210796
210487
  }
210797
210488
  const [action3] = parsed.positionals;
210798
210489
  if (parsed.values.help || !action3 || action3 === "help") {
210799
- printUsage5();
210490
+ printUsage4();
210800
210491
  return 0;
210801
210492
  }
210802
210493
  switch (action3) {
@@ -210813,7 +210504,7 @@ async function runCronSubcommand(argv) {
210813
210504
  return handleDelete(parsed.values, parsed.positionals);
210814
210505
  default:
210815
210506
  console.error(`Unknown action: ${action3}`);
210816
- printUsage5();
210507
+ printUsage4();
210817
210508
  return 1;
210818
210509
  }
210819
210510
  }
@@ -210849,8 +210540,8 @@ var init_cron2 = __esm(async () => {
210849
210540
  });
210850
210541
 
210851
210542
  // src/cli/subcommands/environments.ts
210852
- import { parseArgs as parseArgs7 } from "node:util";
210853
- function printUsage6() {
210543
+ import { parseArgs as parseArgs6 } from "node:util";
210544
+ function printUsage5() {
210854
210545
  console.log(`
210855
210546
  Usage:
210856
210547
  letta environments list [options]
@@ -210918,7 +210609,7 @@ function scoreCurrentEnvironment(environment2, options) {
210918
210609
  return score;
210919
210610
  }
210920
210611
  function parseEnvironmentsArgs(argv) {
210921
- return parseArgs7({
210612
+ return parseArgs6({
210922
210613
  args: argv,
210923
210614
  options: ENVIRONMENTS_OPTIONS,
210924
210615
  strict: true,
@@ -210932,17 +210623,17 @@ async function runEnvironmentsSubcommand(argv, deps = {}) {
210932
210623
  } catch (error4) {
210933
210624
  const message = error4 instanceof Error ? error4.message : String(error4);
210934
210625
  console.error(`Error: ${message}`);
210935
- printUsage6();
210626
+ printUsage5();
210936
210627
  return 1;
210937
210628
  }
210938
210629
  const [action3] = parsed.positionals;
210939
210630
  if (parsed.values.help || !action3 || action3 === "help") {
210940
- printUsage6();
210631
+ printUsage5();
210941
210632
  return 0;
210942
210633
  }
210943
210634
  if (action3 !== "list" && action3 !== "current") {
210944
210635
  console.error(`Unknown action: ${action3}`);
210945
- printUsage6();
210636
+ printUsage5();
210946
210637
  return 1;
210947
210638
  }
210948
210639
  await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
@@ -211004,8 +210695,8 @@ var init_environments3 = __esm(() => {
211004
210695
  });
211005
210696
 
211006
210697
  // src/cli/subcommands/feedback.ts
211007
- import { parseArgs as parseArgs8 } from "node:util";
211008
- function printUsage7(stdout = console.log) {
210698
+ import { parseArgs as parseArgs7 } from "node:util";
210699
+ function printUsage6(stdout = console.log) {
211009
210700
  stdout(`
211010
210701
  Usage:
211011
210702
  letta feedback --message <text>
@@ -211023,7 +210714,7 @@ async function runFeedbackSubcommand(argv, deps = {}) {
211023
210714
  const stderr = deps.stderr ?? console.error;
211024
210715
  let parsed;
211025
210716
  try {
211026
- parsed = parseArgs8({
210717
+ parsed = parseArgs7({
211027
210718
  args: argv,
211028
210719
  options: {
211029
210720
  help: { type: "boolean", short: "h" },
@@ -211034,11 +210725,11 @@ async function runFeedbackSubcommand(argv, deps = {}) {
211034
210725
  });
211035
210726
  } catch (error4) {
211036
210727
  stderr(error4 instanceof Error ? error4.message : String(error4));
211037
- printUsage7(stdout);
210728
+ printUsage6(stdout);
211038
210729
  return 1;
211039
210730
  }
211040
210731
  if (parsed.values.help) {
211041
- printUsage7(stdout);
210732
+ printUsage6(stdout);
211042
210733
  return 0;
211043
210734
  }
211044
210735
  const message = typeof parsed.values.message === "string" ? parsed.values.message.trim() : "";
@@ -211061,6 +210752,8 @@ async function runFeedbackSubcommand(argv, deps = {}) {
211061
210752
  await (deps.submitFeedback ?? submitFeedbackMetadata)(apiKey, (deps.getDeviceId ?? (() => settingsManager.getOrCreateDeviceId()))(), {
211062
210753
  message,
211063
210754
  feature: "letta-code-agent-feedback",
210755
+ submission_source: "agent_skill",
210756
+ client_type: (deps.getClientType ?? getFeedbackClientType)(),
211064
210757
  version: getVersion(),
211065
210758
  platform: process.platform,
211066
210759
  agent_id: agentId || undefined,
@@ -238784,9 +238477,9 @@ ${lanes.join(`
238784
238477
  function isJsonEqual(a2, b3) {
238785
238478
  return a2 === b3 || typeof a2 === "object" && a2 !== null && typeof b3 === "object" && b3 !== null && equalOwnProperties(a2, b3, isJsonEqual);
238786
238479
  }
238787
- function parsePseudoBigInt(stringValue4) {
238480
+ function parsePseudoBigInt(stringValue3) {
238788
238481
  let log2Base;
238789
- switch (stringValue4.charCodeAt(1)) {
238482
+ switch (stringValue3.charCodeAt(1)) {
238790
238483
  case 98:
238791
238484
  case 66:
238792
238485
  log2Base = 1;
@@ -238800,19 +238493,19 @@ ${lanes.join(`
238800
238493
  log2Base = 4;
238801
238494
  break;
238802
238495
  default:
238803
- const nIndex = stringValue4.length - 1;
238496
+ const nIndex = stringValue3.length - 1;
238804
238497
  let nonZeroStart = 0;
238805
- while (stringValue4.charCodeAt(nonZeroStart) === 48) {
238498
+ while (stringValue3.charCodeAt(nonZeroStart) === 48) {
238806
238499
  nonZeroStart++;
238807
238500
  }
238808
- return stringValue4.slice(nonZeroStart, nIndex) || "0";
238501
+ return stringValue3.slice(nonZeroStart, nIndex) || "0";
238809
238502
  }
238810
- const startIndex = 2, endIndex = stringValue4.length - 1;
238503
+ const startIndex = 2, endIndex = stringValue3.length - 1;
238811
238504
  const bitsNeeded = (endIndex - startIndex) * log2Base;
238812
238505
  const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
238813
238506
  for (let i4 = endIndex - 1, bitOffset = 0;i4 >= startIndex; i4--, bitOffset += log2Base) {
238814
238507
  const segment = bitOffset >>> 4;
238815
- const digitChar = stringValue4.charCodeAt(i4);
238508
+ const digitChar = stringValue3.charCodeAt(i4);
238816
238509
  const digit = digitChar <= 57 ? digitChar - 48 : 10 + digitChar - (digitChar <= 70 ? 65 : 97);
238817
238510
  const shiftedDigit = digit << (bitOffset & 15);
238818
238511
  segments[segment] |= shiftedDigit;
@@ -391876,7 +391569,7 @@ function toRunsArray(listResponse) {
391876
391569
  }
391877
391570
  return [];
391878
391571
  }
391879
- function withTimeout2(promise, timeoutMs, timeoutMessage) {
391572
+ function withTimeout(promise, timeoutMs, timeoutMessage) {
391880
391573
  return new Promise((resolve34, reject2) => {
391881
391574
  const timer = setTimeout(() => reject2(new Error(timeoutMessage)), timeoutMs);
391882
391575
  promise.then((value) => {
@@ -391890,7 +391583,7 @@ function withTimeout2(promise, timeoutMs, timeoutMessage) {
391890
391583
  }
391891
391584
  async function discoverFallbackRunIdWithTimeout(ctx) {
391892
391585
  const client = await getClient();
391893
- return withTimeout2(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
391586
+ return withTimeout(discoverFallbackRunIdForResume(client, ctx), FALLBACK_RUN_DISCOVERY_TIMEOUT_MS, `Fallback run discovery timed out after ${FALLBACK_RUN_DISCOVERY_TIMEOUT_MS}ms`);
391894
391587
  }
391895
391588
  async function discoverFallbackRunIdForResume(client, ctx) {
391896
391589
  const statuses = ["running"];
@@ -392627,7 +392320,7 @@ function formatMissingRequiredArgsReason(toolName, parsedArgs, missingRequiredAr
392627
392320
  }
392628
392321
  return base2;
392629
392322
  }
392630
- function parseToolArgs2(rawArgs) {
392323
+ function parseToolArgs(rawArgs) {
392631
392324
  const raw2 = rawArgs ?? "";
392632
392325
  const trimmed = raw2.trim();
392633
392326
  if (!trimmed) {
@@ -392672,7 +392365,7 @@ async function classifyApprovals(approvals, opts = {}) {
392672
392365
  });
392673
392366
  continue;
392674
392367
  }
392675
- const argsParse = parseToolArgs2(approval.toolArgs);
392368
+ const argsParse = parseToolArgs(approval.toolArgs);
392676
392369
  const parsedArgs = argsParse.parsedArgs;
392677
392370
  if (argsParse.parseFailed) {
392678
392371
  debugWarn("approval-classification", `Tool call ${approval.toolCallId} (${toolName}) had unparseable arguments ` + `(${argsParse.rawLength} chars); treating as empty`);
@@ -403564,6 +403257,16 @@ var init_catalog = __esm(() => {
403564
403257
  "listen"
403565
403258
  ]
403566
403259
  },
403260
+ {
403261
+ id: "mcp-servers-info",
403262
+ description: "MCP servers with tools available through letta mcp",
403263
+ modes: [
403264
+ "interactive",
403265
+ "headless-one-shot",
403266
+ "headless-bidirectional",
403267
+ "listen"
403268
+ ]
403269
+ },
403567
403270
  {
403568
403271
  id: "permission-mode",
403569
403272
  description: "Permission mode reminder",
@@ -403599,6 +403302,167 @@ var init_catalog = __esm(() => {
403599
403302
  SHARED_REMINDER_BY_ID = new Map(SHARED_REMINDER_CATALOG.map((entry) => [entry.id, entry]));
403600
403303
  });
403601
403304
 
403305
+ // src/backend/api/unified-mcp.ts
403306
+ var exports_unified_mcp = {};
403307
+ __export(exports_unified_mcp, {
403308
+ searchUnifiedMcpTools: () => searchUnifiedMcpTools,
403309
+ runUnifiedMcpTool: () => runUnifiedMcpTool,
403310
+ listUnifiedMcpTools: () => listUnifiedMcpTools,
403311
+ listUnifiedMcpServers: () => listUnifiedMcpServers
403312
+ });
403313
+ function stringField2(value, key2) {
403314
+ return typeof value[key2] === "string" ? value[key2] : null;
403315
+ }
403316
+ function recordField(value, ...names2) {
403317
+ for (const name of names2) {
403318
+ const field = value[name];
403319
+ if (isRecord(field))
403320
+ return field;
403321
+ }
403322
+ return;
403323
+ }
403324
+ function parseServer(value, registered) {
403325
+ if (!isRecord(value))
403326
+ return null;
403327
+ const id2 = stringField2(value, "id");
403328
+ const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
403329
+ const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
403330
+ if (!id2 || !serverName)
403331
+ return null;
403332
+ const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
403333
+ const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
403334
+ const argsValue = value.args ?? registered?.args;
403335
+ const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
403336
+ const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
403337
+ return {
403338
+ id: id2,
403339
+ serverName,
403340
+ serverType,
403341
+ target: target2,
403342
+ ...serverUrl ? { serverUrl } : {},
403343
+ ...command ? { command, args } : {}
403344
+ };
403345
+ }
403346
+ function parseTool(value) {
403347
+ if (!isRecord(value))
403348
+ return null;
403349
+ const id2 = stringField2(value, "id");
403350
+ const name = stringField2(value, "name");
403351
+ if (!id2 || !name)
403352
+ return null;
403353
+ const description = stringField2(value, "description");
403354
+ const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
403355
+ const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
403356
+ const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
403357
+ const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
403358
+ const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
403359
+ const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
403360
+ const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
403361
+ const iconsValue = value.icons ?? jsonSchema.icons;
403362
+ const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
403363
+ return {
403364
+ id: id2,
403365
+ name,
403366
+ ...title ? { title } : {},
403367
+ description,
403368
+ inputSchema,
403369
+ ...outputSchema ? { outputSchema } : {},
403370
+ ...annotations ? { annotations } : {},
403371
+ ...execution ? { execution } : {},
403372
+ ...meta ? { _meta: meta } : {},
403373
+ ...icons ? { icons } : {}
403374
+ };
403375
+ }
403376
+ function parseRunResult(value) {
403377
+ if (!isRecord(value))
403378
+ throw new Error("Invalid MCP tool run response");
403379
+ return {
403380
+ status: stringField2(value, "status") ?? "unknown",
403381
+ funcReturn: value.func_return,
403382
+ stdout: value.stdout,
403383
+ stderr: value.stderr
403384
+ };
403385
+ }
403386
+ function parseSearchResult(value) {
403387
+ if (!isRecord(value) || !isRecord(value.tool))
403388
+ return null;
403389
+ const toolId = stringField2(value.tool, "id");
403390
+ const jsonSchema = value.tool.json_schema;
403391
+ const score = value.combined_score;
403392
+ if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
403393
+ return null;
403394
+ }
403395
+ return { toolId, jsonSchema, score };
403396
+ }
403397
+ async function withTimeout2(promise, timeoutMs, operation) {
403398
+ let timer;
403399
+ try {
403400
+ return await Promise.race([
403401
+ promise,
403402
+ new Promise((_resolve, reject2) => {
403403
+ timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
403404
+ })
403405
+ ]);
403406
+ } finally {
403407
+ if (timer)
403408
+ clearTimeout(timer);
403409
+ }
403410
+ }
403411
+ async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
403412
+ const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
403413
+ if (!Array.isArray(value))
403414
+ return [];
403415
+ const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
403416
+ const registeredById = new Map;
403417
+ if (needsEnrichment && client.mcpServers) {
403418
+ try {
403419
+ const registered = await withTimeout2(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
403420
+ for (const item of registered) {
403421
+ if (!isRecord(item))
403422
+ continue;
403423
+ const id2 = stringField2(item, "id");
403424
+ if (id2)
403425
+ registeredById.set(id2, item);
403426
+ }
403427
+ } catch {}
403428
+ }
403429
+ return value.map((item) => {
403430
+ const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
403431
+ return parseServer(item, registered);
403432
+ }).filter((server2) => server2 !== null);
403433
+ }
403434
+ async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
403435
+ const value = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
403436
+ if (!Array.isArray(value))
403437
+ return [];
403438
+ return value.map(parseTool).filter((tool) => tool !== null);
403439
+ }
403440
+ async function searchUnifiedMcpTools(params) {
403441
+ const value = await withTimeout2(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
403442
+ body: {
403443
+ query: params.query,
403444
+ search_mode: params.searchMode,
403445
+ limit: params.limit
403446
+ }
403447
+ }), params.timeoutMs ?? 60000, "Searching agent MCP tools");
403448
+ if (!Array.isArray(value)) {
403449
+ throw new Error("Invalid MCP tool search response");
403450
+ }
403451
+ const results = [];
403452
+ for (const item of value) {
403453
+ const result2 = parseSearchResult(item);
403454
+ if (!result2)
403455
+ throw new Error("Invalid MCP tool search result");
403456
+ results.push(result2);
403457
+ }
403458
+ return results;
403459
+ }
403460
+ async function runUnifiedMcpTool(params) {
403461
+ const value = await withTimeout2(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { body: { args: params.args } }), params.timeoutMs ?? 60000, "Running agent MCP tool");
403462
+ return parseRunResult(value);
403463
+ }
403464
+ var init_unified_mcp = () => {};
403465
+
403602
403466
  // src/reminders/engine.ts
403603
403467
  async function buildAgentInfoReminder(context3) {
403604
403468
  if (!context3.systemInfoReminderEnabled || context3.state.hasSentAgentInfo) {
@@ -403658,6 +403522,80 @@ ${SYSTEM_REMINDER_CLOSE}`;
403658
403522
  return null;
403659
403523
  }
403660
403524
  }
403525
+ async function defaultListServerSideServers(agentId) {
403526
+ let serverSideAvailable = false;
403527
+ try {
403528
+ const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
403529
+ serverSideAvailable = getBackend2().capabilities.serverSideToolManagement;
403530
+ } catch {
403531
+ return null;
403532
+ }
403533
+ if (!serverSideAvailable) {
403534
+ return null;
403535
+ }
403536
+ const { getClient: getClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
403537
+ const { getServerUrl: getServerUrl2 } = await Promise.resolve().then(() => (init_server_url(), exports_server_url));
403538
+ const { LETTA_CLOUD_API_URL: LETTA_CLOUD_API_URL2 } = await Promise.resolve().then(() => (init_oauth(), exports_oauth));
403539
+ const { listUnifiedMcpServers: listUnifiedMcpServers2, listUnifiedMcpTools: listUnifiedMcpTools2 } = await Promise.resolve().then(() => (init_unified_mcp(), exports_unified_mcp));
403540
+ const client = await getClient2();
403541
+ const allServers = await listUnifiedMcpServers2(client, agentId, 3000);
403542
+ const servers = getServerUrl2() === LETTA_CLOUD_API_URL2 ? allServers.filter((server2) => server2.serverType !== "stdio") : allServers;
403543
+ return Promise.all(servers.map(async (server2) => ({
403544
+ name: server2.serverName,
403545
+ toolCount: await listUnifiedMcpTools2(client, agentId, server2.id, 3000).then((tools) => tools.length).catch(() => null)
403546
+ })));
403547
+ }
403548
+ function formatMcpServerEntry(entry) {
403549
+ if (entry.toolCount === null) {
403550
+ return entry.name;
403551
+ }
403552
+ return `${entry.name} (${entry.toolCount} ${entry.toolCount === 1 ? "tool" : "tools"})`;
403553
+ }
403554
+ async function buildMcpServersInfoReminderText(context3, deps = {}) {
403555
+ try {
403556
+ const now2 = Date.now();
403557
+ const lastFetched = context3.state.lastMcpServersFetchedAtMs;
403558
+ const due = !context3.state.hasSentMcpServersInfo || lastFetched === null || now2 - lastFetched > MCP_SERVERS_REFRESH_MS;
403559
+ if (!due) {
403560
+ return null;
403561
+ }
403562
+ context3.state.lastMcpServersFetchedAtMs = now2;
403563
+ const localNames = (deps.getLocalServerNames ?? ((agentId) => settingsManager.getMcpServers(agentId).map((server2) => server2.name)))(context3.agent.id);
403564
+ const entries = localNames.map((name) => ({
403565
+ name,
403566
+ toolCount: null
403567
+ }));
403568
+ const serverSideEntries = await (deps.listServerSideServers ?? defaultListServerSideServers)(context3.agent.id);
403569
+ if (serverSideEntries) {
403570
+ entries.push(...serverSideEntries);
403571
+ }
403572
+ const uniqueEntries = [
403573
+ ...new Map(entries.map((entry) => [entry.name, entry])).values()
403574
+ ];
403575
+ const namesKey = uniqueEntries.map((entry) => `${entry.name}\x01${entry.toolCount ?? ""}`).join("\x00");
403576
+ if (context3.state.hasSentMcpServersInfo && context3.state.lastSentMcpServerNamesKey === namesKey) {
403577
+ return null;
403578
+ }
403579
+ context3.state.hasSentMcpServersInfo = true;
403580
+ context3.state.lastSentMcpServerNamesKey = namesKey;
403581
+ if (uniqueEntries.length === 0) {
403582
+ return `${SYSTEM_REMINDER_OPEN}
403583
+ MCP servers with available tools: None
403584
+ ${SYSTEM_REMINDER_CLOSE}`;
403585
+ }
403586
+ const rendered = uniqueEntries.map(formatMcpServerEntry).join(", ");
403587
+ return `${SYSTEM_REMINDER_OPEN}
403588
+ MCP servers with available tools: ${rendered}
403589
+ Find tools (with schemas) with \`letta mcp search "<what you want to do>"\`, list one server's tools with \`letta mcp tools <server>\` (\`--full\` includes schemas, \`letta mcp schema <tool-name>\` fetches one), and invoke one with \`letta mcp call <tool-name> --args '{"key":"value"}'\`.
403590
+ ${SYSTEM_REMINDER_CLOSE}`;
403591
+ } catch (error4) {
403592
+ debugLog("mcp", `Failed to build MCP servers reminder: ${error4 instanceof Error ? error4.message : String(error4)}`);
403593
+ return null;
403594
+ }
403595
+ }
403596
+ async function buildMcpServersInfoReminder(context3) {
403597
+ return buildMcpServersInfoReminderText(context3);
403598
+ }
403661
403599
  async function buildSessionContextReminder(context3) {
403662
403600
  if (!context3.systemInfoReminderEnabled || context3.state.hasSentSessionContext) {
403663
403601
  return null;
@@ -403853,7 +403791,7 @@ function prependReminderPartsToContent(content, reminderParts) {
403853
403791
  }
403854
403792
  return [...reminderParts, { type: "text", text: text2 }];
403855
403793
  }
403856
- var PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
403794
+ var MCP_SERVERS_REFRESH_MS = 300000, PERMISSION_MODE_DESCRIPTIONS, MAX_COMMAND_REMINDERS_PER_TURN = 10, MAX_TOOLSET_REMINDERS_PER_TURN = 5, MAX_COMMAND_INPUT_CHARS = 2000, MAX_COMMAND_OUTPUT_CHARS = 4000, MAX_TOOL_LIST_CHARS = 3000, sharedReminderProviders;
403857
403795
  var init_engine3 = __esm(() => {
403858
403796
  init_agent_info();
403859
403797
  init_conversation_bootstrap();
@@ -403874,6 +403812,7 @@ var init_engine3 = __esm(() => {
403874
403812
  "agent-info": buildAgentInfoReminder,
403875
403813
  "conversation-bootstrap": buildConversationBootstrapReminderPart,
403876
403814
  "secrets-info": buildSecretsInfoReminder,
403815
+ "mcp-servers-info": buildMcpServersInfoReminder,
403877
403816
  "session-context": buildSessionContextReminder,
403878
403817
  "permission-mode": buildPermissionModeReminder,
403879
403818
  "memory-git-sync": buildMemoryGitSyncReminder,
@@ -408217,7 +408156,7 @@ function getNumber(record3, keys3) {
408217
408156
  }
408218
408157
  return null;
408219
408158
  }
408220
- function getString2(record3, keys3) {
408159
+ function getString(record3, keys3) {
408221
408160
  const value = getValue(record3, keys3);
408222
408161
  if (typeof value === "string" && value.trim())
408223
408162
  return value.trim();
@@ -408303,7 +408242,7 @@ function normalizeCredits(raw2, rateLimit) {
408303
408242
  const resetCredits = getRecord(raw2, ["rate_limit_reset_credits", "rateLimitResetCredits"]) ?? getRecord(rateLimit, ["rate_limit_reset_credits", "rateLimitResetCredits"]);
408304
408243
  if (!credits && !resetCredits)
408305
408244
  return null;
408306
- const balance = getString2(credits, ["balance", "credit_balance", "amount"]);
408245
+ const balance = getString(credits, ["balance", "credit_balance", "amount"]);
408307
408246
  const availableCount = getNumber(credits, ["available_count", "availableCount", "count"]) ?? getNumber(resetCredits, ["available_count", "availableCount", "count"]);
408308
408247
  const hasCredits = getBoolean(credits, ["has_credits", "hasCredits"]);
408309
408248
  const unlimited = getBoolean(credits, ["unlimited", "is_unlimited"]);
@@ -408322,8 +408261,8 @@ function normalizeIndividualLimit(raw2, nowMs) {
408322
408261
  const record3 = getRecord(raw2, ["individual_limit", "individualLimit"]) ?? getRecord(spendControl, ["individual_limit", "individualLimit"]);
408323
408262
  if (!record3)
408324
408263
  return null;
408325
- const limit3 = getString2(record3, ["limit"]);
408326
- const used = getString2(record3, ["used"]);
408264
+ const limit3 = getString(record3, ["limit"]);
408265
+ const used = getString(record3, ["used"]);
408327
408266
  const remainingPercent = getNumber(record3, [
408328
408267
  "remaining_percent",
408329
408268
  "remainingPercent"
@@ -408352,10 +408291,10 @@ function normalizeCloudUsageWindow(value, fallbackLabel, nowMs) {
408352
408291
  const record3 = asRecord8(value);
408353
408292
  if (!record3)
408354
408293
  return null;
408355
- return normalizeUsageWindow(record3, getString2(record3, ["label", "name"]) ?? fallbackLabel, nowMs);
408294
+ return normalizeUsageWindow(record3, getString(record3, ["label", "name"]) ?? fallbackLabel, nowMs);
408356
408295
  }
408357
408296
  function normalizeAdditionalRateLimit(details, index, nowMs) {
408358
- const label = getString2(details, [
408297
+ const label = getString(details, [
408359
408298
  "limit_name",
408360
408299
  "limitName",
408361
408300
  "metered_feature",
@@ -408381,7 +408320,7 @@ function getRateLimitReachedType(raw2) {
408381
408320
  if (typeof value === "string" && value.trim())
408382
408321
  return value.trim();
408383
408322
  const record3 = asRecord8(value);
408384
- return getString2(record3, ["type", "kind"]);
408323
+ return getString(record3, ["type", "kind"]);
408385
408324
  }
408386
408325
  function formatPercent(value) {
408387
408326
  const rounded = Math.round(value);
@@ -408496,7 +408435,7 @@ function normalizeWhamUsageResponse(input) {
408496
408435
  const snapshotWithoutSummary = {
408497
408436
  providerName: input.providerName,
408498
408437
  fetchedAt,
408499
- planType: getString2(raw2, ["plan_type", "planType"]),
408438
+ planType: getString(raw2, ["plan_type", "planType"]),
408500
408439
  limitReached: getBoolean(rateLimit, ["limit_reached", "limitReached"]) ?? getBoolean(spendControl, ["reached"]),
408501
408440
  rateLimitReachedType: getRateLimitReachedType(raw2),
408502
408441
  primary,
@@ -408515,18 +408454,18 @@ function normalizeCloudChatGPTUsageResponse(input) {
408515
408454
  if (!raw2)
408516
408455
  return null;
408517
408456
  const nowMs = input.nowMs ?? Date.now();
408518
- const fetchedAt = getString2(raw2, ["fetchedAt", "fetched_at"]) ?? new Date(nowMs).toISOString();
408457
+ const fetchedAt = getString(raw2, ["fetchedAt", "fetched_at"]) ?? new Date(nowMs).toISOString();
408519
408458
  const additional = getRecordArray(raw2, [
408520
408459
  "additional",
408521
408460
  "additional_rate_limits",
408522
408461
  "additionalRateLimits"
408523
408462
  ]).map((window2, index) => normalizeCloudUsageWindow(window2, `limit ${index + 1}`, nowMs)).filter((window2) => !!window2);
408524
408463
  const snapshotWithoutSummary = {
408525
- providerName: getString2(raw2, ["providerName", "provider_name"]) ?? input.providerName,
408464
+ providerName: getString(raw2, ["providerName", "provider_name"]) ?? input.providerName,
408526
408465
  fetchedAt,
408527
- planType: getString2(raw2, ["planType", "plan_type"]),
408466
+ planType: getString(raw2, ["planType", "plan_type"]),
408528
408467
  limitReached: getBoolean(raw2, ["limitReached", "limit_reached"]),
408529
- rateLimitReachedType: getString2(raw2, [
408468
+ rateLimitReachedType: getString(raw2, [
408530
408469
  "rateLimitReachedType",
408531
408470
  "rate_limit_reached_type"
408532
408471
  ]),
@@ -408538,7 +408477,7 @@ function normalizeCloudChatGPTUsageResponse(input) {
408538
408477
  };
408539
408478
  return {
408540
408479
  ...snapshotWithoutSummary,
408541
- summary: getString2(raw2, ["summary"]) ?? formatChatGPTUsageSnapshot(snapshotWithoutSummary, new Date(nowMs))
408480
+ summary: getString(raw2, ["summary"]) ?? formatChatGPTUsageSnapshot(snapshotWithoutSummary, new Date(nowMs))
408542
408481
  };
408543
408482
  }
408544
408483
  function retryAfterMs(response) {
@@ -408563,7 +408502,7 @@ async function readJsonRecord(response) {
408563
408502
  }
408564
408503
  }
408565
408504
  function responseMessage(raw2, fallback) {
408566
- return getString2(raw2 ?? undefined, ["message", "error", "detail"]) ?? fallback;
408505
+ return getString(raw2 ?? undefined, ["message", "error", "detail"]) ?? fallback;
408567
408506
  }
408568
408507
  function chatGPTUsageError(code2, message, retryAfter) {
408569
408508
  return {
@@ -412332,7 +412271,7 @@ var init_app_server_openai_common = __esm(() => {
412332
412271
  function asRecord9(value) {
412333
412272
  return value !== null && typeof value === "object" ? value : null;
412334
412273
  }
412335
- function stringValue4(value) {
412274
+ function stringValue3(value) {
412336
412275
  return typeof value === "string" ? value : undefined;
412337
412276
  }
412338
412277
  function extractToolCallFragments(record3) {
@@ -412346,12 +412285,12 @@ function extractToolCallFragments(record3) {
412346
412285
  if (!toolCall) {
412347
412286
  continue;
412348
412287
  }
412349
- const toolCallId = stringValue4(toolCall.tool_call_id);
412288
+ const toolCallId = stringValue3(toolCall.tool_call_id);
412350
412289
  if (!toolCallId) {
412351
412290
  continue;
412352
412291
  }
412353
- const name = stringValue4(toolCall.name) ?? null;
412354
- const argumentsDelta = stringValue4(toolCall.arguments) ?? null;
412292
+ const name = stringValue3(toolCall.name) ?? null;
412293
+ const argumentsDelta = stringValue3(toolCall.arguments) ?? null;
412355
412294
  fragments.push({ toolCallId, name, argumentsDelta });
412356
412295
  }
412357
412296
  return fragments;
@@ -412391,7 +412330,7 @@ function extractToolReturns(record3) {
412391
412330
  if (!rec) {
412392
412331
  continue;
412393
412332
  }
412394
- const toolCallId = stringValue4(rec.tool_call_id);
412333
+ const toolCallId = stringValue3(rec.tool_call_id);
412395
412334
  const status = asToolReturnStatus2(rec.status);
412396
412335
  if (!toolCallId || !status) {
412397
412336
  continue;
@@ -412406,7 +412345,7 @@ function extractToolReturns(record3) {
412406
412345
  return results;
412407
412346
  }
412408
412347
  }
412409
- const topLevelToolCallId = stringValue4(record3.tool_call_id);
412348
+ const topLevelToolCallId = stringValue3(record3.tool_call_id);
412410
412349
  const topLevelStatus = asToolReturnStatus2(record3.status);
412411
412350
  if (!topLevelToolCallId || !topLevelStatus) {
412412
412351
  return [];
@@ -412494,13 +412433,13 @@ function createToolLifecycleTracker(onEvent) {
412494
412433
  return;
412495
412434
  }
412496
412435
  const record3 = delta2;
412497
- const messageType = stringValue4(record3.message_type);
412498
- const toolCallId = stringValue4(record3.tool_call_id);
412436
+ const messageType = stringValue3(record3.message_type);
412437
+ const toolCallId = stringValue3(record3.tool_call_id);
412499
412438
  if (messageType === "client_tool_start" && toolCallId) {
412500
412439
  const state = getOrCreate(toolCallId);
412501
412440
  state.clientManaged = true;
412502
412441
  if (!state.name)
412503
- state.name = stringValue4(record3.tool_name) ?? null;
412442
+ state.name = stringValue3(record3.tool_name) ?? null;
412504
412443
  return;
412505
412444
  }
412506
412445
  if (messageType === "client_tool_end" && toolCallId) {
@@ -414087,7 +414026,7 @@ var init_gateway_supervisor = __esm(() => {
414087
414026
 
414088
414027
  // src/cli/subcommands/listen.tsx
414089
414028
  import { hostname as hostname4 } from "node:os";
414090
- import { parseArgs as parseArgs9 } from "node:util";
414029
+ import { parseArgs as parseArgs8 } from "node:util";
414091
414030
  import { MessageChannel as MessageChannel2 } from "node:worker_threads";
414092
414031
  function PromptEnvName(props) {
414093
414032
  const [value, setValue] = import_react33.useState("");
@@ -414200,7 +414139,7 @@ function printListenUsage() {
414200
414139
  async function runListenSubcommand(argv) {
414201
414140
  let values3;
414202
414141
  try {
414203
- ({ values: values3 } = parseArgs9({
414142
+ ({ values: values3 } = parseArgs8({
414204
414143
  args: argv,
414205
414144
  options: LISTEN_OPTIONS,
414206
414145
  strict: true,
@@ -415108,15 +415047,15 @@ var init_transcript_migration = __esm(() => {
415108
415047
  });
415109
415048
 
415110
415049
  // src/cli/subcommands/local-backend.ts
415111
- import { parseArgs as parseArgs10 } from "node:util";
415050
+ import { parseArgs as parseArgs9 } from "node:util";
415112
415051
  function parseLocalBackendArgs(argv) {
415113
- return parseArgs10({
415052
+ return parseArgs9({
415114
415053
  args: argv,
415115
415054
  options: LOCAL_BACKEND_OPTIONS,
415116
415055
  strict: true
415117
415056
  });
415118
415057
  }
415119
- function printUsage8() {
415058
+ function printUsage7() {
415120
415059
  console.log(`
415121
415060
  Usage:
415122
415061
  letta local-backend migrate-transcripts [--storage-dir <path>] [--dry-run]
@@ -415129,12 +415068,12 @@ before it is replaced.
415129
415068
  async function runLocalBackendSubcommand(argv) {
415130
415069
  const [command, ...rest4] = argv;
415131
415070
  if (!command || command === "help" || command === "--help" || command === "-h") {
415132
- printUsage8();
415071
+ printUsage7();
415133
415072
  return command ? 0 : 1;
415134
415073
  }
415135
415074
  if (command !== "migrate-transcripts") {
415136
415075
  console.error(`Unknown local-backend command: ${command}`);
415137
- printUsage8();
415076
+ printUsage7();
415138
415077
  return 1;
415139
415078
  }
415140
415079
  let parsed;
@@ -415143,11 +415082,11 @@ async function runLocalBackendSubcommand(argv) {
415143
415082
  } catch (error4) {
415144
415083
  const message = error4 instanceof Error ? error4.message : String(error4);
415145
415084
  console.error(`Error: ${message}`);
415146
- printUsage8();
415085
+ printUsage7();
415147
415086
  return 1;
415148
415087
  }
415149
415088
  if (parsed.values.help) {
415150
- printUsage8();
415089
+ printUsage7();
415151
415090
  return 0;
415152
415091
  }
415153
415092
  const storageDir = parsed.values["storage-dir"] ?? getLocalBackendStorageDir();
@@ -415169,160 +415108,6 @@ var init_local_backend2 = __esm(() => {
415169
415108
  };
415170
415109
  });
415171
415110
 
415172
- // src/backend/api/unified-mcp.ts
415173
- function stringField2(value, key2) {
415174
- return typeof value[key2] === "string" ? value[key2] : null;
415175
- }
415176
- function recordField(value, ...names2) {
415177
- for (const name of names2) {
415178
- const field = value[name];
415179
- if (isRecord(field))
415180
- return field;
415181
- }
415182
- return;
415183
- }
415184
- function parseServer(value, registered) {
415185
- if (!isRecord(value))
415186
- return null;
415187
- const id2 = stringField2(value, "id");
415188
- const serverName = stringField2(value, "server_name") ?? (registered ? stringField2(registered, "server_name") : null);
415189
- const serverType = stringField2(value, "mcp_server_type") ?? (registered ? stringField2(registered, "mcp_server_type") : null) ?? "unknown";
415190
- if (!id2 || !serverName)
415191
- return null;
415192
- const serverUrl = stringField2(value, "server_url") ?? (registered ? stringField2(registered, "server_url") : null) ?? undefined;
415193
- const command = stringField2(value, "command") ?? (registered ? stringField2(registered, "command") : null) ?? undefined;
415194
- const argsValue = value.args ?? registered?.args;
415195
- const args = Array.isArray(argsValue) ? argsValue.filter((item) => typeof item === "string") : [];
415196
- const target2 = serverUrl ?? [command, ...args].filter(Boolean).join(" ");
415197
- return {
415198
- id: id2,
415199
- serverName,
415200
- serverType,
415201
- target: target2,
415202
- ...serverUrl ? { serverUrl } : {},
415203
- ...command ? { command, args } : {}
415204
- };
415205
- }
415206
- function parseTool(value) {
415207
- if (!isRecord(value))
415208
- return null;
415209
- const id2 = stringField2(value, "id");
415210
- const name = stringField2(value, "name");
415211
- if (!id2 || !name)
415212
- return null;
415213
- const description = stringField2(value, "description");
415214
- const jsonSchema = isRecord(value.json_schema) ? value.json_schema : {};
415215
- const inputSchema = isRecord(jsonSchema.parameters) ? jsonSchema.parameters : isRecord(value.args_json_schema) ? value.args_json_schema : { type: "object", properties: {} };
415216
- const title = stringField2(value, "title") ?? stringField2(jsonSchema, "title");
415217
- const outputSchema = recordField(value, "outputSchema", "output_schema") ?? recordField(jsonSchema, "outputSchema", "output_schema");
415218
- const annotations = recordField(value, "annotations") ?? recordField(jsonSchema, "annotations");
415219
- const execution = recordField(value, "execution") ?? recordField(jsonSchema, "execution");
415220
- const meta = recordField(value, "_meta") ?? recordField(jsonSchema, "_meta");
415221
- const iconsValue = value.icons ?? jsonSchema.icons;
415222
- const icons = Array.isArray(iconsValue) ? iconsValue.filter(isRecord) : undefined;
415223
- return {
415224
- id: id2,
415225
- name,
415226
- ...title ? { title } : {},
415227
- description,
415228
- inputSchema,
415229
- ...outputSchema ? { outputSchema } : {},
415230
- ...annotations ? { annotations } : {},
415231
- ...execution ? { execution } : {},
415232
- ...meta ? { _meta: meta } : {},
415233
- ...icons ? { icons } : {}
415234
- };
415235
- }
415236
- function parseRunResult(value) {
415237
- if (!isRecord(value))
415238
- throw new Error("Invalid MCP tool run response");
415239
- return {
415240
- status: stringField2(value, "status") ?? "unknown",
415241
- funcReturn: value.func_return,
415242
- stdout: value.stdout,
415243
- stderr: value.stderr
415244
- };
415245
- }
415246
- function parseSearchResult(value) {
415247
- if (!isRecord(value) || !isRecord(value.tool))
415248
- return null;
415249
- const toolId = stringField2(value.tool, "id");
415250
- const jsonSchema = value.tool.json_schema;
415251
- const score = value.combined_score;
415252
- if (!toolId || jsonSchema !== null && !isRecord(jsonSchema) || typeof score !== "number") {
415253
- return null;
415254
- }
415255
- return { toolId, jsonSchema, score };
415256
- }
415257
- async function withTimeout3(promise, timeoutMs, operation) {
415258
- let timer;
415259
- try {
415260
- return await Promise.race([
415261
- promise,
415262
- new Promise((_resolve, reject2) => {
415263
- timer = setTimeout(() => reject2(new Error(`${operation} timed out after ${timeoutMs}ms`)), timeoutMs);
415264
- })
415265
- ]);
415266
- } finally {
415267
- if (timer)
415268
- clearTimeout(timer);
415269
- }
415270
- }
415271
- async function listUnifiedMcpServers(client, agentId, timeoutMs = 1e4) {
415272
- const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent MCP servers");
415273
- if (!Array.isArray(value))
415274
- return [];
415275
- const needsEnrichment = value.some((item) => isRecord(item) && !stringField2(item, "mcp_server_type"));
415276
- const registeredById = new Map;
415277
- if (needsEnrichment && client.mcpServers) {
415278
- try {
415279
- const registered = await withTimeout3(client.mcpServers.list(), timeoutMs, "Listing registered MCP servers");
415280
- for (const item of registered) {
415281
- if (!isRecord(item))
415282
- continue;
415283
- const id2 = stringField2(item, "id");
415284
- if (id2)
415285
- registeredById.set(id2, item);
415286
- }
415287
- } catch {}
415288
- }
415289
- return value.map((item) => {
415290
- const registered = isRecord(item) ? registeredById.get(stringField2(item, "id") ?? "") : undefined;
415291
- return parseServer(item, registered);
415292
- }).filter((server2) => server2 !== null);
415293
- }
415294
- async function listUnifiedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
415295
- const value = await withTimeout3(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent MCP server tools");
415296
- if (!Array.isArray(value))
415297
- return [];
415298
- return value.map(parseTool).filter((tool) => tool !== null);
415299
- }
415300
- async function searchUnifiedMcpTools(params) {
415301
- const value = await withTimeout3(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/tools/search`, {
415302
- body: {
415303
- query: params.query,
415304
- search_mode: params.searchMode,
415305
- limit: params.limit
415306
- }
415307
- }), params.timeoutMs ?? 60000, "Searching agent MCP tools");
415308
- if (!Array.isArray(value)) {
415309
- throw new Error("Invalid MCP tool search response");
415310
- }
415311
- const results = [];
415312
- for (const item of value) {
415313
- const result2 = parseSearchResult(item);
415314
- if (!result2)
415315
- throw new Error("Invalid MCP tool search result");
415316
- results.push(result2);
415317
- }
415318
- return results;
415319
- }
415320
- async function runUnifiedMcpTool(params) {
415321
- const value = await withTimeout3(params.client.post(`/v1/agents/${encodeURIComponent(params.agentId)}/mcp-servers/${encodeURIComponent(params.mcpServerId)}/tools/${encodeURIComponent(params.toolId)}/run`, { body: { args: params.args } }), params.timeoutMs ?? 60000, "Running agent MCP tool");
415322
- return parseRunResult(value);
415323
- }
415324
- var init_unified_mcp = () => {};
415325
-
415326
415111
  // node_modules/pkce-challenge/dist/index.node.js
415327
415112
  async function getRandomValues(size2) {
415328
415113
  return (await crypto2).getRandomValues(new Uint8Array(size2));
@@ -432165,7 +431950,7 @@ var init_mcp_client = __esm(() => {
432165
431950
  init_streamableHttp();
432166
431951
  DEFAULT_CLIENT_INFO = {
432167
431952
  name: "letta-code",
432168
- version: "0.31.10"
431953
+ version: "0.31.11"
432169
431954
  };
432170
431955
  });
432171
431956
 
@@ -432606,20 +432391,23 @@ function printMcpUsage(stdout) {
432606
432391
  Usage:
432607
432392
  letta mcp list [--agent <id>]
432608
432393
  letta mcp get <server> [--agent <id>]
432609
- letta mcp tools [server] [--agent <id>]
432394
+ letta mcp tools [server] [--full] [--agent <id>]
432395
+ letta mcp schema <tool-name> [--agent <id>]
432610
432396
  letta mcp search <query> [--mode <hybrid|vector|fts>] [--limit <n>] [--agent <id>]
432611
432397
  letta mcp call <tool-name> [--args '<json>' | --args-file <path|->] [--agent <id>]
432612
432398
 
432613
432399
  Commands:
432614
432400
  list List MCP servers available to the agent
432615
432401
  get Print one server's redacted connection configuration
432616
- tools Print complete MCP tool schemas; names are accepted by call
432402
+ tools List tool names and descriptions; names are accepted by call
432403
+ schema Print one tool's complete schema
432617
432404
  search Search tools available to the agent
432618
432405
  call Call one exact tool name and print an MCP CallToolResult
432619
432406
 
432620
432407
  Options:
432621
432408
  --agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
432622
432409
  --agent-id <id> Alias for --agent
432410
+ --full Include complete schemas in tools output
432623
432411
  --mode <mode> Search mode: hybrid (default), vector, or fts
432624
432412
  --limit <n> Search result limit from 1 to 100 (default: 5)
432625
432413
  --args <json> JSON object passed to a tool
@@ -432828,9 +432616,16 @@ var init_mcp_tool_names = __esm(async () => {
432828
432616
  });
432829
432617
 
432830
432618
  // src/cli/subcommands/mcp.ts
432831
- import { parseArgs as parseArgs11 } from "node:util";
432619
+ import { parseArgs as parseArgs10 } from "node:util";
432620
+ function defaultIsHostedLettaCloud() {
432621
+ try {
432622
+ return getServerUrl() === LETTA_CLOUD_API_URL;
432623
+ } catch {
432624
+ return !process.env.LETTA_BASE_URL;
432625
+ }
432626
+ }
432832
432627
  function parseMcpArgs(argv) {
432833
- return parseArgs11({
432628
+ return parseArgs10({
432834
432629
  args: argv,
432835
432630
  options: {
432836
432631
  help: { type: "boolean", short: "h" },
@@ -432838,6 +432633,7 @@ function parseMcpArgs(argv) {
432838
432633
  "agent-id": { type: "string" },
432839
432634
  mode: { type: "string" },
432840
432635
  limit: { type: "string" },
432636
+ full: { type: "boolean" },
432841
432637
  args: { type: "string" },
432842
432638
  "args-file": { type: "string" }
432843
432639
  },
@@ -432853,7 +432649,7 @@ function parseCommandLine(argv) {
432853
432649
  }
432854
432650
  return { action: action3, target: target2, values: parsed.values };
432855
432651
  }
432856
- function stringValue5(value) {
432652
+ function stringValue4(value) {
432857
432653
  return typeof value === "string" ? value : undefined;
432858
432654
  }
432859
432655
  function getLocalServers(deps, agentId) {
@@ -432892,9 +432688,8 @@ function redactUrl(value) {
432892
432688
  const url2 = new URL(value);
432893
432689
  url2.username = "";
432894
432690
  url2.password = "";
432895
- const sensitive = /token|key|secret|password|signature|credential/i;
432896
432691
  for (const key2 of url2.searchParams.keys()) {
432897
- if (sensitive.test(key2))
432692
+ if (SENSITIVE_NAME.test(key2))
432898
432693
  url2.searchParams.set(key2, "[REDACTED]");
432899
432694
  }
432900
432695
  return url2.toString();
@@ -432902,6 +432697,32 @@ function redactUrl(value) {
432902
432697
  return value;
432903
432698
  }
432904
432699
  }
432700
+ function redactArgs(args) {
432701
+ const redacted = [];
432702
+ let redactNext = false;
432703
+ for (const arg of args) {
432704
+ if (redactNext) {
432705
+ redacted.push("[REDACTED]");
432706
+ redactNext = false;
432707
+ continue;
432708
+ }
432709
+ if (arg.startsWith("-")) {
432710
+ const equalsIndex = arg.indexOf("=");
432711
+ const flagName = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
432712
+ if (SENSITIVE_NAME.test(flagName)) {
432713
+ if (equalsIndex === -1) {
432714
+ redactNext = true;
432715
+ redacted.push(arg);
432716
+ } else {
432717
+ redacted.push(`${flagName}=[REDACTED]`);
432718
+ }
432719
+ continue;
432720
+ }
432721
+ }
432722
+ redacted.push(arg);
432723
+ }
432724
+ return redacted;
432725
+ }
432905
432726
  function serverDetails(target2) {
432906
432727
  if (target2.kind === "client") {
432907
432728
  const config2 = target2.config;
@@ -432917,7 +432738,7 @@ function serverDetails(target2) {
432917
432738
  name: config2.name,
432918
432739
  transport: "stdio",
432919
432740
  command: config2.command,
432920
- args: config2.args ?? [],
432741
+ args: redactArgs(config2.args ?? []),
432921
432742
  ...config2.cwd ? { cwd: config2.cwd } : {},
432922
432743
  env: redactValues(config2.env)
432923
432744
  };
@@ -432931,7 +432752,7 @@ function serverDetails(target2) {
432931
432752
  name: server2.serverName,
432932
432753
  transport: "stdio",
432933
432754
  command: server2.command ?? server2.target.split(" ")[0] ?? "",
432934
- args: server2.args ?? [],
432755
+ args: redactArgs(server2.args ?? []),
432935
432756
  env: {}
432936
432757
  };
432937
432758
  }
@@ -433021,7 +432842,10 @@ async function buildToolCatalog(deps, agentId, options = {}) {
433021
432842
  const connections = [];
433022
432843
  const usedNames = new Set;
433023
432844
  try {
433024
- const serverTargets = activeServers.filter((target2) => target2.kind === "server");
432845
+ const hostedLettaCloud = (deps.isHostedLettaCloud ?? defaultIsHostedLettaCloud)();
432846
+ const allServerTargets = activeServers.filter((target2) => target2.kind === "server");
432847
+ const serverTargets = hostedLettaCloud ? allServerTargets.filter(({ server: server2 }) => server2.serverType !== "stdio") : allServerTargets;
432848
+ const excludedHostedStdioServers = serverTargets.length !== allServerTargets.length;
433025
432849
  if (serverTargets.length > 0) {
433026
432850
  const client = await getServerClient(deps);
433027
432851
  const toolLists = await Promise.all(serverTargets.map(async ({ server: server2 }) => ({
@@ -433084,6 +432908,7 @@ async function buildToolCatalog(deps, agentId, options = {}) {
433084
432908
  }
433085
432909
  return {
433086
432910
  tools: catalog,
432911
+ excludedHostedStdioServers,
433087
432912
  close: async () => {
433088
432913
  await Promise.allSettled(connections.map((connection) => connection.close()));
433089
432914
  }
@@ -433126,12 +432951,12 @@ function mcpToolResultFromServer(result2) {
433126
432951
  isError: !success || normalized.isError === true
433127
432952
  };
433128
432953
  }
433129
- function printJson2(stdout, value) {
432954
+ function printJson(stdout, value) {
433130
432955
  stdout(JSON.stringify(value, null, 2));
433131
432956
  }
433132
432957
  async function runList(deps, agentId, stdout) {
433133
432958
  const servers = await listUnifiedServers(deps, agentId);
433134
- printJson2(stdout, servers.map(serverSummary));
432959
+ printJson(stdout, servers.map(serverSummary));
433135
432960
  return 0;
433136
432961
  }
433137
432962
  async function runGet(deps, agentId, selector, stdout) {
@@ -433139,25 +432964,45 @@ async function runGet(deps, agentId, selector, stdout) {
433139
432964
  throw new McpCliError("invalid_arguments", "Usage: letta mcp get <server>");
433140
432965
  }
433141
432966
  const server2 = resolveServer(await listUnifiedServers(deps, agentId), selector);
433142
- printJson2(stdout, serverDetails(server2));
432967
+ printJson(stdout, serverDetails(server2));
433143
432968
  return 0;
433144
432969
  }
433145
- async function runTools(deps, agentId, serverSelector, stdout) {
432970
+ async function runTools(deps, agentId, serverSelector, full, stdout) {
433146
432971
  const catalog = await buildToolCatalog(deps, agentId, { serverSelector });
433147
432972
  try {
433148
- printJson2(stdout, catalog.tools.map((tool) => tool.schema));
432973
+ printJson(stdout, catalog.tools.map((tool) => full ? tool.schema : {
432974
+ name: tool.schema.name,
432975
+ ...tool.schema.title ? { title: tool.schema.title } : {},
432976
+ ...tool.schema.description ? { description: tool.schema.description } : {}
432977
+ }));
433149
432978
  } finally {
433150
432979
  await catalog.close();
433151
432980
  }
433152
432981
  return 0;
433153
432982
  }
432983
+ async function runSchema(deps, agentId, toolName, stdout) {
432984
+ if (!toolName) {
432985
+ throw new McpCliError("invalid_arguments", "Usage: letta mcp schema <tool-name>");
432986
+ }
432987
+ const catalog = await buildToolCatalog(deps, agentId, { toolName });
432988
+ try {
432989
+ const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
432990
+ if (!tool) {
432991
+ throw new McpCliError("tool_not_found", `MCP tool '${toolName}' is not available`);
432992
+ }
432993
+ printJson(stdout, tool.schema);
432994
+ return 0;
432995
+ } finally {
432996
+ await catalog.close();
432997
+ }
432998
+ }
433154
432999
  async function runSearch(parsed, deps, agentId, stdout) {
433155
433000
  const serverSearchAvailable = serverMcpAvailable(deps);
433156
433001
  const hasClientLocalServers = getLocalServers(deps, agentId).length > 0;
433157
433002
  return runMcpSearch({
433158
433003
  query: parsed.target,
433159
- mode: stringValue5(parsed.values.mode),
433160
- limit: stringValue5(parsed.values.limit),
433004
+ mode: stringValue4(parsed.values.mode),
433005
+ limit: stringValue4(parsed.values.limit),
433161
433006
  stdout,
433162
433007
  searchTools: async (request) => {
433163
433008
  if (!serverSearchAvailable) {
@@ -433190,15 +433035,20 @@ async function runSearch(parsed, deps, agentId, stdout) {
433190
433035
  catalogPromise
433191
433036
  ]);
433192
433037
  catalog = resolvedCatalog;
433193
- const serverResults = searchResults.map((result2) => {
433038
+ const serverResults = searchResults.flatMap((result2) => {
433194
433039
  const callable = resolvedCatalog.tools.find((tool) => tool.target.kind === "server" && tool.target.toolId === result2.toolId);
433195
433040
  if (!callable) {
433041
+ if (resolvedCatalog.excludedHostedStdioServers) {
433042
+ return [];
433043
+ }
433196
433044
  throw new Error(`MCP search returned unavailable tool '${result2.toolId}'`);
433197
433045
  }
433198
- return {
433199
- tool: result2.jsonSchema === null ? null : { ...result2.jsonSchema, name: callable.schema.name },
433200
- score: result2.score
433201
- };
433046
+ return [
433047
+ {
433048
+ tool: result2.jsonSchema === null ? null : { ...result2.jsonSchema, name: callable.schema.name },
433049
+ score: result2.score
433050
+ }
433051
+ ];
433202
433052
  });
433203
433053
  if (!includeLocal)
433204
433054
  return serverResults;
@@ -433221,7 +433071,7 @@ async function runCall(parsed, deps, agentId, stdout) {
433221
433071
  if (!toolName) {
433222
433072
  throw new McpCliError("invalid_arguments", "Usage: letta mcp call <tool-name> [--args '<json>']");
433223
433073
  }
433224
- const args = await loadMcpToolArgs(stringValue5(parsed.values.args), stringValue5(parsed.values["args-file"]), deps);
433074
+ const args = await loadMcpToolArgs(stringValue4(parsed.values.args), stringValue4(parsed.values["args-file"]), deps);
433225
433075
  const catalog = await buildToolCatalog(deps, agentId, { toolName });
433226
433076
  try {
433227
433077
  const tool = catalog.tools.find((candidate) => candidate.schema.name === toolName);
@@ -433235,7 +433085,7 @@ async function runCall(parsed, deps, agentId, stdout) {
433235
433085
  toolId: tool.target.toolId,
433236
433086
  args
433237
433087
  }));
433238
- printJson2(stdout, result2);
433088
+ printJson(stdout, result2);
433239
433089
  return result2.isError === true ? 2 : 0;
433240
433090
  } finally {
433241
433091
  await catalog.close();
@@ -433255,7 +433105,7 @@ async function runMcpSubcommand(argv, deps = {}) {
433255
433105
  printMcpUsage(stdout);
433256
433106
  return 0;
433257
433107
  }
433258
- const agentId = resolveMcpAgentId(stringValue5(parsed.values.agent), stringValue5(parsed.values["agent-id"]), deps.env ?? process.env);
433108
+ const agentId = resolveMcpAgentId(stringValue4(parsed.values.agent), stringValue4(parsed.values["agent-id"]), deps.env ?? process.env);
433259
433109
  if (!agentId) {
433260
433110
  printMcpError(stderr, new McpCliError("agent_id_required", "No agent context found", "Pass --agent <agent-id> or set LETTA_AGENT_ID."));
433261
433111
  return 1;
@@ -433270,7 +433120,9 @@ async function runMcpSubcommand(argv, deps = {}) {
433270
433120
  case "tools":
433271
433121
  case "list-tools":
433272
433122
  case "list_tools":
433273
- return await runTools(deps, agentId, parsed.target, stdout);
433123
+ return await runTools(deps, agentId, parsed.target, parsed.values.full === true, stdout);
433124
+ case "schema":
433125
+ return await runSchema(deps, agentId, parsed.target, stdout);
433274
433126
  case "search":
433275
433127
  return await runSearch(parsed, deps, agentId, stdout);
433276
433128
  case "call":
@@ -433286,9 +433138,12 @@ async function runMcpSubcommand(argv, deps = {}) {
433286
433138
  return 1;
433287
433139
  }
433288
433140
  }
433141
+ var SENSITIVE_NAME;
433289
433142
  var init_mcp = __esm(async () => {
433143
+ init_oauth();
433290
433144
  init_backend2();
433291
433145
  init_client2();
433146
+ init_server_url();
433292
433147
  init_unified_mcp();
433293
433148
  init_mcp_client();
433294
433149
  init_mcp_oauth();
@@ -433299,6 +433154,7 @@ var init_mcp = __esm(async () => {
433299
433154
  init_mcp_runtime(),
433300
433155
  init_mcp_tool_names()
433301
433156
  ]);
433157
+ SENSITIVE_NAME = /token|key|secret|password|signature|credential|auth/i;
433302
433158
  });
433303
433159
 
433304
433160
  // src/cli/subcommands/memory-tokens.ts
@@ -433327,7 +433183,7 @@ function printText(total, files, top, quiet) {
433327
433183
  console.log(` ${formatNumber(row.tokens).padStart(8)} ${row.path}`);
433328
433184
  }
433329
433185
  }
433330
- function printJson3(total, files) {
433186
+ function printJson2(total, files) {
433331
433187
  console.log(JSON.stringify({
433332
433188
  total_tokens: total,
433333
433189
  files
@@ -433368,7 +433224,7 @@ async function runMemoryTokensAction(options) {
433368
433224
  }
433369
433225
  const { total, files } = estimate;
433370
433226
  if (format5 === "json") {
433371
- printJson3(total, files);
433227
+ printJson2(total, files);
433372
433228
  } else {
433373
433229
  printText(total, files, top, options.quiet);
433374
433230
  }
@@ -433383,8 +433239,8 @@ var init_memory_tokens = __esm(() => {
433383
433239
  import { cpSync, existsSync as existsSync57, mkdirSync as mkdirSync39, rmSync as rmSync12, statSync as statSync19 } from "node:fs";
433384
433240
  import { readdir as readdir12 } from "node:fs/promises";
433385
433241
  import { dirname as dirname31, join as join72 } from "node:path";
433386
- import { parseArgs as parseArgs12 } from "node:util";
433387
- function printUsage9() {
433242
+ import { parseArgs as parseArgs11 } from "node:util";
433243
+ function printUsage8() {
433388
433244
  console.log(`
433389
433245
  Usage:
433390
433246
  letta memory status [--agent <id>]
@@ -433417,7 +433273,7 @@ function getAgentId3(agentFromArgs, agentIdFromArgs) {
433417
433273
  return agentFromArgs || agentIdFromArgs || process.env.LETTA_AGENT_ID || "";
433418
433274
  }
433419
433275
  function parseMemoryArgs(argv) {
433420
- return parseArgs12({
433276
+ return parseArgs11({
433421
433277
  args: argv,
433422
433278
  options: MEMORY_OPTIONS,
433423
433279
  strict: true,
@@ -433478,12 +433334,12 @@ async function runMemorySubcommand(argv) {
433478
433334
  } catch (error5) {
433479
433335
  const message = error5 instanceof Error ? error5.message : String(error5);
433480
433336
  console.error(`Error: ${message}`);
433481
- printUsage9();
433337
+ printUsage8();
433482
433338
  return 1;
433483
433339
  }
433484
433340
  const [action3] = parsed.positionals;
433485
433341
  if (parsed.values.help || !action3 || action3 === "help") {
433486
- printUsage9();
433342
+ printUsage8();
433487
433343
  return 0;
433488
433344
  }
433489
433345
  const agentId = getAgentId3(parsed.values.agent, parsed.values["agent-id"]);
@@ -433627,7 +433483,7 @@ async function runMemorySubcommand(argv) {
433627
433483
  return 1;
433628
433484
  }
433629
433485
  console.error(`Unknown action: ${action3}`);
433630
- printUsage9();
433486
+ printUsage8();
433631
433487
  return 1;
433632
433488
  }
433633
433489
  var MEMORY_OPTIONS;
@@ -433986,8 +433842,8 @@ var init_message_search = __esm(() => {
433986
433842
  // src/cli/subcommands/messages.ts
433987
433843
  import { writeFile as writeFile16 } from "node:fs/promises";
433988
433844
  import { resolve as resolve35 } from "node:path";
433989
- import { parseArgs as parseArgs13 } from "node:util";
433990
- function printUsage10() {
433845
+ import { parseArgs as parseArgs12 } from "node:util";
433846
+ function printUsage9() {
433991
433847
  console.log(`
433992
433848
  Usage:
433993
433849
  letta messages search --query <text> [options]
@@ -434072,7 +433928,7 @@ function pageItems4(page) {
434072
433928
  return [];
434073
433929
  }
434074
433930
  function parseMessagesArgs(argv) {
434075
- return parseArgs13({
433931
+ return parseArgs12({
434076
433932
  args: argv,
434077
433933
  options: MESSAGES_OPTIONS,
434078
433934
  strict: true,
@@ -434086,12 +433942,12 @@ async function runMessagesSubcommand(argv, deps = {}) {
434086
433942
  } catch (error5) {
434087
433943
  const message = error5 instanceof Error ? error5.message : String(error5);
434088
433944
  console.error(`Error: ${message}`);
434089
- printUsage10();
433945
+ printUsage9();
434090
433946
  return 1;
434091
433947
  }
434092
433948
  const [action3] = parsed.positionals;
434093
433949
  if (parsed.values.help || !action3 || action3 === "help") {
434094
- printUsage10();
433950
+ printUsage9();
434095
433951
  return 0;
434096
433952
  }
434097
433953
  try {
@@ -434333,7 +434189,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
434333
434189
  return 1;
434334
434190
  }
434335
434191
  console.error(`Unknown action: ${action3}`);
434336
- printUsage10();
434192
+ printUsage9();
434337
434193
  return 1;
434338
434194
  }
434339
434195
  var MESSAGES_OPTIONS;
@@ -435363,8 +435219,8 @@ var init_package_scaffolder = __esm(() => {
435363
435219
 
435364
435220
  // src/cli/subcommands/mods.ts
435365
435221
  import { dirname as dirname32, join as join74 } from "node:path";
435366
- import { parseArgs as parseArgs14 } from "node:util";
435367
- function printUsage11() {
435222
+ import { parseArgs as parseArgs13 } from "node:util";
435223
+ function printUsage10() {
435368
435224
  console.log(`
435369
435225
  Usage:
435370
435226
  letta mods list [--agent <id>]
@@ -435381,7 +435237,7 @@ Options:
435381
435237
  `.trim());
435382
435238
  }
435383
435239
  function parseModsArgs(argv) {
435384
- return parseArgs14({
435240
+ return parseArgs13({
435385
435241
  args: argv,
435386
435242
  options: MODS_OPTIONS,
435387
435243
  strict: true,
@@ -435389,7 +435245,7 @@ function parseModsArgs(argv) {
435389
435245
  });
435390
435246
  }
435391
435247
  function parseModsPackageArgs(argv) {
435392
- return parseArgs14({
435248
+ return parseArgs13({
435393
435249
  args: argv,
435394
435250
  options: MODS_PACKAGE_OPTIONS,
435395
435251
  strict: true,
@@ -435487,16 +435343,16 @@ async function runList2(argv, options = {}) {
435487
435343
  parsed = parseModsArgs(argv);
435488
435344
  } catch (error5) {
435489
435345
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
435490
- printUsage11();
435346
+ printUsage10();
435491
435347
  return 1;
435492
435348
  }
435493
435349
  if (parsed.values.help) {
435494
- printUsage11();
435350
+ printUsage10();
435495
435351
  return 0;
435496
435352
  }
435497
435353
  if (parsed.positionals.length > 0) {
435498
435354
  console.error(`Unexpected argument: ${parsed.positionals[0]}`);
435499
- printUsage11();
435355
+ printUsage10();
435500
435356
  return 1;
435501
435357
  }
435502
435358
  const agentId = getExplicitAgentId(parsed.values);
@@ -435513,27 +435369,27 @@ async function runPackageMutation(action3, argv, options = {}) {
435513
435369
  parsed = parseModsArgs(argv);
435514
435370
  } catch (error5) {
435515
435371
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
435516
- printUsage11();
435372
+ printUsage10();
435517
435373
  return 1;
435518
435374
  }
435519
435375
  if (parsed.values.help) {
435520
- printUsage11();
435376
+ printUsage10();
435521
435377
  return 0;
435522
435378
  }
435523
435379
  if (getExplicitAgentId(parsed.values)) {
435524
435380
  console.error(`--agent is only supported for 'letta mods list'.`);
435525
- printUsage11();
435381
+ printUsage10();
435526
435382
  return 1;
435527
435383
  }
435528
435384
  const [specifier, extra] = parsed.positionals;
435529
435385
  if (!specifier) {
435530
435386
  console.error(`Missing package specifier.`);
435531
- printUsage11();
435387
+ printUsage10();
435532
435388
  return 1;
435533
435389
  }
435534
435390
  if (extra) {
435535
435391
  console.error(`Unexpected argument: ${extra}`);
435536
- printUsage11();
435392
+ printUsage10();
435537
435393
  return 1;
435538
435394
  }
435539
435395
  try {
@@ -435559,27 +435415,27 @@ async function runPackageUpdate(argv, options = {}) {
435559
435415
  parsed = parseModsArgs(argv);
435560
435416
  } catch (error5) {
435561
435417
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
435562
- printUsage11();
435418
+ printUsage10();
435563
435419
  return 1;
435564
435420
  }
435565
435421
  if (parsed.values.help) {
435566
- printUsage11();
435422
+ printUsage10();
435567
435423
  return 0;
435568
435424
  }
435569
435425
  if (getExplicitAgentId(parsed.values)) {
435570
435426
  console.error(`--agent is not supported for 'letta mods update'.`);
435571
- printUsage11();
435427
+ printUsage10();
435572
435428
  return 1;
435573
435429
  }
435574
435430
  const [specifier, extra] = parsed.positionals;
435575
435431
  if (!specifier) {
435576
435432
  console.error(`Missing package specifier.`);
435577
- printUsage11();
435433
+ printUsage10();
435578
435434
  return 1;
435579
435435
  }
435580
435436
  if (extra) {
435581
435437
  console.error(`Unexpected argument: ${extra}`);
435582
- printUsage11();
435438
+ printUsage10();
435583
435439
  return 1;
435584
435440
  }
435585
435441
  try {
@@ -435601,33 +435457,33 @@ async function runPackageScaffold(argv) {
435601
435457
  parsed = parseModsPackageArgs(argv);
435602
435458
  } catch (error5) {
435603
435459
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
435604
- printUsage11();
435460
+ printUsage10();
435605
435461
  return 1;
435606
435462
  }
435607
435463
  if (parsed.values.help) {
435608
- printUsage11();
435464
+ printUsage10();
435609
435465
  return 0;
435610
435466
  }
435611
435467
  if (getExplicitAgentId(parsed.values)) {
435612
435468
  console.error(`--agent is not supported for 'letta mods package'.`);
435613
- printUsage11();
435469
+ printUsage10();
435614
435470
  return 1;
435615
435471
  }
435616
435472
  const [sourceFile, extra] = parsed.positionals;
435617
435473
  if (!sourceFile) {
435618
435474
  console.error(`Missing mod file.`);
435619
- printUsage11();
435475
+ printUsage10();
435620
435476
  return 1;
435621
435477
  }
435622
435478
  if (extra) {
435623
435479
  console.error(`Unexpected argument: ${extra}`);
435624
- printUsage11();
435480
+ printUsage10();
435625
435481
  return 1;
435626
435482
  }
435627
435483
  const packageName = parsed.values.name;
435628
435484
  if (typeof packageName !== "string" || !packageName.trim()) {
435629
435485
  console.error(`Missing required --name <package-name>.`);
435630
- printUsage11();
435486
+ printUsage10();
435631
435487
  return 1;
435632
435488
  }
435633
435489
  try {
@@ -435649,7 +435505,7 @@ async function runPackageScaffold(argv) {
435649
435505
  async function runModsSubcommand(argv, options = {}) {
435650
435506
  const [action3, ...rest4] = argv;
435651
435507
  if (!action3 || action3 === "help" || action3 === "--help" || action3 === "-h") {
435652
- printUsage11();
435508
+ printUsage10();
435653
435509
  return 0;
435654
435510
  }
435655
435511
  switch (action3) {
@@ -435665,7 +435521,7 @@ async function runModsSubcommand(argv, options = {}) {
435665
435521
  return runPackageMutation(action3, rest4, options);
435666
435522
  default:
435667
435523
  console.error(`Unknown mods action: ${action3}`);
435668
- printUsage11();
435524
+ printUsage10();
435669
435525
  return 1;
435670
435526
  }
435671
435527
  }
@@ -435745,8 +435601,8 @@ var init_sandbox_files = __esm(() => {
435745
435601
  // src/cli/subcommands/sandbox.ts
435746
435602
  import { readFile as readFile24, stat as stat16, writeFile as writeFile17 } from "node:fs/promises";
435747
435603
  import { basename as basename26, resolve as resolve36 } from "node:path";
435748
- import { parseArgs as parseArgs15 } from "node:util";
435749
- function printUsage12() {
435604
+ import { parseArgs as parseArgs14 } from "node:util";
435605
+ function printUsage11() {
435750
435606
  console.log(`
435751
435607
  Usage:
435752
435608
  letta sandbox upload <local-path>
@@ -435760,7 +435616,7 @@ Notes:
435760
435616
  `.trim());
435761
435617
  }
435762
435618
  function parseSandboxArgs(argv) {
435763
- return parseArgs15({
435619
+ return parseArgs14({
435764
435620
  args: argv,
435765
435621
  options: SANDBOX_OPTIONS,
435766
435622
  strict: true,
@@ -435800,17 +435656,17 @@ async function runSandboxSubcommand(argv, deps = {}) {
435800
435656
  parsed = parseSandboxArgs(argv);
435801
435657
  } catch (error5) {
435802
435658
  console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
435803
- printUsage12();
435659
+ printUsage11();
435804
435660
  return 1;
435805
435661
  }
435806
435662
  const [action3, path48] = parsed.positionals;
435807
435663
  if (parsed.values.help || !action3 || action3 === "help") {
435808
- printUsage12();
435664
+ printUsage11();
435809
435665
  return 0;
435810
435666
  }
435811
435667
  if (action3 !== "upload" && action3 !== "download" || !path48) {
435812
435668
  console.error("Error: expected upload or download with a file path");
435813
- printUsage12();
435669
+ printUsage11();
435814
435670
  return 1;
435815
435671
  }
435816
435672
  try {
@@ -435854,8 +435710,8 @@ var init_sandbox2 = __esm(() => {
435854
435710
  });
435855
435711
 
435856
435712
  // src/cli/subcommands/secret.ts
435857
- import { parseArgs as parseArgs16 } from "node:util";
435858
- function printUsage13() {
435713
+ import { parseArgs as parseArgs15 } from "node:util";
435714
+ function printUsage12() {
435859
435715
  console.log(`
435860
435716
  Usage:
435861
435717
  letta secret set KEY --env SOURCE_VAR Set KEY from environment variable SOURCE_VAR
@@ -435880,7 +435736,7 @@ Notes:
435880
435736
  `.trim());
435881
435737
  }
435882
435738
  function parseSecretArgs(argv) {
435883
- return parseArgs16({
435739
+ return parseArgs15({
435884
435740
  args: argv,
435885
435741
  options: SECRET_OPTIONS,
435886
435742
  strict: true,
@@ -435915,11 +435771,11 @@ async function runSecretSubcommand(argv, deps = {}) {
435915
435771
  parsed = parseSecretArgs(argv);
435916
435772
  } catch (error5) {
435917
435773
  printError(error5);
435918
- printUsage13();
435774
+ printUsage12();
435919
435775
  return 1;
435920
435776
  }
435921
435777
  if (parsed.values.help || parsed.positionals.length === 0) {
435922
- printUsage13();
435778
+ printUsage12();
435923
435779
  return parsed.values.help ? 0 : 1;
435924
435780
  }
435925
435781
  const [verb, rawKey, rawValue] = parsed.positionals;
@@ -435929,7 +435785,7 @@ async function runSecretSubcommand(argv, deps = {}) {
435929
435785
  }
435930
435786
  switch (verb) {
435931
435787
  case "help": {
435932
- printUsage13();
435788
+ printUsage12();
435933
435789
  return 0;
435934
435790
  }
435935
435791
  case "list": {
@@ -436037,7 +435893,7 @@ async function runSecretSubcommand(argv, deps = {}) {
436037
435893
  }
436038
435894
  default: {
436039
435895
  console.error(`Unknown subcommand '${verb ?? ""}'.`);
436040
- printUsage13();
435896
+ printUsage12();
436041
435897
  return 1;
436042
435898
  }
436043
435899
  }
@@ -436055,7 +435911,7 @@ var init_secret = __esm(() => {
436055
435911
  });
436056
435912
 
436057
435913
  // src/cli/subcommands/app-server.ts
436058
- import { parseArgs as parseArgs17 } from "node:util";
435914
+ import { parseArgs as parseArgs16 } from "node:util";
436059
435915
  function printAppServerHelp() {
436060
435916
  console.log(`Usage: letta server --listen [url]
436061
435917
 
@@ -436103,7 +435959,7 @@ Stopped App Server (${signal}).`);
436103
435959
  async function runAppServerSubcommand(argv) {
436104
435960
  let parsed;
436105
435961
  try {
436106
- parsed = parseArgs17({
435962
+ parsed = parseArgs16({
436107
435963
  args: argv,
436108
435964
  allowPositionals: false,
436109
435965
  options: {
@@ -436688,7 +436544,7 @@ var init_setup6 = __esm(async () => {
436688
436544
  });
436689
436545
 
436690
436546
  // src/cli/subcommands/setup.ts
436691
- function printUsage14() {
436547
+ function printUsage13() {
436692
436548
  console.log(`
436693
436549
  Usage:
436694
436550
  letta setup
@@ -436699,12 +436555,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
436699
436555
  async function runSetupSubcommand(argv) {
436700
436556
  const [arg, ...rest4] = argv;
436701
436557
  if (arg === "help" || arg === "--help" || arg === "-h") {
436702
- printUsage14();
436558
+ printUsage13();
436703
436559
  return 0;
436704
436560
  }
436705
436561
  if (arg || rest4.length > 0) {
436706
436562
  console.error(`Unexpected arguments: ${[arg, ...rest4].filter(Boolean).join(" ")}`);
436707
- printUsage14();
436563
+ printUsage13();
436708
436564
  return 1;
436709
436565
  }
436710
436566
  await settingsManager.initialize();
@@ -436719,8 +436575,8 @@ var init_setup7 = __esm(async () => {
436719
436575
  // src/cli/subcommands/shared-memory.ts
436720
436576
  import { existsSync as existsSync61 } from "node:fs";
436721
436577
  import { join as join75 } from "node:path";
436722
- import { parseArgs as parseArgs18 } from "node:util";
436723
- function printUsage15() {
436578
+ import { parseArgs as parseArgs17 } from "node:util";
436579
+ function printUsage14() {
436724
436580
  console.log(`
436725
436581
  Usage:
436726
436582
  letta shared-memory list [--agent <id>]
@@ -436755,7 +436611,7 @@ Examples:
436755
436611
  `.trim());
436756
436612
  }
436757
436613
  function parseSharedMemoryArgs(argv) {
436758
- return parseArgs18({
436614
+ return parseArgs17({
436759
436615
  args: argv,
436760
436616
  options: SHARED_MEMORY_OPTIONS,
436761
436617
  strict: true,
@@ -436831,12 +436687,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
436831
436687
  parsed = parseSharedMemoryArgs(argv);
436832
436688
  } catch (error5) {
436833
436689
  console.error(error5 instanceof Error ? error5.message : String(error5));
436834
- printUsage15();
436690
+ printUsage14();
436835
436691
  return 1;
436836
436692
  }
436837
436693
  const [action3, reference] = parsed.positionals;
436838
436694
  if (parsed.values.help || !action3 || action3 === "help") {
436839
- printUsage15();
436695
+ printUsage14();
436840
436696
  return 0;
436841
436697
  }
436842
436698
  if (isLocalBackendEnvEnabled()) {
@@ -436941,7 +436797,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
436941
436797
  return result2.failed > 0 ? 1 : 0;
436942
436798
  }
436943
436799
  console.error(`Unknown action: ${action3}`);
436944
- printUsage15();
436800
+ printUsage14();
436945
436801
  return 1;
436946
436802
  } catch (error5) {
436947
436803
  console.error(error5 instanceof Error ? error5.message : String(error5));
@@ -438449,8 +438305,8 @@ import {
438449
438305
  import { mkdir as mkdir14, readdir as readdir13 } from "node:fs/promises";
438450
438306
  import { tmpdir as tmpdir11 } from "node:os";
438451
438307
  import { basename as basename27, dirname as dirname33, join as join76, normalize as normalize5, resolve as resolve37, sep as sep8 } from "node:path";
438452
- import { parseArgs as parseArgs19, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
438453
- function printUsage16() {
438308
+ import { parseArgs as parseArgs18, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
438309
+ function printUsage15() {
438454
438310
  console.log(`
438455
438311
  Usage:
438456
438312
  letta install <thing> [--agent <id> | -n <agent name>] [--force]
@@ -438477,7 +438333,7 @@ Options:
438477
438333
  `.trim());
438478
438334
  }
438479
438335
  function parseSkillsArgs(argv) {
438480
- return parseArgs19({
438336
+ return parseArgs18({
438481
438337
  args: argv,
438482
438338
  options: SKILLS_OPTIONS,
438483
438339
  strict: true,
@@ -439125,17 +438981,17 @@ async function runInstall(argv, options = {}) {
439125
438981
  parsed = parseSkillsArgs(argv);
439126
438982
  } catch (error5) {
439127
438983
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
439128
- printUsage16();
438984
+ printUsage15();
439129
438985
  return 1;
439130
438986
  }
439131
438987
  const [specifier] = parsed.positionals;
439132
438988
  if (parsed.values.help || !specifier || specifier === "help") {
439133
- printUsage16();
438989
+ printUsage15();
439134
438990
  return 0;
439135
438991
  }
439136
438992
  if (parsed.positionals.length > 1) {
439137
438993
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
439138
- printUsage16();
438994
+ printUsage15();
439139
438995
  return 1;
439140
438996
  }
439141
438997
  if (specifier.startsWith("npm:")) {
@@ -439226,16 +439082,16 @@ async function runList3(argv) {
439226
439082
  parsed = parseSkillsArgs(argv);
439227
439083
  } catch (error5) {
439228
439084
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
439229
- printUsage16();
439085
+ printUsage15();
439230
439086
  return 1;
439231
439087
  }
439232
439088
  if (parsed.values.help) {
439233
- printUsage16();
439089
+ printUsage15();
439234
439090
  return 0;
439235
439091
  }
439236
439092
  if (parsed.positionals.length > 0) {
439237
439093
  console.error(`Unexpected argument: ${parsed.positionals[0]}`);
439238
- printUsage16();
439094
+ printUsage15();
439239
439095
  return 1;
439240
439096
  }
439241
439097
  try {
@@ -439256,17 +439112,17 @@ async function runDelete(argv) {
439256
439112
  parsed = parseSkillsArgs(argv);
439257
439113
  } catch (error5) {
439258
439114
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
439259
- printUsage16();
439115
+ printUsage15();
439260
439116
  return 1;
439261
439117
  }
439262
439118
  const [skillName] = parsed.positionals;
439263
439119
  if (parsed.values.help || !skillName || skillName === "help") {
439264
- printUsage16();
439120
+ printUsage15();
439265
439121
  return 0;
439266
439122
  }
439267
439123
  if (parsed.positionals.length > 1) {
439268
439124
  console.error(`Unexpected argument: ${parsed.positionals[1]}`);
439269
- printUsage16();
439125
+ printUsage15();
439270
439126
  return 1;
439271
439127
  }
439272
439128
  const agentId = getExplicitAgentId2(parsed.values);
@@ -439306,11 +439162,11 @@ async function runSkillsSubcommand(argv) {
439306
439162
  case "help":
439307
439163
  case "--help":
439308
439164
  case "-h":
439309
- printUsage16();
439165
+ printUsage15();
439310
439166
  return 0;
439311
439167
  default:
439312
439168
  console.error(`Unknown action: ${action3}`);
439313
- printUsage16();
439169
+ printUsage15();
439314
439170
  return 1;
439315
439171
  }
439316
439172
  }
@@ -439329,8 +439185,8 @@ var init_skills4 = __esm(() => {
439329
439185
  });
439330
439186
 
439331
439187
  // src/cli/subcommands/teleport.ts
439332
- import { parseArgs as parseArgs20 } from "node:util";
439333
- function printUsage17() {
439188
+ import { parseArgs as parseArgs19 } from "node:util";
439189
+ function printUsage16() {
439334
439190
  console.log(`
439335
439191
  Usage:
439336
439192
  letta teleport list
@@ -439353,7 +439209,7 @@ Notes:
439353
439209
  `.trim());
439354
439210
  }
439355
439211
  function parseTeleportArgs(argv) {
439356
- return parseArgs20({
439212
+ return parseArgs19({
439357
439213
  args: argv,
439358
439214
  options: TELEPORT_OPTIONS,
439359
439215
  strict: true,
@@ -439426,12 +439282,12 @@ async function runTeleportSubcommand(argv, deps = {}) {
439426
439282
  parsed = parseTeleportArgs(argv);
439427
439283
  } catch (error5) {
439428
439284
  console.error(`Error: ${error5 instanceof Error ? error5.message : error5}`);
439429
- printUsage17();
439285
+ printUsage16();
439430
439286
  return 1;
439431
439287
  }
439432
439288
  const [action3] = parsed.positionals;
439433
439289
  if (parsed.values.help || !action3 || action3 === "help") {
439434
- printUsage17();
439290
+ printUsage16();
439435
439291
  return 0;
439436
439292
  }
439437
439293
  try {
@@ -439867,8 +439723,8 @@ var init_review = () => {};
439867
439723
 
439868
439724
  // src/cli/subcommands/trajectories.ts
439869
439725
  import { readFile as readFile28 } from "node:fs/promises";
439870
- import { parseArgs as parseArgs21 } from "node:util";
439871
- function printUsage18() {
439726
+ import { parseArgs as parseArgs20 } from "node:util";
439727
+ function printUsage17() {
439872
439728
  console.log(`
439873
439729
  Usage:
439874
439730
  letta trajectories export [options]
@@ -440006,7 +439862,7 @@ ${results.length} session(s) matched "${keyword}"`);
440006
439862
  return 0;
440007
439863
  }
440008
439864
  function parseTrajectoriesArgs(argv) {
440009
- return parseArgs21({
439865
+ return parseArgs20({
440010
439866
  args: argv,
440011
439867
  options: TRAJECTORIES_OPTIONS,
440012
439868
  strict: true,
@@ -440019,12 +439875,12 @@ async function runTrajectoriesSubcommand(argv) {
440019
439875
  parsed = parseTrajectoriesArgs(argv);
440020
439876
  } catch (error5) {
440021
439877
  console.error(`Error: ${error5 instanceof Error ? error5.message : String(error5)}`);
440022
- printUsage18();
439878
+ printUsage17();
440023
439879
  return 1;
440024
439880
  }
440025
439881
  const [action3] = parsed.positionals;
440026
439882
  if (parsed.values.help || action3 === "help" || !action3) {
440027
- printUsage18();
439883
+ printUsage17();
440028
439884
  return parsed.values.help || action3 === "help" ? 0 : 1;
440029
439885
  }
440030
439886
  const asJson = Boolean(parsed.values.json);
@@ -440056,7 +439912,7 @@ async function runTrajectoriesSubcommand(argv) {
440056
439912
  }
440057
439913
  if (action3 !== "export") {
440058
439914
  console.error(`Unknown command: ${action3}`);
440059
- printUsage18();
439915
+ printUsage17();
440060
439916
  return 1;
440061
439917
  }
440062
439918
  const options = {
@@ -441605,9 +441461,9 @@ class ChannelRichDraftStreamerImpl {
441605
441461
  return;
441606
441462
  }
441607
441463
  const record5 = asRecord10(chunk2);
441608
- const messageType = stringValue6(record5?.message_type);
441464
+ const messageType = stringValue5(record5?.message_type);
441609
441465
  if (messageType === "tool_return_message") {
441610
- const toolCallId = stringValue6(record5?.tool_call_id);
441466
+ const toolCallId = stringValue5(record5?.tool_call_id);
441611
441467
  if (toolCallId) {
441612
441468
  this.finishCall(toolCallId);
441613
441469
  }
@@ -441900,14 +441756,14 @@ function extractToolCallFragments2(record5) {
441900
441756
  const fragments = [];
441901
441757
  for (const rawToolCall of rawToolCalls) {
441902
441758
  const toolCall = asRecord10(rawToolCall);
441903
- const toolCallId = stringValue6(toolCall?.tool_call_id);
441759
+ const toolCallId = stringValue5(toolCall?.tool_call_id);
441904
441760
  if (!toolCallId) {
441905
441761
  continue;
441906
441762
  }
441907
441763
  fragments.push({
441908
441764
  toolCallId,
441909
- name: stringValue6(toolCall?.name),
441910
- argumentsDelta: stringValue6(toolCall?.arguments)
441765
+ name: stringValue5(toolCall?.name),
441766
+ argumentsDelta: stringValue5(toolCall?.arguments)
441911
441767
  });
441912
441768
  }
441913
441769
  return fragments;
@@ -442027,7 +441883,7 @@ function buildDraftId(seed) {
442027
441883
  function asRecord10(value) {
442028
441884
  return value && typeof value === "object" ? value : null;
442029
441885
  }
442030
- function stringValue6(value) {
441886
+ function stringValue5(value) {
442031
441887
  return typeof value === "string" ? value : undefined;
442032
441888
  }
442033
441889
  var MESSAGE_CHANNEL_TOOL_NAMES, DEFAULT_DRAFT_DEBOUNCE_MS = 1000, MIN_DRAFT_TEXT_LENGTH = 1;
@@ -444895,14 +444751,14 @@ var exports_channel_gateway = {};
444895
444751
  __export(exports_channel_gateway, {
444896
444752
  runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
444897
444753
  });
444898
- import { parseArgs as parseArgs22 } from "node:util";
444754
+ import { parseArgs as parseArgs21 } from "node:util";
444899
444755
  function isGatewayCommandEnvelope(value) {
444900
444756
  return Boolean(value && typeof value === "object" && "type" in value && value.type === "command" && "requestId" in value && typeof value.requestId === "string" && "command" in value && value.command && typeof value.command === "object");
444901
444757
  }
444902
444758
  async function runChannelGatewaySubcommand(argv) {
444903
444759
  let values3;
444904
444760
  try {
444905
- ({ values: values3 } = parseArgs22({
444761
+ ({ values: values3 } = parseArgs21({
444906
444762
  args: argv,
444907
444763
  strict: true,
444908
444764
  allowPositionals: false,
@@ -445042,7 +444898,6 @@ function subcommandNeedsEarlyBackendMode(command) {
445042
444898
  case "sandbox":
445043
444899
  case "secret":
445044
444900
  case "server":
445045
- case "cloud-mcp":
445046
444901
  case "shared-memory":
445047
444902
  case "skills":
445048
444903
  case "teleport":
@@ -445087,8 +444942,6 @@ async function runSubcommand(argv) {
445087
444942
  return runTeleportSubcommand(rest4);
445088
444943
  case "server":
445089
444944
  return runServerSubcommand(rest4);
445090
- case "cloud-mcp":
445091
- return runCloudMcpSubcommand(rest4);
445092
444945
  case "feedback":
445093
444946
  return runFeedbackSubcommand(rest4);
445094
444947
  case "remote":
@@ -445126,7 +444979,6 @@ var init_router = __esm(async () => {
445126
444979
  init_agents6();
445127
444980
  init_backend3();
445128
444981
  init_channels();
445129
- init_cloud_mcp();
445130
444982
  init_connect();
445131
444983
  init_environments3();
445132
444984
  init_feedback3();
@@ -465838,6 +465690,110 @@ var init_LettaLoginOverlay = __esm(async () => {
465838
465690
  jsx_dev_runtime63 = __toESM(require_jsx_dev_runtime(), 1);
465839
465691
  });
465840
465692
 
465693
+ // src/backend/api/mcp-servers.ts
465694
+ function withTimeout3(promise2, timeoutMs, label) {
465695
+ let timer;
465696
+ const timeout = new Promise((_4, reject2) => {
465697
+ timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
465698
+ });
465699
+ return Promise.race([promise2, timeout]).finally(() => {
465700
+ if (timer !== undefined)
465701
+ clearTimeout(timer);
465702
+ });
465703
+ }
465704
+ function listServerMcpServers(client, timeoutMs = 1e4) {
465705
+ return withTimeout3(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
465706
+ }
465707
+ async function listLiveServerMcpTools(client, serverName2, timeoutMs = 15000) {
465708
+ const result2 = await withTimeout3(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName2}"`);
465709
+ if (!Array.isArray(result2))
465710
+ return [];
465711
+ return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
465712
+ }
465713
+ async function loadServerMcpEntries(client, timeoutMs = 15000) {
465714
+ const servers = await listServerMcpServers(client, timeoutMs);
465715
+ return Promise.all(servers.map(async (server2) => {
465716
+ try {
465717
+ const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
465718
+ return { server: server2, tools };
465719
+ } catch (cause) {
465720
+ return {
465721
+ server: server2,
465722
+ tools: [],
465723
+ toolsError: cause instanceof Error ? cause.message : String(cause)
465724
+ };
465725
+ }
465726
+ }));
465727
+ }
465728
+ function parseMcpMetadata(tool) {
465729
+ const metadata = tool.metadata_;
465730
+ const mcp = metadata?.mcp;
465731
+ if (typeof mcp !== "object" || mcp === null)
465732
+ return null;
465733
+ const { server_id, server_name } = mcp;
465734
+ return {
465735
+ ...typeof server_id === "string" && { serverId: server_id },
465736
+ ...typeof server_name === "string" && { serverName: server_name }
465737
+ };
465738
+ }
465739
+ async function listAgentMcpAttachments(client, agentId) {
465740
+ const attachments = [];
465741
+ for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
465742
+ if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
465743
+ continue;
465744
+ attachments.push({
465745
+ toolId: tool.id,
465746
+ toolName: tool.name,
465747
+ ...parseMcpMetadata(tool)
465748
+ });
465749
+ }
465750
+ return attachments;
465751
+ }
465752
+ function attachmentsForEntry(entry, attachments) {
465753
+ return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
465754
+ }
465755
+ function attachedToolNamesForEntry(entry, attachments) {
465756
+ return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
465757
+ }
465758
+ async function registerServerMcpTool(client, serverName2, toolName) {
465759
+ const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName2)}/${encodeURIComponent(toolName)}`);
465760
+ if (typeof result2?.id !== "string") {
465761
+ throw new Error(`Registering MCP tool "${toolName}" on server "${serverName2}" returned no tool id`);
465762
+ }
465763
+ return { id: result2.id };
465764
+ }
465765
+ async function attachServerMcpTools(client, agentId, serverName2, toolNames) {
465766
+ await Promise.all(toolNames.map(async (toolName) => {
465767
+ const { id: id2 } = await registerServerMcpTool(client, serverName2, toolName);
465768
+ await client.agents.tools.attach(id2, { agent_id: agentId });
465769
+ }));
465770
+ }
465771
+ async function detachServerMcpTools(client, agentId, toolIds) {
465772
+ await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
465773
+ }
465774
+ function refreshServerMcpServer(client, mcpServerId, agentId) {
465775
+ return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
465776
+ }
465777
+ function planServerMcpToggle(entry, attachments) {
465778
+ const attached = attachmentsForEntry(entry, attachments);
465779
+ if (attached.length > 0) {
465780
+ return {
465781
+ action: "detach",
465782
+ toolIds: attached.map((attachment) => attachment.toolId)
465783
+ };
465784
+ }
465785
+ return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
465786
+ }
465787
+ function describeServerMcpTarget(server2) {
465788
+ if ("server_url" in server2 && server2.server_url) {
465789
+ return server2.server_url;
465790
+ }
465791
+ if ("command" in server2 && server2.command) {
465792
+ return [server2.command, ...server2.args ?? []].join(" ");
465793
+ }
465794
+ return "";
465795
+ }
465796
+
465841
465797
  // src/cli/components/McpSelector.tsx
465842
465798
  function buildMcpRows(localStates, serverEntries) {
465843
465799
  return [
@@ -465954,7 +465910,6 @@ var import_react87, jsx_dev_runtime64, SOLID_LINE12 = "─", DISPLAY_PAGE_SIZE2
465954
465910
  var init_McpSelector = __esm(async () => {
465955
465911
  init_backend2();
465956
465912
  init_client2();
465957
- init_mcp_servers2();
465958
465913
  init_truncate_text();
465959
465914
  init_use_terminal_width();
465960
465915
  init_mcp_oauth();
@@ -475585,7 +475540,7 @@ var init_ToolCallMessageRich = __esm(async () => {
475585
475540
  let shellSemanticKind = null;
475586
475541
  let hasShellDescription = false;
475587
475542
  if (!isQuestionTool(rawName)) {
475588
- const parseArgs23 = () => {
475543
+ const parseArgs22 = () => {
475589
475544
  if (!argsText.trim()) {
475590
475545
  return { formatted: null, parseable: true };
475591
475546
  }
@@ -475599,7 +475554,7 @@ var init_ToolCallMessageRich = __esm(async () => {
475599
475554
  return { formatted: null, parseable: false };
475600
475555
  }
475601
475556
  };
475602
- const { formatted, parseable } = parseArgs23();
475557
+ const { formatted, parseable } = parseArgs22();
475603
475558
  const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
475604
475559
  if (!argsComplete) {
475605
475560
  args = "(…)";
@@ -477815,7 +477770,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
477815
477770
  buffersRef.current.byId.set(cmdId, line);
477816
477771
  refreshDerived();
477817
477772
  }
477818
- function parseArgs23(msg) {
477773
+ function parseArgs22(msg) {
477819
477774
  return msg.trim().split(/\s+/).filter(Boolean);
477820
477775
  }
477821
477776
  function formatConnectUsage() {
@@ -478197,7 +478152,7 @@ ${formatBedrockUsage2()}`, false);
478197
478152
  }
478198
478153
  }
478199
478154
  async function handleConnect(ctx, msg) {
478200
- const parts = parseArgs23(msg);
478155
+ const parts = parseArgs22(msg);
478201
478156
  const providerToken = parts[1];
478202
478157
  if (!providerToken) {
478203
478158
  addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
@@ -498026,6 +497981,8 @@ function useFeedbackHandler(ctx) {
498026
497981
  await submitFeedbackMetadata(apiKey, settingsManager.getOrCreateDeviceId(), {
498027
497982
  message: resolvedMessage,
498028
497983
  feature: "letta-code",
497984
+ submission_source: "slash_command",
497985
+ client_type: getFeedbackClientType(),
498029
497986
  agent_id: agentId,
498030
497987
  session_id: telemetry.getSessionId(),
498031
497988
  run_id: lastRunIdRef.current ?? undefined,
@@ -509140,7 +509097,6 @@ USAGE
509140
509097
  letta teleport ... Move the current conversation between environments
509141
509098
  letta messages ... Messages subcommands (JSON-only)
509142
509099
  letta mcp ... List, search, and call MCP servers available to an agent
509143
- letta cloud-mcp ... Legacy server-side MCP commands (JSON-only)
509144
509100
  letta mods ... List and manage local mods
509145
509101
  letta sandbox ... Transfer files to or from the current Cloud sandbox
509146
509102
  letta server ... Run a remote environment, channels, or the App Server
@@ -509168,7 +509124,6 @@ SUBCOMMANDS
509168
509124
  letta messages search --query <text> [--all-agents]
509169
509125
  letta messages list [--agent <id>]
509170
509126
  letta messages transcript --conversation <id> [--out <path>]
509171
- letta cloud-mcp list|tools|run ... [--agent <id>]
509172
509127
  letta mods list [--agent <id>]
509173
509128
  letta mods package <mod-file> --name <package-name> [--out <dir>]
509174
509129
  letta mods enable <package-spec>
@@ -512995,4 +512950,4 @@ function registerBunOAuthFlows() {
512995
512950
  registerBunOAuthFlows();
512996
512951
  await init_src5().then(() => exports_src2);
512997
512952
 
512998
- //# debugId=39DF2EA197BB152964756E2164756E21
512953
+ //# debugId=A04282B12C1CC94F64756E2164756E21