@letta-ai/letta-code 0.31.0 → 0.31.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/hooks/executor.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-launchers.d.ts +3 -1
- package/dist/types/tools/impl/shell-launchers.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-runner.d.ts.map +1 -1
- package/dist/types/utils/systemd-workload-scope.d.ts +15 -0
- package/dist/types/utils/systemd-workload-scope.d.ts.map +1 -0
- package/letta.js +427 -166
- package/package.json +1 -1
- package/skills/using-server-mcp/SKILL.md +36 -0
package/letta.js
CHANGED
|
@@ -5509,7 +5509,7 @@ var package_default;
|
|
|
5509
5509
|
var init_package = __esm(() => {
|
|
5510
5510
|
package_default = {
|
|
5511
5511
|
name: "@letta-ai/letta-code",
|
|
5512
|
-
version: "0.31.
|
|
5512
|
+
version: "0.31.2",
|
|
5513
5513
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5514
5514
|
type: "module",
|
|
5515
5515
|
packageManager: "bun@1.3.10",
|
|
@@ -84634,21 +84634,24 @@ function stripPowerShellUtf8OutputPrefix(command) {
|
|
|
84634
84634
|
const leadingWhitespace = command.slice(0, command.length - trimmed.length);
|
|
84635
84635
|
return `${leadingWhitespace}${trimmed.slice(POWERSHELL_UTF8_OUTPUT_PREFIX.length)}`;
|
|
84636
84636
|
}
|
|
84637
|
-
function buildPowerShellCommand(command, envAliases = []) {
|
|
84637
|
+
function buildPowerShellCommand(command, envAliases = [], preserveExitCode = false) {
|
|
84638
84638
|
const powerShellCommand = stripPowerShellUtf8OutputPrefix(normalizePowerShellCommand(command));
|
|
84639
84639
|
const aliases = [
|
|
84640
84640
|
...new Set([...POWERSHELL_ENV_ALIASES, ...envAliases])
|
|
84641
84641
|
].filter(isValidEnvAlias);
|
|
84642
84642
|
const aliasPrelude = aliases.map((name) => `$${name} = $env:${name}`).join("; ");
|
|
84643
|
-
|
|
84643
|
+
const encodedCommand = Buffer.from(powerShellCommand, "utf16le").toString("base64");
|
|
84644
|
+
const exitCodePrefix = preserveExitCode ? "$global:LASTEXITCODE = $null; " + `$__lettaHookText = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('${encodedCommand}')); ` + "$__lettaTokens = $null; $__lettaParseErrors = $null; " + "$__lettaHookAst = [System.Management.Automation.Language.Parser]::ParseInput($__lettaHookText, [ref]$__lettaTokens, [ref]$__lettaParseErrors); " + "$__lettaStatements = $__lettaHookAst.EndBlock.Statements; " + "$__lettaFinalStatement = if ($__lettaStatements.Count -gt 0) { $__lettaStatements[$__lettaStatements.Count - 1] } else { $null }; " + "$__lettaFinalPipelineElement = if ($__lettaFinalStatement -is [System.Management.Automation.Language.PipelineAst]) { $__lettaFinalStatement.PipelineElements[$__lettaFinalStatement.PipelineElements.Count - 1] } else { $null }; " + "$__lettaFinalCommandName = if ($__lettaFinalPipelineElement -is [System.Management.Automation.Language.CommandAst]) { $__lettaFinalPipelineElement.GetCommandName() } else { $null }; " : "";
|
|
84645
|
+
const exitCodeSuffix = preserveExitCode ? POWERSHELL_EXIT_CODE_SUFFIX : "";
|
|
84646
|
+
return prefixPowerShellCommandWithUtf8Output(`${aliasPrelude}; ${exitCodePrefix}${powerShellCommand}${exitCodeSuffix}`);
|
|
84644
84647
|
}
|
|
84645
|
-
function windowsLaunchers(command, envAliases = []) {
|
|
84648
|
+
function windowsLaunchers(command, envAliases = [], preserveExitCode = false) {
|
|
84646
84649
|
const trimmed = command.trim();
|
|
84647
84650
|
if (!trimmed)
|
|
84648
84651
|
return [];
|
|
84649
84652
|
const launchers = [];
|
|
84650
84653
|
const seen = new Set;
|
|
84651
|
-
const powerShellCommand = buildPowerShellCommand(trimmed, envAliases);
|
|
84654
|
+
const powerShellCommand = buildPowerShellCommand(trimmed, envAliases, preserveExitCode);
|
|
84652
84655
|
pushUnique(launchers, seen, [
|
|
84653
84656
|
"pwsh",
|
|
84654
84657
|
"-NoProfile",
|
|
@@ -84786,11 +84789,13 @@ function unixLaunchers(command, login) {
|
|
|
84786
84789
|
function buildShellLaunchers(command, options) {
|
|
84787
84790
|
const login = options?.login ?? false;
|
|
84788
84791
|
const commandToRun = withStrictShellPrelude(command, options?.env);
|
|
84789
|
-
return process.platform === "win32" ? windowsLaunchers(commandToRun, options?.powershellEnvAliases) : unixLaunchers(commandToRun, login);
|
|
84792
|
+
return process.platform === "win32" ? windowsLaunchers(commandToRun, options?.powershellEnvAliases, options?.preservePowerShellExitCode) : unixLaunchers(commandToRun, login);
|
|
84790
84793
|
}
|
|
84791
84794
|
var SEP = "\x00", STRICT_SHELL_ENV_VAR = "LETTA_BASH_STRICT", STRICT_SHELL_PRELUDE = "set -euo pipefail", POWERSHELL_UTF8_OUTPUT_PREFIX = `try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}
|
|
84792
|
-
`, POWERSHELL_ENV_ALIASES, WINDOWS_PWSH_FALLBACK_PATH = "C:\\Program Files\\PowerShell\\7\\pwsh.exe", WINDOWS_POWERSHELL_FALLBACK_PATH = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
|
|
84795
|
+
`, POWERSHELL_EXIT_CODE_SUFFIX, POWERSHELL_ENV_ALIASES, WINDOWS_PWSH_FALLBACK_PATH = "C:\\Program Files\\PowerShell\\7\\pwsh.exe", WINDOWS_POWERSHELL_FALLBACK_PATH = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
|
|
84793
84796
|
var init_shell_launchers = __esm(() => {
|
|
84797
|
+
POWERSHELL_EXIT_CODE_SUFFIX = `
|
|
84798
|
+
$__lettaCommandSucceeded = $?; ` + "if ($__lettaCommandSucceeded) { exit 0 }; " + "$__lettaFinalCommand = $null; " + "if ($null -ne $__lettaFinalCommandName) { try { $__lettaFinalCommand = $ExecutionContext.InvokeCommand.GetCommand($__lettaFinalCommandName, [System.Management.Automation.CommandTypes]::All) } catch {} }; " + "while ($__lettaFinalCommand -is [System.Management.Automation.AliasInfo]) { $__lettaFinalCommand = $__lettaFinalCommand.ResolvedCommand }; " + "if (($__lettaFinalCommand.CommandType -eq [System.Management.Automation.CommandTypes]::Application) -and ($null -ne $LASTEXITCODE) -and ($LASTEXITCODE -ne 0)) { exit $LASTEXITCODE }; " + "exit 1";
|
|
84794
84799
|
POWERSHELL_ENV_ALIASES = [
|
|
84795
84800
|
"MEMORY_DIR",
|
|
84796
84801
|
"LETTA_MEMORY_DIR",
|
|
@@ -85050,7 +85055,9 @@ async function executeCommandHook(hook, input, workingDirectory = process.cwd())
|
|
|
85050
85055
|
const startTime = Date.now();
|
|
85051
85056
|
const timeout = hook.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
85052
85057
|
const inputJson = JSON.stringify(input);
|
|
85053
|
-
const launchers = buildShellLaunchers(hook.command
|
|
85058
|
+
const launchers = buildShellLaunchers(hook.command, {
|
|
85059
|
+
preservePowerShellExitCode: true
|
|
85060
|
+
});
|
|
85054
85061
|
if (launchers.length === 0) {
|
|
85055
85062
|
return {
|
|
85056
85063
|
exitCode: 1 /* ERROR */,
|
|
@@ -92337,6 +92344,27 @@ var init_shell_env = __esm(() => {
|
|
|
92337
92344
|
init_ripgrep_manager();
|
|
92338
92345
|
});
|
|
92339
92346
|
|
|
92347
|
+
// src/utils/systemd-workload-scope.ts
|
|
92348
|
+
function wrapManagedWorkloadLauncher(launcher, options = {}) {
|
|
92349
|
+
const env2 = options.env ?? process.env;
|
|
92350
|
+
const platform2 = options.platform ?? process.platform;
|
|
92351
|
+
const slice = env2[WORKLOAD_SYSTEMD_SLICE_ENV]?.trim();
|
|
92352
|
+
if (launcher.length === 0 || platform2 !== "linux" || !slice) {
|
|
92353
|
+
return launcher;
|
|
92354
|
+
}
|
|
92355
|
+
return [
|
|
92356
|
+
"systemd-run",
|
|
92357
|
+
"--scope",
|
|
92358
|
+
"--quiet",
|
|
92359
|
+
"--collect",
|
|
92360
|
+
"--property=TimeoutStopSec=5s",
|
|
92361
|
+
`--slice=${slice}`,
|
|
92362
|
+
"--",
|
|
92363
|
+
...launcher
|
|
92364
|
+
];
|
|
92365
|
+
}
|
|
92366
|
+
var WORKLOAD_SYSTEMD_SLICE_ENV = "LETTA_WORKLOAD_SYSTEMD_SLICE";
|
|
92367
|
+
|
|
92340
92368
|
// src/tools/impl/github-pull-request-tracker.ts
|
|
92341
92369
|
function conversationTags(conversation) {
|
|
92342
92370
|
const tags = typeof conversation === "object" && conversation !== null ? Reflect.get(conversation, "tags") : undefined;
|
|
@@ -92772,7 +92800,10 @@ function spawnPtyProcess(launcher, options, events) {
|
|
|
92772
92800
|
return typeof Bun !== "undefined" ? spawnPtyBridgeProcess(launcher, options, events) : spawnNativePtyProcess(launcher, options, events);
|
|
92773
92801
|
}
|
|
92774
92802
|
function startShellProcess(launcher, options) {
|
|
92775
|
-
const
|
|
92803
|
+
const managedLauncher = wrapManagedWorkloadLauncher(launcher, {
|
|
92804
|
+
env: options.env
|
|
92805
|
+
});
|
|
92806
|
+
const [executable] = managedLauncher;
|
|
92776
92807
|
if (!executable) {
|
|
92777
92808
|
throw new ShellExecutionError("Executable is required");
|
|
92778
92809
|
}
|
|
@@ -92878,7 +92909,7 @@ function startShellProcess(launcher, options) {
|
|
|
92878
92909
|
}
|
|
92879
92910
|
};
|
|
92880
92911
|
try {
|
|
92881
|
-
processHandle = options.tty ? spawnPtyProcess(
|
|
92912
|
+
processHandle = options.tty ? spawnPtyProcess(managedLauncher, options, events) : spawnPipeProcess(managedLauncher, options, events);
|
|
92882
92913
|
} catch (error4) {
|
|
92883
92914
|
completed = true;
|
|
92884
92915
|
cleanup();
|
|
@@ -113258,7 +113289,12 @@ async function executeSubagent(type3, config, model, userPrompt, subagentId, isR
|
|
|
113258
113289
|
if (sandbox) {
|
|
113259
113290
|
debugLog("subagent", `memory subagent child sandboxed via ${sandbox.backend}`);
|
|
113260
113291
|
}
|
|
113261
|
-
const
|
|
113292
|
+
const managedLauncher = wrapManagedWorkloadLauncher([spawnLauncher.command, ...spawnLauncher.args], { env: spawnEnv });
|
|
113293
|
+
const [managedCommand, ...managedArgs] = managedLauncher;
|
|
113294
|
+
if (!managedCommand) {
|
|
113295
|
+
throw new Error("Subagent executable is required");
|
|
113296
|
+
}
|
|
113297
|
+
const proc2 = spawn5(managedCommand, managedArgs, {
|
|
113262
113298
|
cwd: subagentWorkingDirectory,
|
|
113263
113299
|
env: spawnEnv
|
|
113264
113300
|
});
|
|
@@ -415677,6 +415713,330 @@ var init_server = __esm(async () => {
|
|
|
415677
415713
|
]);
|
|
415678
415714
|
});
|
|
415679
415715
|
|
|
415716
|
+
// src/backend/api/mcp-servers.ts
|
|
415717
|
+
function getString2(record3, key2) {
|
|
415718
|
+
const value = record3[key2];
|
|
415719
|
+
return typeof value === "string" ? value : null;
|
|
415720
|
+
}
|
|
415721
|
+
function parseAgentConnectedMcpServer(value) {
|
|
415722
|
+
if (!isRecord(value)) {
|
|
415723
|
+
return null;
|
|
415724
|
+
}
|
|
415725
|
+
const id2 = getString2(value, "id");
|
|
415726
|
+
const serverName = getString2(value, "server_name");
|
|
415727
|
+
const serverType = getString2(value, "mcp_server_type");
|
|
415728
|
+
if (!id2 || !serverName || !serverType) {
|
|
415729
|
+
return null;
|
|
415730
|
+
}
|
|
415731
|
+
const target2 = getString2(value, "server_url") ?? [
|
|
415732
|
+
getString2(value, "command"),
|
|
415733
|
+
...Array.isArray(value.args) ? value.args : []
|
|
415734
|
+
].filter((item) => typeof item === "string").join(" ");
|
|
415735
|
+
return { id: id2, serverName, serverType, target: target2 };
|
|
415736
|
+
}
|
|
415737
|
+
function parseAgentConnectedMcpTool(value) {
|
|
415738
|
+
if (!isRecord(value)) {
|
|
415739
|
+
return null;
|
|
415740
|
+
}
|
|
415741
|
+
const id2 = getString2(value, "id");
|
|
415742
|
+
const name = getString2(value, "name");
|
|
415743
|
+
if (!id2 || !name) {
|
|
415744
|
+
return null;
|
|
415745
|
+
}
|
|
415746
|
+
const description = getString2(value, "description");
|
|
415747
|
+
return { id: id2, name, description };
|
|
415748
|
+
}
|
|
415749
|
+
function parseAgentMcpToolRunResult(value) {
|
|
415750
|
+
if (!isRecord(value)) {
|
|
415751
|
+
throw new Error("MCP tool run returned an invalid response");
|
|
415752
|
+
}
|
|
415753
|
+
const status = getString2(value, "status") ?? "unknown";
|
|
415754
|
+
return {
|
|
415755
|
+
status,
|
|
415756
|
+
funcReturn: value.func_return,
|
|
415757
|
+
stdout: value.stdout,
|
|
415758
|
+
stderr: value.stderr
|
|
415759
|
+
};
|
|
415760
|
+
}
|
|
415761
|
+
function withTimeout2(promise, timeoutMs, label) {
|
|
415762
|
+
let timer;
|
|
415763
|
+
const timeout = new Promise((_4, reject2) => {
|
|
415764
|
+
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
415765
|
+
});
|
|
415766
|
+
return Promise.race([promise, timeout]).finally(() => {
|
|
415767
|
+
if (timer !== undefined)
|
|
415768
|
+
clearTimeout(timer);
|
|
415769
|
+
});
|
|
415770
|
+
}
|
|
415771
|
+
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
415772
|
+
return withTimeout2(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
415773
|
+
}
|
|
415774
|
+
async function listAgentConnectedMcpServers(client, agentId, timeoutMs = 1e4) {
|
|
415775
|
+
const result2 = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers`), timeoutMs, "Listing agent-connected MCP servers");
|
|
415776
|
+
if (!Array.isArray(result2)) {
|
|
415777
|
+
return [];
|
|
415778
|
+
}
|
|
415779
|
+
return result2.map(parseAgentConnectedMcpServer).filter((server2) => server2 !== null);
|
|
415780
|
+
}
|
|
415781
|
+
async function listAgentConnectedMcpTools(client, agentId, mcpServerId, timeoutMs = 1e4) {
|
|
415782
|
+
const result2 = await withTimeout2(client.get(`/v1/agents/${encodeURIComponent(agentId)}/mcp-servers/${encodeURIComponent(mcpServerId)}/tools`), timeoutMs, "Listing agent-connected MCP server tools");
|
|
415783
|
+
if (!Array.isArray(result2)) {
|
|
415784
|
+
return [];
|
|
415785
|
+
}
|
|
415786
|
+
return result2.map(parseAgentConnectedMcpTool).filter((tool) => tool !== null);
|
|
415787
|
+
}
|
|
415788
|
+
async function runAgentConnectedMcpTool(params) {
|
|
415789
|
+
const result2 = await withTimeout2(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");
|
|
415790
|
+
return parseAgentMcpToolRunResult(result2);
|
|
415791
|
+
}
|
|
415792
|
+
async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
|
|
415793
|
+
const result2 = await withTimeout2(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
|
|
415794
|
+
if (!Array.isArray(result2))
|
|
415795
|
+
return [];
|
|
415796
|
+
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
415797
|
+
}
|
|
415798
|
+
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
415799
|
+
const servers = await listServerMcpServers(client, timeoutMs);
|
|
415800
|
+
return Promise.all(servers.map(async (server2) => {
|
|
415801
|
+
try {
|
|
415802
|
+
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
415803
|
+
return { server: server2, tools };
|
|
415804
|
+
} catch (cause) {
|
|
415805
|
+
return {
|
|
415806
|
+
server: server2,
|
|
415807
|
+
tools: [],
|
|
415808
|
+
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
415809
|
+
};
|
|
415810
|
+
}
|
|
415811
|
+
}));
|
|
415812
|
+
}
|
|
415813
|
+
function parseMcpMetadata(tool) {
|
|
415814
|
+
const metadata = tool.metadata_;
|
|
415815
|
+
const mcp = metadata?.mcp;
|
|
415816
|
+
if (typeof mcp !== "object" || mcp === null)
|
|
415817
|
+
return null;
|
|
415818
|
+
const { server_id, server_name } = mcp;
|
|
415819
|
+
return {
|
|
415820
|
+
...typeof server_id === "string" && { serverId: server_id },
|
|
415821
|
+
...typeof server_name === "string" && { serverName: server_name }
|
|
415822
|
+
};
|
|
415823
|
+
}
|
|
415824
|
+
async function listAgentMcpAttachments(client, agentId) {
|
|
415825
|
+
const attachments = [];
|
|
415826
|
+
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
415827
|
+
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
415828
|
+
continue;
|
|
415829
|
+
attachments.push({
|
|
415830
|
+
toolId: tool.id,
|
|
415831
|
+
toolName: tool.name,
|
|
415832
|
+
...parseMcpMetadata(tool)
|
|
415833
|
+
});
|
|
415834
|
+
}
|
|
415835
|
+
return attachments;
|
|
415836
|
+
}
|
|
415837
|
+
function attachmentsForEntry(entry, attachments) {
|
|
415838
|
+
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
415839
|
+
}
|
|
415840
|
+
function attachedToolNamesForEntry(entry, attachments) {
|
|
415841
|
+
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
415842
|
+
}
|
|
415843
|
+
async function registerServerMcpTool(client, serverName, toolName) {
|
|
415844
|
+
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
|
|
415845
|
+
if (typeof result2?.id !== "string") {
|
|
415846
|
+
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
|
|
415847
|
+
}
|
|
415848
|
+
return { id: result2.id };
|
|
415849
|
+
}
|
|
415850
|
+
async function attachServerMcpTools(client, agentId, serverName, toolNames) {
|
|
415851
|
+
await Promise.all(toolNames.map(async (toolName) => {
|
|
415852
|
+
const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
|
|
415853
|
+
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
415854
|
+
}));
|
|
415855
|
+
}
|
|
415856
|
+
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
415857
|
+
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
415858
|
+
}
|
|
415859
|
+
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
415860
|
+
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
415861
|
+
}
|
|
415862
|
+
function planServerMcpToggle(entry, attachments) {
|
|
415863
|
+
const attached = attachmentsForEntry(entry, attachments);
|
|
415864
|
+
if (attached.length > 0) {
|
|
415865
|
+
return {
|
|
415866
|
+
action: "detach",
|
|
415867
|
+
toolIds: attached.map((attachment) => attachment.toolId)
|
|
415868
|
+
};
|
|
415869
|
+
}
|
|
415870
|
+
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
415871
|
+
}
|
|
415872
|
+
function describeServerMcpTarget(server2) {
|
|
415873
|
+
if ("server_url" in server2 && server2.server_url) {
|
|
415874
|
+
return server2.server_url;
|
|
415875
|
+
}
|
|
415876
|
+
if ("command" in server2 && server2.command) {
|
|
415877
|
+
return [server2.command, ...server2.args ?? []].join(" ");
|
|
415878
|
+
}
|
|
415879
|
+
return "";
|
|
415880
|
+
}
|
|
415881
|
+
var init_mcp_servers2 = () => {};
|
|
415882
|
+
|
|
415883
|
+
// src/cli/subcommands/server-mcp.ts
|
|
415884
|
+
import { parseArgs as parseArgs16 } from "node:util";
|
|
415885
|
+
function printUsage13(stdout = console.log) {
|
|
415886
|
+
stdout(`
|
|
415887
|
+
Usage:
|
|
415888
|
+
letta server-mcp list [--agent <id>]
|
|
415889
|
+
letta server-mcp tools <mcp-server-id> [--agent <id>]
|
|
415890
|
+
letta server-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]
|
|
415891
|
+
|
|
415892
|
+
Actions:
|
|
415893
|
+
list List MCP servers connected to the agent
|
|
415894
|
+
tools List registered tools for one connected MCP server
|
|
415895
|
+
run Run one registered MCP tool through the agent-scoped server route
|
|
415896
|
+
|
|
415897
|
+
Aliases:
|
|
415898
|
+
list-servers, list_servers Alias for list
|
|
415899
|
+
list-tools, list_tools Alias for tools
|
|
415900
|
+
call, run-tool, run_tool Alias for run
|
|
415901
|
+
|
|
415902
|
+
Options:
|
|
415903
|
+
--agent <id> Agent ID. Defaults to LETTA_AGENT_ID or AGENT_ID
|
|
415904
|
+
--agent-id <id> Alias for --agent
|
|
415905
|
+
--args '<json>' JSON object passed as MCP tool arguments for run
|
|
415906
|
+
-h, --help Show this help
|
|
415907
|
+
|
|
415908
|
+
Notes:
|
|
415909
|
+
- Output is JSON only.
|
|
415910
|
+
- Requires a signed-in Letta Cloud agent with server-side MCP support.
|
|
415911
|
+
- Uses CLI auth; override with LETTA_API_KEY/LETTA_BASE_URL if needed.
|
|
415912
|
+
`.trim());
|
|
415913
|
+
}
|
|
415914
|
+
function parseServerMcpArgs(argv) {
|
|
415915
|
+
return parseArgs16({
|
|
415916
|
+
args: argv,
|
|
415917
|
+
options: {
|
|
415918
|
+
help: { type: "boolean", short: "h" },
|
|
415919
|
+
agent: { type: "string" },
|
|
415920
|
+
"agent-id": { type: "string" },
|
|
415921
|
+
args: { type: "string" }
|
|
415922
|
+
},
|
|
415923
|
+
strict: true,
|
|
415924
|
+
allowPositionals: true
|
|
415925
|
+
});
|
|
415926
|
+
}
|
|
415927
|
+
function stringValue4(value) {
|
|
415928
|
+
return typeof value === "string" ? value : undefined;
|
|
415929
|
+
}
|
|
415930
|
+
function resolveServerMcpAgentId(agent, agentId, env4 = process.env) {
|
|
415931
|
+
return (agent || agentId || env4.LETTA_AGENT_ID || env4.AGENT_ID || "").trim();
|
|
415932
|
+
}
|
|
415933
|
+
function parseToolArgs2(value) {
|
|
415934
|
+
const raw2 = stringValue4(value);
|
|
415935
|
+
if (!raw2) {
|
|
415936
|
+
return {};
|
|
415937
|
+
}
|
|
415938
|
+
let parsed;
|
|
415939
|
+
try {
|
|
415940
|
+
parsed = JSON.parse(raw2);
|
|
415941
|
+
} catch (error4) {
|
|
415942
|
+
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
415943
|
+
throw new Error(`Invalid --args JSON: ${message}`);
|
|
415944
|
+
}
|
|
415945
|
+
if (!isRecord(parsed)) {
|
|
415946
|
+
throw new Error("Invalid --args JSON: expected a JSON object");
|
|
415947
|
+
}
|
|
415948
|
+
return parsed;
|
|
415949
|
+
}
|
|
415950
|
+
function printJson2(stdout, result2) {
|
|
415951
|
+
stdout(JSON.stringify(result2, null, 2));
|
|
415952
|
+
}
|
|
415953
|
+
async function defaultGetClient() {
|
|
415954
|
+
const client = await getClient();
|
|
415955
|
+
return client;
|
|
415956
|
+
}
|
|
415957
|
+
async function runServerMcpSubcommand(argv, deps = {}) {
|
|
415958
|
+
const stdout = deps.stdout ?? console.log;
|
|
415959
|
+
const stderr = deps.stderr ?? console.error;
|
|
415960
|
+
let parsed;
|
|
415961
|
+
try {
|
|
415962
|
+
parsed = parseServerMcpArgs(argv);
|
|
415963
|
+
} catch (error4) {
|
|
415964
|
+
const message = error4 instanceof Error ? error4.message : String(error4);
|
|
415965
|
+
stderr(`Error: ${message}`);
|
|
415966
|
+
printUsage13(stdout);
|
|
415967
|
+
return 1;
|
|
415968
|
+
}
|
|
415969
|
+
const [action3, mcpServerId, toolId] = parsed.positionals;
|
|
415970
|
+
if (parsed.values.help || !action3 || action3 === "help") {
|
|
415971
|
+
printUsage13(stdout);
|
|
415972
|
+
return 0;
|
|
415973
|
+
}
|
|
415974
|
+
const isAvailable = deps.isServerSideMcpAvailable ?? (() => getBackend().capabilities.serverSideToolManagement);
|
|
415975
|
+
if (!isAvailable()) {
|
|
415976
|
+
stderr("Server-side MCP requires a signed-in Letta Cloud agent; the local backend does not support it.");
|
|
415977
|
+
return 1;
|
|
415978
|
+
}
|
|
415979
|
+
const agentId = resolveServerMcpAgentId(stringValue4(parsed.values.agent), stringValue4(parsed.values["agent-id"]));
|
|
415980
|
+
if (!agentId) {
|
|
415981
|
+
stderr("Agent id required: pass --agent <id> or set LETTA_AGENT_ID/AGENT_ID.");
|
|
415982
|
+
return 1;
|
|
415983
|
+
}
|
|
415984
|
+
await (deps.initializeSettings ?? (() => settingsManager.initialize()))();
|
|
415985
|
+
const client = await (deps.getClient ?? defaultGetClient)();
|
|
415986
|
+
try {
|
|
415987
|
+
if (action3 === "list" || action3 === "list-servers" || action3 === "list_servers") {
|
|
415988
|
+
printJson2(stdout, {
|
|
415989
|
+
agent_id: agentId,
|
|
415990
|
+
servers: await listAgentConnectedMcpServers(client, agentId)
|
|
415991
|
+
});
|
|
415992
|
+
return 0;
|
|
415993
|
+
}
|
|
415994
|
+
if (action3 === "tools" || action3 === "list-tools" || action3 === "list_tools") {
|
|
415995
|
+
if (!mcpServerId) {
|
|
415996
|
+
stderr("Usage: letta server-mcp tools <mcp-server-id> [--agent <id>]");
|
|
415997
|
+
return 1;
|
|
415998
|
+
}
|
|
415999
|
+
printJson2(stdout, {
|
|
416000
|
+
agent_id: agentId,
|
|
416001
|
+
mcp_server_id: mcpServerId,
|
|
416002
|
+
tools: await listAgentConnectedMcpTools(client, agentId, mcpServerId)
|
|
416003
|
+
});
|
|
416004
|
+
return 0;
|
|
416005
|
+
}
|
|
416006
|
+
if (action3 === "run" || action3 === "call" || action3 === "run-tool" || action3 === "run_tool") {
|
|
416007
|
+
if (!mcpServerId || !toolId) {
|
|
416008
|
+
stderr("Usage: letta server-mcp run <mcp-server-id> <tool-id> [--args '<json>'] [--agent <id>]");
|
|
416009
|
+
return 1;
|
|
416010
|
+
}
|
|
416011
|
+
printJson2(stdout, {
|
|
416012
|
+
agent_id: agentId,
|
|
416013
|
+
mcp_server_id: mcpServerId,
|
|
416014
|
+
tool_id: toolId,
|
|
416015
|
+
result: await runAgentConnectedMcpTool({
|
|
416016
|
+
client,
|
|
416017
|
+
agentId,
|
|
416018
|
+
mcpServerId,
|
|
416019
|
+
toolId,
|
|
416020
|
+
args: parseToolArgs2(parsed.values.args)
|
|
416021
|
+
})
|
|
416022
|
+
});
|
|
416023
|
+
return 0;
|
|
416024
|
+
}
|
|
416025
|
+
stderr(`Unknown server-mcp action: ${action3}`);
|
|
416026
|
+
printUsage13(stdout);
|
|
416027
|
+
return 1;
|
|
416028
|
+
} catch (error4) {
|
|
416029
|
+
stderr(error4 instanceof Error ? error4.message : String(error4));
|
|
416030
|
+
return 1;
|
|
416031
|
+
}
|
|
416032
|
+
}
|
|
416033
|
+
var init_server_mcp = __esm(() => {
|
|
416034
|
+
init_backend2();
|
|
416035
|
+
init_client2();
|
|
416036
|
+
init_mcp_servers2();
|
|
416037
|
+
init_settings_manager();
|
|
416038
|
+
});
|
|
416039
|
+
|
|
415680
416040
|
// src/auth/LettaLoginView.tsx
|
|
415681
416041
|
import { hostname as hostname5 } from "node:os";
|
|
415682
416042
|
async function completeLettaLogin(tokens, options) {
|
|
@@ -416095,7 +416455,7 @@ var init_setup6 = __esm(async () => {
|
|
|
416095
416455
|
});
|
|
416096
416456
|
|
|
416097
416457
|
// src/cli/subcommands/setup.ts
|
|
416098
|
-
function
|
|
416458
|
+
function printUsage14() {
|
|
416099
416459
|
console.log(`
|
|
416100
416460
|
Usage:
|
|
416101
416461
|
letta setup
|
|
@@ -416106,12 +416466,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
|
|
|
416106
416466
|
async function runSetupSubcommand(argv) {
|
|
416107
416467
|
const [arg, ...rest4] = argv;
|
|
416108
416468
|
if (arg === "help" || arg === "--help" || arg === "-h") {
|
|
416109
|
-
|
|
416469
|
+
printUsage14();
|
|
416110
416470
|
return 0;
|
|
416111
416471
|
}
|
|
416112
416472
|
if (arg || rest4.length > 0) {
|
|
416113
416473
|
console.error(`Unexpected arguments: ${[arg, ...rest4].filter(Boolean).join(" ")}`);
|
|
416114
|
-
|
|
416474
|
+
printUsage14();
|
|
416115
416475
|
return 1;
|
|
416116
416476
|
}
|
|
416117
416477
|
await settingsManager.initialize();
|
|
@@ -416126,8 +416486,8 @@ var init_setup7 = __esm(async () => {
|
|
|
416126
416486
|
// src/cli/subcommands/shared-memory.ts
|
|
416127
416487
|
import { existsSync as existsSync59 } from "node:fs";
|
|
416128
416488
|
import { join as join75 } from "node:path";
|
|
416129
|
-
import { parseArgs as
|
|
416130
|
-
function
|
|
416489
|
+
import { parseArgs as parseArgs17 } from "node:util";
|
|
416490
|
+
function printUsage15() {
|
|
416131
416491
|
console.log(`
|
|
416132
416492
|
Usage:
|
|
416133
416493
|
letta shared-memory list [--agent <id>]
|
|
@@ -416162,7 +416522,7 @@ Examples:
|
|
|
416162
416522
|
`.trim());
|
|
416163
416523
|
}
|
|
416164
416524
|
function parseSharedMemoryArgs(argv) {
|
|
416165
|
-
return
|
|
416525
|
+
return parseArgs17({
|
|
416166
416526
|
args: argv,
|
|
416167
416527
|
options: SHARED_MEMORY_OPTIONS,
|
|
416168
416528
|
strict: true,
|
|
@@ -416238,12 +416598,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
416238
416598
|
parsed = parseSharedMemoryArgs(argv);
|
|
416239
416599
|
} catch (error4) {
|
|
416240
416600
|
console.error(error4 instanceof Error ? error4.message : String(error4));
|
|
416241
|
-
|
|
416601
|
+
printUsage15();
|
|
416242
416602
|
return 1;
|
|
416243
416603
|
}
|
|
416244
416604
|
const [action3, reference] = parsed.positionals;
|
|
416245
416605
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
416246
|
-
|
|
416606
|
+
printUsage15();
|
|
416247
416607
|
return 0;
|
|
416248
416608
|
}
|
|
416249
416609
|
if (isLocalBackendEnvEnabled()) {
|
|
@@ -416348,7 +416708,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
416348
416708
|
return result2.failed > 0 ? 1 : 0;
|
|
416349
416709
|
}
|
|
416350
416710
|
console.error(`Unknown action: ${action3}`);
|
|
416351
|
-
|
|
416711
|
+
printUsage15();
|
|
416352
416712
|
return 1;
|
|
416353
416713
|
} catch (error4) {
|
|
416354
416714
|
console.error(error4 instanceof Error ? error4.message : String(error4));
|
|
@@ -417856,8 +418216,8 @@ import {
|
|
|
417856
418216
|
import { mkdir as mkdir15, readdir as readdir14 } from "node:fs/promises";
|
|
417857
418217
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
417858
418218
|
import { basename as basename27, dirname as dirname34, join as join76, normalize as normalize5, resolve as resolve37, sep as sep8 } from "node:path";
|
|
417859
|
-
import { parseArgs as
|
|
417860
|
-
function
|
|
418219
|
+
import { parseArgs as parseArgs18, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
418220
|
+
function printUsage16() {
|
|
417861
418221
|
console.log(`
|
|
417862
418222
|
Usage:
|
|
417863
418223
|
letta install <thing> [--agent <id> | -n <agent name>] [--force]
|
|
@@ -417884,7 +418244,7 @@ Options:
|
|
|
417884
418244
|
`.trim());
|
|
417885
418245
|
}
|
|
417886
418246
|
function parseSkillsArgs(argv) {
|
|
417887
|
-
return
|
|
418247
|
+
return parseArgs18({
|
|
417888
418248
|
args: argv,
|
|
417889
418249
|
options: SKILLS_OPTIONS,
|
|
417890
418250
|
strict: true,
|
|
@@ -418532,17 +418892,17 @@ async function runInstall(argv, options = {}) {
|
|
|
418532
418892
|
parsed = parseSkillsArgs(argv);
|
|
418533
418893
|
} catch (error4) {
|
|
418534
418894
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418535
|
-
|
|
418895
|
+
printUsage16();
|
|
418536
418896
|
return 1;
|
|
418537
418897
|
}
|
|
418538
418898
|
const [specifier] = parsed.positionals;
|
|
418539
418899
|
if (parsed.values.help || !specifier || specifier === "help") {
|
|
418540
|
-
|
|
418900
|
+
printUsage16();
|
|
418541
418901
|
return 0;
|
|
418542
418902
|
}
|
|
418543
418903
|
if (parsed.positionals.length > 1) {
|
|
418544
418904
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
418545
|
-
|
|
418905
|
+
printUsage16();
|
|
418546
418906
|
return 1;
|
|
418547
418907
|
}
|
|
418548
418908
|
if (specifier.startsWith("npm:")) {
|
|
@@ -418633,16 +418993,16 @@ async function runList2(argv) {
|
|
|
418633
418993
|
parsed = parseSkillsArgs(argv);
|
|
418634
418994
|
} catch (error4) {
|
|
418635
418995
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418636
|
-
|
|
418996
|
+
printUsage16();
|
|
418637
418997
|
return 1;
|
|
418638
418998
|
}
|
|
418639
418999
|
if (parsed.values.help) {
|
|
418640
|
-
|
|
419000
|
+
printUsage16();
|
|
418641
419001
|
return 0;
|
|
418642
419002
|
}
|
|
418643
419003
|
if (parsed.positionals.length > 0) {
|
|
418644
419004
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
418645
|
-
|
|
419005
|
+
printUsage16();
|
|
418646
419006
|
return 1;
|
|
418647
419007
|
}
|
|
418648
419008
|
try {
|
|
@@ -418663,17 +419023,17 @@ async function runDelete(argv) {
|
|
|
418663
419023
|
parsed = parseSkillsArgs(argv);
|
|
418664
419024
|
} catch (error4) {
|
|
418665
419025
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418666
|
-
|
|
419026
|
+
printUsage16();
|
|
418667
419027
|
return 1;
|
|
418668
419028
|
}
|
|
418669
419029
|
const [skillName] = parsed.positionals;
|
|
418670
419030
|
if (parsed.values.help || !skillName || skillName === "help") {
|
|
418671
|
-
|
|
419031
|
+
printUsage16();
|
|
418672
419032
|
return 0;
|
|
418673
419033
|
}
|
|
418674
419034
|
if (parsed.positionals.length > 1) {
|
|
418675
419035
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
418676
|
-
|
|
419036
|
+
printUsage16();
|
|
418677
419037
|
return 1;
|
|
418678
419038
|
}
|
|
418679
419039
|
const agentId = getExplicitAgentId2(parsed.values);
|
|
@@ -418713,11 +419073,11 @@ async function runSkillsSubcommand(argv) {
|
|
|
418713
419073
|
case "help":
|
|
418714
419074
|
case "--help":
|
|
418715
419075
|
case "-h":
|
|
418716
|
-
|
|
419076
|
+
printUsage16();
|
|
418717
419077
|
return 0;
|
|
418718
419078
|
default:
|
|
418719
419079
|
console.error(`Unknown action: ${action3}`);
|
|
418720
|
-
|
|
419080
|
+
printUsage16();
|
|
418721
419081
|
return 1;
|
|
418722
419082
|
}
|
|
418723
419083
|
}
|
|
@@ -418736,8 +419096,8 @@ var init_skills4 = __esm(() => {
|
|
|
418736
419096
|
});
|
|
418737
419097
|
|
|
418738
419098
|
// src/cli/subcommands/teleport.ts
|
|
418739
|
-
import { parseArgs as
|
|
418740
|
-
function
|
|
419099
|
+
import { parseArgs as parseArgs19 } from "node:util";
|
|
419100
|
+
function printUsage17() {
|
|
418741
419101
|
console.log(`
|
|
418742
419102
|
Usage:
|
|
418743
419103
|
letta teleport list
|
|
@@ -418760,7 +419120,7 @@ Notes:
|
|
|
418760
419120
|
`.trim());
|
|
418761
419121
|
}
|
|
418762
419122
|
function parseTeleportArgs(argv) {
|
|
418763
|
-
return
|
|
419123
|
+
return parseArgs19({
|
|
418764
419124
|
args: argv,
|
|
418765
419125
|
options: TELEPORT_OPTIONS,
|
|
418766
419126
|
strict: true,
|
|
@@ -418833,12 +419193,12 @@ async function runTeleportSubcommand(argv, deps = {}) {
|
|
|
418833
419193
|
parsed = parseTeleportArgs(argv);
|
|
418834
419194
|
} catch (error4) {
|
|
418835
419195
|
console.error(`Error: ${error4 instanceof Error ? error4.message : error4}`);
|
|
418836
|
-
|
|
419196
|
+
printUsage17();
|
|
418837
419197
|
return 1;
|
|
418838
419198
|
}
|
|
418839
419199
|
const [action3] = parsed.positionals;
|
|
418840
419200
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
418841
|
-
|
|
419201
|
+
printUsage17();
|
|
418842
419202
|
return 0;
|
|
418843
419203
|
}
|
|
418844
419204
|
try {
|
|
@@ -419274,8 +419634,8 @@ var init_review = () => {};
|
|
|
419274
419634
|
|
|
419275
419635
|
// src/cli/subcommands/trajectories.ts
|
|
419276
419636
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
419277
|
-
import { parseArgs as
|
|
419278
|
-
function
|
|
419637
|
+
import { parseArgs as parseArgs20 } from "node:util";
|
|
419638
|
+
function printUsage18() {
|
|
419279
419639
|
console.log(`
|
|
419280
419640
|
Usage:
|
|
419281
419641
|
letta trajectories export [options]
|
|
@@ -419413,7 +419773,7 @@ ${results.length} session(s) matched "${keyword}"`);
|
|
|
419413
419773
|
return 0;
|
|
419414
419774
|
}
|
|
419415
419775
|
function parseTrajectoriesArgs(argv) {
|
|
419416
|
-
return
|
|
419776
|
+
return parseArgs20({
|
|
419417
419777
|
args: argv,
|
|
419418
419778
|
options: TRAJECTORIES_OPTIONS,
|
|
419419
419779
|
strict: true,
|
|
@@ -419426,12 +419786,12 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
419426
419786
|
parsed = parseTrajectoriesArgs(argv);
|
|
419427
419787
|
} catch (error4) {
|
|
419428
419788
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
419429
|
-
|
|
419789
|
+
printUsage18();
|
|
419430
419790
|
return 1;
|
|
419431
419791
|
}
|
|
419432
419792
|
const [action3] = parsed.positionals;
|
|
419433
419793
|
if (parsed.values.help || action3 === "help" || !action3) {
|
|
419434
|
-
|
|
419794
|
+
printUsage18();
|
|
419435
419795
|
return parsed.values.help || action3 === "help" ? 0 : 1;
|
|
419436
419796
|
}
|
|
419437
419797
|
const asJson = Boolean(parsed.values.json);
|
|
@@ -419463,7 +419823,7 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
419463
419823
|
}
|
|
419464
419824
|
if (action3 !== "export") {
|
|
419465
419825
|
console.error(`Unknown command: ${action3}`);
|
|
419466
|
-
|
|
419826
|
+
printUsage18();
|
|
419467
419827
|
return 1;
|
|
419468
419828
|
}
|
|
419469
419829
|
const options = {
|
|
@@ -421012,9 +421372,9 @@ class ChannelRichDraftStreamerImpl {
|
|
|
421012
421372
|
return;
|
|
421013
421373
|
}
|
|
421014
421374
|
const record3 = asRecord10(chunk2);
|
|
421015
|
-
const messageType =
|
|
421375
|
+
const messageType = stringValue5(record3?.message_type);
|
|
421016
421376
|
if (messageType === "tool_return_message") {
|
|
421017
|
-
const toolCallId =
|
|
421377
|
+
const toolCallId = stringValue5(record3?.tool_call_id);
|
|
421018
421378
|
if (toolCallId) {
|
|
421019
421379
|
this.finishCall(toolCallId);
|
|
421020
421380
|
}
|
|
@@ -421307,14 +421667,14 @@ function extractToolCallFragments2(record3) {
|
|
|
421307
421667
|
const fragments = [];
|
|
421308
421668
|
for (const rawToolCall of rawToolCalls) {
|
|
421309
421669
|
const toolCall = asRecord10(rawToolCall);
|
|
421310
|
-
const toolCallId =
|
|
421670
|
+
const toolCallId = stringValue5(toolCall?.tool_call_id);
|
|
421311
421671
|
if (!toolCallId) {
|
|
421312
421672
|
continue;
|
|
421313
421673
|
}
|
|
421314
421674
|
fragments.push({
|
|
421315
421675
|
toolCallId,
|
|
421316
|
-
name:
|
|
421317
|
-
argumentsDelta:
|
|
421676
|
+
name: stringValue5(toolCall?.name),
|
|
421677
|
+
argumentsDelta: stringValue5(toolCall?.arguments)
|
|
421318
421678
|
});
|
|
421319
421679
|
}
|
|
421320
421680
|
return fragments;
|
|
@@ -421434,7 +421794,7 @@ function buildDraftId(seed) {
|
|
|
421434
421794
|
function asRecord10(value) {
|
|
421435
421795
|
return value && typeof value === "object" ? value : null;
|
|
421436
421796
|
}
|
|
421437
|
-
function
|
|
421797
|
+
function stringValue5(value) {
|
|
421438
421798
|
return typeof value === "string" ? value : undefined;
|
|
421439
421799
|
}
|
|
421440
421800
|
var MESSAGE_CHANNEL_TOOL_NAMES, DEFAULT_DRAFT_DEBOUNCE_MS = 1000, MIN_DRAFT_TEXT_LENGTH = 1;
|
|
@@ -424302,14 +424662,14 @@ var exports_channel_gateway = {};
|
|
|
424302
424662
|
__export(exports_channel_gateway, {
|
|
424303
424663
|
runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
|
|
424304
424664
|
});
|
|
424305
|
-
import { parseArgs as
|
|
424665
|
+
import { parseArgs as parseArgs21 } from "node:util";
|
|
424306
424666
|
function isGatewayCommandEnvelope(value) {
|
|
424307
424667
|
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");
|
|
424308
424668
|
}
|
|
424309
424669
|
async function runChannelGatewaySubcommand(argv) {
|
|
424310
424670
|
let values3;
|
|
424311
424671
|
try {
|
|
424312
|
-
({ values: values3 } =
|
|
424672
|
+
({ values: values3 } = parseArgs21({
|
|
424313
424673
|
args: argv,
|
|
424314
424674
|
strict: true,
|
|
424315
424675
|
allowPositionals: false,
|
|
@@ -424448,6 +424808,7 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
424448
424808
|
case "sandbox":
|
|
424449
424809
|
case "secret":
|
|
424450
424810
|
case "server":
|
|
424811
|
+
case "server-mcp":
|
|
424451
424812
|
case "shared-memory":
|
|
424452
424813
|
case "skills":
|
|
424453
424814
|
case "teleport":
|
|
@@ -424490,6 +424851,8 @@ async function runSubcommand(argv) {
|
|
|
424490
424851
|
return runTeleportSubcommand(rest4);
|
|
424491
424852
|
case "server":
|
|
424492
424853
|
return runServerSubcommand(rest4);
|
|
424854
|
+
case "server-mcp":
|
|
424855
|
+
return runServerMcpSubcommand(rest4);
|
|
424493
424856
|
case "remote":
|
|
424494
424857
|
return runListenSubcommand(rest4);
|
|
424495
424858
|
case "connect":
|
|
@@ -424535,6 +424898,7 @@ var init_router = __esm(async () => {
|
|
|
424535
424898
|
init_messages10();
|
|
424536
424899
|
init_sandbox2();
|
|
424537
424900
|
init_secret();
|
|
424901
|
+
init_server_mcp();
|
|
424538
424902
|
init_shared_memory();
|
|
424539
424903
|
init_skills4();
|
|
424540
424904
|
init_teleport2();
|
|
@@ -442494,7 +442858,7 @@ var init_mcp_client = __esm(() => {
|
|
|
442494
442858
|
init_streamableHttp();
|
|
442495
442859
|
DEFAULT_CLIENT_INFO = {
|
|
442496
442860
|
name: "letta-code",
|
|
442497
|
-
version: "0.31.
|
|
442861
|
+
version: "0.31.2"
|
|
442498
442862
|
};
|
|
442499
442863
|
});
|
|
442500
442864
|
|
|
@@ -462371,110 +462735,6 @@ var init_LettaLoginOverlay = __esm(async () => {
|
|
|
462371
462735
|
jsx_dev_runtime63 = __toESM(require_jsx_dev_runtime(), 1);
|
|
462372
462736
|
});
|
|
462373
462737
|
|
|
462374
|
-
// src/backend/api/mcp-servers.ts
|
|
462375
|
-
function withTimeout2(promise2, timeoutMs, label) {
|
|
462376
|
-
let timer;
|
|
462377
|
-
const timeout = new Promise((_4, reject2) => {
|
|
462378
|
-
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
462379
|
-
});
|
|
462380
|
-
return Promise.race([promise2, timeout]).finally(() => {
|
|
462381
|
-
if (timer !== undefined)
|
|
462382
|
-
clearTimeout(timer);
|
|
462383
|
-
});
|
|
462384
|
-
}
|
|
462385
|
-
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
462386
|
-
return withTimeout2(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
462387
|
-
}
|
|
462388
|
-
async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
|
|
462389
|
-
const result2 = await withTimeout2(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
|
|
462390
|
-
if (!Array.isArray(result2))
|
|
462391
|
-
return [];
|
|
462392
|
-
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
462393
|
-
}
|
|
462394
|
-
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
462395
|
-
const servers = await listServerMcpServers(client, timeoutMs);
|
|
462396
|
-
return Promise.all(servers.map(async (server2) => {
|
|
462397
|
-
try {
|
|
462398
|
-
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
462399
|
-
return { server: server2, tools };
|
|
462400
|
-
} catch (cause) {
|
|
462401
|
-
return {
|
|
462402
|
-
server: server2,
|
|
462403
|
-
tools: [],
|
|
462404
|
-
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
462405
|
-
};
|
|
462406
|
-
}
|
|
462407
|
-
}));
|
|
462408
|
-
}
|
|
462409
|
-
function parseMcpMetadata(tool) {
|
|
462410
|
-
const metadata = tool.metadata_;
|
|
462411
|
-
const mcp = metadata?.mcp;
|
|
462412
|
-
if (typeof mcp !== "object" || mcp === null)
|
|
462413
|
-
return null;
|
|
462414
|
-
const { server_id, server_name } = mcp;
|
|
462415
|
-
return {
|
|
462416
|
-
...typeof server_id === "string" && { serverId: server_id },
|
|
462417
|
-
...typeof server_name === "string" && { serverName: server_name }
|
|
462418
|
-
};
|
|
462419
|
-
}
|
|
462420
|
-
async function listAgentMcpAttachments(client, agentId) {
|
|
462421
|
-
const attachments = [];
|
|
462422
|
-
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
462423
|
-
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
462424
|
-
continue;
|
|
462425
|
-
attachments.push({
|
|
462426
|
-
toolId: tool.id,
|
|
462427
|
-
toolName: tool.name,
|
|
462428
|
-
...parseMcpMetadata(tool)
|
|
462429
|
-
});
|
|
462430
|
-
}
|
|
462431
|
-
return attachments;
|
|
462432
|
-
}
|
|
462433
|
-
function attachmentsForEntry(entry, attachments) {
|
|
462434
|
-
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
462435
|
-
}
|
|
462436
|
-
function attachedToolNamesForEntry(entry, attachments) {
|
|
462437
|
-
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
462438
|
-
}
|
|
462439
|
-
async function registerServerMcpTool(client, serverName, toolName) {
|
|
462440
|
-
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
|
|
462441
|
-
if (typeof result2?.id !== "string") {
|
|
462442
|
-
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
|
|
462443
|
-
}
|
|
462444
|
-
return { id: result2.id };
|
|
462445
|
-
}
|
|
462446
|
-
async function attachServerMcpTools(client, agentId, serverName, toolNames) {
|
|
462447
|
-
await Promise.all(toolNames.map(async (toolName) => {
|
|
462448
|
-
const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
|
|
462449
|
-
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
462450
|
-
}));
|
|
462451
|
-
}
|
|
462452
|
-
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
462453
|
-
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
462454
|
-
}
|
|
462455
|
-
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
462456
|
-
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
462457
|
-
}
|
|
462458
|
-
function planServerMcpToggle(entry, attachments) {
|
|
462459
|
-
const attached = attachmentsForEntry(entry, attachments);
|
|
462460
|
-
if (attached.length > 0) {
|
|
462461
|
-
return {
|
|
462462
|
-
action: "detach",
|
|
462463
|
-
toolIds: attached.map((attachment) => attachment.toolId)
|
|
462464
|
-
};
|
|
462465
|
-
}
|
|
462466
|
-
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
462467
|
-
}
|
|
462468
|
-
function describeServerMcpTarget(server2) {
|
|
462469
|
-
if ("server_url" in server2 && server2.server_url) {
|
|
462470
|
-
return server2.server_url;
|
|
462471
|
-
}
|
|
462472
|
-
if ("command" in server2 && server2.command) {
|
|
462473
|
-
return [server2.command, ...server2.args ?? []].join(" ");
|
|
462474
|
-
}
|
|
462475
|
-
return "";
|
|
462476
|
-
}
|
|
462477
|
-
|
|
462478
462738
|
// src/cli/components/McpSelector.tsx
|
|
462479
462739
|
function buildMcpRows(localStates, serverEntries) {
|
|
462480
462740
|
return [
|
|
@@ -462591,6 +462851,7 @@ var import_react87, jsx_dev_runtime64, SOLID_LINE12 = "─", DISPLAY_PAGE_SIZE2
|
|
|
462591
462851
|
var init_McpSelector = __esm(async () => {
|
|
462592
462852
|
init_backend2();
|
|
462593
462853
|
init_client2();
|
|
462854
|
+
init_mcp_servers2();
|
|
462594
462855
|
init_truncate_text();
|
|
462595
462856
|
init_use_terminal_width();
|
|
462596
462857
|
init_mcp_oauth();
|
|
@@ -472220,7 +472481,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
472220
472481
|
let shellSemanticKind = null;
|
|
472221
472482
|
let hasShellDescription = false;
|
|
472222
472483
|
if (!isQuestionTool(rawName)) {
|
|
472223
|
-
const
|
|
472484
|
+
const parseArgs22 = () => {
|
|
472224
472485
|
if (!argsText.trim()) {
|
|
472225
472486
|
return { formatted: null, parseable: true };
|
|
472226
472487
|
}
|
|
@@ -472234,7 +472495,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
472234
472495
|
return { formatted: null, parseable: false };
|
|
472235
472496
|
}
|
|
472236
472497
|
};
|
|
472237
|
-
const { formatted, parseable } =
|
|
472498
|
+
const { formatted, parseable } = parseArgs22();
|
|
472238
472499
|
const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
|
|
472239
472500
|
if (!argsComplete) {
|
|
472240
472501
|
args = "(…)";
|
|
@@ -474450,7 +474711,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
|
|
|
474450
474711
|
buffersRef.current.byId.set(cmdId, line);
|
|
474451
474712
|
refreshDerived();
|
|
474452
474713
|
}
|
|
474453
|
-
function
|
|
474714
|
+
function parseArgs22(msg) {
|
|
474454
474715
|
return msg.trim().split(/\s+/).filter(Boolean);
|
|
474455
474716
|
}
|
|
474456
474717
|
function formatConnectUsage() {
|
|
@@ -474832,7 +475093,7 @@ ${formatBedrockUsage2()}`, false);
|
|
|
474832
475093
|
}
|
|
474833
475094
|
}
|
|
474834
475095
|
async function handleConnect(ctx, msg) {
|
|
474835
|
-
const parts =
|
|
475096
|
+
const parts = parseArgs22(msg);
|
|
474836
475097
|
const providerToken = parts[1];
|
|
474837
475098
|
if (!providerToken) {
|
|
474838
475099
|
addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
|
|
@@ -505768,9 +506029,7 @@ USAGE
|
|
|
505768
506029
|
letta -p "..." One-off prompt in headless mode (no TTY UI)
|
|
505769
506030
|
|
|
505770
506031
|
# maintenance
|
|
505771
|
-
letta update
|
|
505772
|
-
letta upgrade Alias for \`letta update\`
|
|
505773
|
-
letta --update/--upgrade Aliases for \`letta update\`
|
|
506032
|
+
letta update Check for updates and install (aliases: upgrade, --update, --upgrade)
|
|
505774
506033
|
letta memory ... Memory filesystem subcommands
|
|
505775
506034
|
letta agents ... Agents subcommands (JSON-only)
|
|
505776
506035
|
letta environments ... List available remote environments (JSON-only)
|
|
@@ -505779,6 +506038,7 @@ USAGE
|
|
|
505779
506038
|
letta mods ... List and manage local mods
|
|
505780
506039
|
letta sandbox ... Transfer files to or from the current Cloud sandbox
|
|
505781
506040
|
letta server ... Run a remote environment, channels, or the App Server
|
|
506041
|
+
letta server-mcp ... Use MCP servers connected to an agent
|
|
505782
506042
|
letta connect ... Connect providers from terminal
|
|
505783
506043
|
letta backend ... Show or set the default backend
|
|
505784
506044
|
letta setup Re-run first-run setup
|
|
@@ -505810,6 +506070,7 @@ SUBCOMMANDS
|
|
|
505810
506070
|
letta mods enable <package-spec>
|
|
505811
506071
|
letta mods disable <package-spec>
|
|
505812
506072
|
letta mods remove <package-spec>
|
|
506073
|
+
letta server-mcp list|tools|run ... [--agent <id>]
|
|
505813
506074
|
letta server [--env-name <name> | --listen [url]] [options]
|
|
505814
506075
|
letta connect <provider> [options]
|
|
505815
506076
|
letta install <thing> [--agent <id> | -n <name>]
|
|
@@ -509630,4 +509891,4 @@ function registerBunOAuthFlows() {
|
|
|
509630
509891
|
registerBunOAuthFlows();
|
|
509631
509892
|
await init_src5().then(() => exports_src2);
|
|
509632
509893
|
|
|
509633
|
-
//# debugId=
|
|
509894
|
+
//# debugId=48BEECE3782D14CC64756E2164756E21
|