@letta-ai/letta-code 0.31.1 → 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/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/letta.js +400 -168
- 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 */,
|
|
@@ -208834,12 +208841,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
208834
208841
|
}
|
|
208835
208842
|
return calls;
|
|
208836
208843
|
}
|
|
208837
|
-
function
|
|
208844
|
+
function contentText2(content) {
|
|
208838
208845
|
if (typeof content === "string") {
|
|
208839
208846
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
208840
208847
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
208841
208848
|
try {
|
|
208842
|
-
return
|
|
208849
|
+
return contentText2(JSON.parse(encoded));
|
|
208843
208850
|
} catch {
|
|
208844
208851
|
return encoded;
|
|
208845
208852
|
}
|
|
@@ -208925,7 +208932,7 @@ var init_hermes = __esm(() => {
|
|
|
208925
208932
|
});
|
|
208926
208933
|
};
|
|
208927
208934
|
if (row.role === "user") {
|
|
208928
|
-
const content =
|
|
208935
|
+
const content = contentText2(row.content);
|
|
208929
208936
|
if (content) {
|
|
208930
208937
|
emit({
|
|
208931
208938
|
type: "message",
|
|
@@ -208945,7 +208952,7 @@ var init_hermes = __esm(() => {
|
|
|
208945
208952
|
...timestamp ? { timestamp } : {}
|
|
208946
208953
|
});
|
|
208947
208954
|
}
|
|
208948
|
-
const content =
|
|
208955
|
+
const content = contentText2(row.content);
|
|
208949
208956
|
if (content) {
|
|
208950
208957
|
emit({
|
|
208951
208958
|
type: "message",
|
|
@@ -208968,7 +208975,7 @@ var init_hermes = __esm(() => {
|
|
|
208968
208975
|
if (row.role === "tool") {
|
|
208969
208976
|
emit({
|
|
208970
208977
|
type: "tool_result",
|
|
208971
|
-
content:
|
|
208978
|
+
content: contentText2(row.content),
|
|
208972
208979
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
208973
208980
|
...timestamp ? { timestamp } : {}
|
|
208974
208981
|
});
|
|
@@ -415706,6 +415713,330 @@ var init_server = __esm(async () => {
|
|
|
415706
415713
|
]);
|
|
415707
415714
|
});
|
|
415708
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
|
+
|
|
415709
416040
|
// src/auth/LettaLoginView.tsx
|
|
415710
416041
|
import { hostname as hostname5 } from "node:os";
|
|
415711
416042
|
async function completeLettaLogin(tokens, options) {
|
|
@@ -416124,7 +416455,7 @@ var init_setup6 = __esm(async () => {
|
|
|
416124
416455
|
});
|
|
416125
416456
|
|
|
416126
416457
|
// src/cli/subcommands/setup.ts
|
|
416127
|
-
function
|
|
416458
|
+
function printUsage14() {
|
|
416128
416459
|
console.log(`
|
|
416129
416460
|
Usage:
|
|
416130
416461
|
letta setup
|
|
@@ -416135,12 +416466,12 @@ Re-run the interactive setup menu to choose local mode or sign in with Letta.
|
|
|
416135
416466
|
async function runSetupSubcommand(argv) {
|
|
416136
416467
|
const [arg, ...rest4] = argv;
|
|
416137
416468
|
if (arg === "help" || arg === "--help" || arg === "-h") {
|
|
416138
|
-
|
|
416469
|
+
printUsage14();
|
|
416139
416470
|
return 0;
|
|
416140
416471
|
}
|
|
416141
416472
|
if (arg || rest4.length > 0) {
|
|
416142
416473
|
console.error(`Unexpected arguments: ${[arg, ...rest4].filter(Boolean).join(" ")}`);
|
|
416143
|
-
|
|
416474
|
+
printUsage14();
|
|
416144
416475
|
return 1;
|
|
416145
416476
|
}
|
|
416146
416477
|
await settingsManager.initialize();
|
|
@@ -416155,8 +416486,8 @@ var init_setup7 = __esm(async () => {
|
|
|
416155
416486
|
// src/cli/subcommands/shared-memory.ts
|
|
416156
416487
|
import { existsSync as existsSync59 } from "node:fs";
|
|
416157
416488
|
import { join as join75 } from "node:path";
|
|
416158
|
-
import { parseArgs as
|
|
416159
|
-
function
|
|
416489
|
+
import { parseArgs as parseArgs17 } from "node:util";
|
|
416490
|
+
function printUsage15() {
|
|
416160
416491
|
console.log(`
|
|
416161
416492
|
Usage:
|
|
416162
416493
|
letta shared-memory list [--agent <id>]
|
|
@@ -416191,7 +416522,7 @@ Examples:
|
|
|
416191
416522
|
`.trim());
|
|
416192
416523
|
}
|
|
416193
416524
|
function parseSharedMemoryArgs(argv) {
|
|
416194
|
-
return
|
|
416525
|
+
return parseArgs17({
|
|
416195
416526
|
args: argv,
|
|
416196
416527
|
options: SHARED_MEMORY_OPTIONS,
|
|
416197
416528
|
strict: true,
|
|
@@ -416267,12 +416598,12 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
416267
416598
|
parsed = parseSharedMemoryArgs(argv);
|
|
416268
416599
|
} catch (error4) {
|
|
416269
416600
|
console.error(error4 instanceof Error ? error4.message : String(error4));
|
|
416270
|
-
|
|
416601
|
+
printUsage15();
|
|
416271
416602
|
return 1;
|
|
416272
416603
|
}
|
|
416273
416604
|
const [action3, reference] = parsed.positionals;
|
|
416274
416605
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
416275
|
-
|
|
416606
|
+
printUsage15();
|
|
416276
416607
|
return 0;
|
|
416277
416608
|
}
|
|
416278
416609
|
if (isLocalBackendEnvEnabled()) {
|
|
@@ -416377,7 +416708,7 @@ async function runSharedMemorySubcommand(argv, deps = {}) {
|
|
|
416377
416708
|
return result2.failed > 0 ? 1 : 0;
|
|
416378
416709
|
}
|
|
416379
416710
|
console.error(`Unknown action: ${action3}`);
|
|
416380
|
-
|
|
416711
|
+
printUsage15();
|
|
416381
416712
|
return 1;
|
|
416382
416713
|
} catch (error4) {
|
|
416383
416714
|
console.error(error4 instanceof Error ? error4.message : String(error4));
|
|
@@ -417885,8 +418216,8 @@ import {
|
|
|
417885
418216
|
import { mkdir as mkdir15, readdir as readdir14 } from "node:fs/promises";
|
|
417886
418217
|
import { tmpdir as tmpdir11 } from "node:os";
|
|
417887
418218
|
import { basename as basename27, dirname as dirname34, join as join76, normalize as normalize5, resolve as resolve37, sep as sep8 } from "node:path";
|
|
417888
|
-
import { parseArgs as
|
|
417889
|
-
function
|
|
418219
|
+
import { parseArgs as parseArgs18, TextDecoder as TextDecoder2, TextEncoder as TextEncoder2 } from "node:util";
|
|
418220
|
+
function printUsage16() {
|
|
417890
418221
|
console.log(`
|
|
417891
418222
|
Usage:
|
|
417892
418223
|
letta install <thing> [--agent <id> | -n <agent name>] [--force]
|
|
@@ -417913,7 +418244,7 @@ Options:
|
|
|
417913
418244
|
`.trim());
|
|
417914
418245
|
}
|
|
417915
418246
|
function parseSkillsArgs(argv) {
|
|
417916
|
-
return
|
|
418247
|
+
return parseArgs18({
|
|
417917
418248
|
args: argv,
|
|
417918
418249
|
options: SKILLS_OPTIONS,
|
|
417919
418250
|
strict: true,
|
|
@@ -418561,17 +418892,17 @@ async function runInstall(argv, options = {}) {
|
|
|
418561
418892
|
parsed = parseSkillsArgs(argv);
|
|
418562
418893
|
} catch (error4) {
|
|
418563
418894
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418564
|
-
|
|
418895
|
+
printUsage16();
|
|
418565
418896
|
return 1;
|
|
418566
418897
|
}
|
|
418567
418898
|
const [specifier] = parsed.positionals;
|
|
418568
418899
|
if (parsed.values.help || !specifier || specifier === "help") {
|
|
418569
|
-
|
|
418900
|
+
printUsage16();
|
|
418570
418901
|
return 0;
|
|
418571
418902
|
}
|
|
418572
418903
|
if (parsed.positionals.length > 1) {
|
|
418573
418904
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
418574
|
-
|
|
418905
|
+
printUsage16();
|
|
418575
418906
|
return 1;
|
|
418576
418907
|
}
|
|
418577
418908
|
if (specifier.startsWith("npm:")) {
|
|
@@ -418662,16 +418993,16 @@ async function runList2(argv) {
|
|
|
418662
418993
|
parsed = parseSkillsArgs(argv);
|
|
418663
418994
|
} catch (error4) {
|
|
418664
418995
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418665
|
-
|
|
418996
|
+
printUsage16();
|
|
418666
418997
|
return 1;
|
|
418667
418998
|
}
|
|
418668
418999
|
if (parsed.values.help) {
|
|
418669
|
-
|
|
419000
|
+
printUsage16();
|
|
418670
419001
|
return 0;
|
|
418671
419002
|
}
|
|
418672
419003
|
if (parsed.positionals.length > 0) {
|
|
418673
419004
|
console.error(`Unexpected argument: ${parsed.positionals[0]}`);
|
|
418674
|
-
|
|
419005
|
+
printUsage16();
|
|
418675
419006
|
return 1;
|
|
418676
419007
|
}
|
|
418677
419008
|
try {
|
|
@@ -418692,17 +419023,17 @@ async function runDelete(argv) {
|
|
|
418692
419023
|
parsed = parseSkillsArgs(argv);
|
|
418693
419024
|
} catch (error4) {
|
|
418694
419025
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
418695
|
-
|
|
419026
|
+
printUsage16();
|
|
418696
419027
|
return 1;
|
|
418697
419028
|
}
|
|
418698
419029
|
const [skillName] = parsed.positionals;
|
|
418699
419030
|
if (parsed.values.help || !skillName || skillName === "help") {
|
|
418700
|
-
|
|
419031
|
+
printUsage16();
|
|
418701
419032
|
return 0;
|
|
418702
419033
|
}
|
|
418703
419034
|
if (parsed.positionals.length > 1) {
|
|
418704
419035
|
console.error(`Unexpected argument: ${parsed.positionals[1]}`);
|
|
418705
|
-
|
|
419036
|
+
printUsage16();
|
|
418706
419037
|
return 1;
|
|
418707
419038
|
}
|
|
418708
419039
|
const agentId = getExplicitAgentId2(parsed.values);
|
|
@@ -418742,11 +419073,11 @@ async function runSkillsSubcommand(argv) {
|
|
|
418742
419073
|
case "help":
|
|
418743
419074
|
case "--help":
|
|
418744
419075
|
case "-h":
|
|
418745
|
-
|
|
419076
|
+
printUsage16();
|
|
418746
419077
|
return 0;
|
|
418747
419078
|
default:
|
|
418748
419079
|
console.error(`Unknown action: ${action3}`);
|
|
418749
|
-
|
|
419080
|
+
printUsage16();
|
|
418750
419081
|
return 1;
|
|
418751
419082
|
}
|
|
418752
419083
|
}
|
|
@@ -418765,8 +419096,8 @@ var init_skills4 = __esm(() => {
|
|
|
418765
419096
|
});
|
|
418766
419097
|
|
|
418767
419098
|
// src/cli/subcommands/teleport.ts
|
|
418768
|
-
import { parseArgs as
|
|
418769
|
-
function
|
|
419099
|
+
import { parseArgs as parseArgs19 } from "node:util";
|
|
419100
|
+
function printUsage17() {
|
|
418770
419101
|
console.log(`
|
|
418771
419102
|
Usage:
|
|
418772
419103
|
letta teleport list
|
|
@@ -418789,7 +419120,7 @@ Notes:
|
|
|
418789
419120
|
`.trim());
|
|
418790
419121
|
}
|
|
418791
419122
|
function parseTeleportArgs(argv) {
|
|
418792
|
-
return
|
|
419123
|
+
return parseArgs19({
|
|
418793
419124
|
args: argv,
|
|
418794
419125
|
options: TELEPORT_OPTIONS,
|
|
418795
419126
|
strict: true,
|
|
@@ -418862,12 +419193,12 @@ async function runTeleportSubcommand(argv, deps = {}) {
|
|
|
418862
419193
|
parsed = parseTeleportArgs(argv);
|
|
418863
419194
|
} catch (error4) {
|
|
418864
419195
|
console.error(`Error: ${error4 instanceof Error ? error4.message : error4}`);
|
|
418865
|
-
|
|
419196
|
+
printUsage17();
|
|
418866
419197
|
return 1;
|
|
418867
419198
|
}
|
|
418868
419199
|
const [action3] = parsed.positionals;
|
|
418869
419200
|
if (parsed.values.help || !action3 || action3 === "help") {
|
|
418870
|
-
|
|
419201
|
+
printUsage17();
|
|
418871
419202
|
return 0;
|
|
418872
419203
|
}
|
|
418873
419204
|
try {
|
|
@@ -419303,8 +419634,8 @@ var init_review = () => {};
|
|
|
419303
419634
|
|
|
419304
419635
|
// src/cli/subcommands/trajectories.ts
|
|
419305
419636
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
419306
|
-
import { parseArgs as
|
|
419307
|
-
function
|
|
419637
|
+
import { parseArgs as parseArgs20 } from "node:util";
|
|
419638
|
+
function printUsage18() {
|
|
419308
419639
|
console.log(`
|
|
419309
419640
|
Usage:
|
|
419310
419641
|
letta trajectories export [options]
|
|
@@ -419442,7 +419773,7 @@ ${results.length} session(s) matched "${keyword}"`);
|
|
|
419442
419773
|
return 0;
|
|
419443
419774
|
}
|
|
419444
419775
|
function parseTrajectoriesArgs(argv) {
|
|
419445
|
-
return
|
|
419776
|
+
return parseArgs20({
|
|
419446
419777
|
args: argv,
|
|
419447
419778
|
options: TRAJECTORIES_OPTIONS,
|
|
419448
419779
|
strict: true,
|
|
@@ -419455,12 +419786,12 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
419455
419786
|
parsed = parseTrajectoriesArgs(argv);
|
|
419456
419787
|
} catch (error4) {
|
|
419457
419788
|
console.error(`Error: ${error4 instanceof Error ? error4.message : String(error4)}`);
|
|
419458
|
-
|
|
419789
|
+
printUsage18();
|
|
419459
419790
|
return 1;
|
|
419460
419791
|
}
|
|
419461
419792
|
const [action3] = parsed.positionals;
|
|
419462
419793
|
if (parsed.values.help || action3 === "help" || !action3) {
|
|
419463
|
-
|
|
419794
|
+
printUsage18();
|
|
419464
419795
|
return parsed.values.help || action3 === "help" ? 0 : 1;
|
|
419465
419796
|
}
|
|
419466
419797
|
const asJson = Boolean(parsed.values.json);
|
|
@@ -419492,7 +419823,7 @@ async function runTrajectoriesSubcommand(argv) {
|
|
|
419492
419823
|
}
|
|
419493
419824
|
if (action3 !== "export") {
|
|
419494
419825
|
console.error(`Unknown command: ${action3}`);
|
|
419495
|
-
|
|
419826
|
+
printUsage18();
|
|
419496
419827
|
return 1;
|
|
419497
419828
|
}
|
|
419498
419829
|
const options = {
|
|
@@ -421041,9 +421372,9 @@ class ChannelRichDraftStreamerImpl {
|
|
|
421041
421372
|
return;
|
|
421042
421373
|
}
|
|
421043
421374
|
const record3 = asRecord10(chunk2);
|
|
421044
|
-
const messageType =
|
|
421375
|
+
const messageType = stringValue5(record3?.message_type);
|
|
421045
421376
|
if (messageType === "tool_return_message") {
|
|
421046
|
-
const toolCallId =
|
|
421377
|
+
const toolCallId = stringValue5(record3?.tool_call_id);
|
|
421047
421378
|
if (toolCallId) {
|
|
421048
421379
|
this.finishCall(toolCallId);
|
|
421049
421380
|
}
|
|
@@ -421336,14 +421667,14 @@ function extractToolCallFragments2(record3) {
|
|
|
421336
421667
|
const fragments = [];
|
|
421337
421668
|
for (const rawToolCall of rawToolCalls) {
|
|
421338
421669
|
const toolCall = asRecord10(rawToolCall);
|
|
421339
|
-
const toolCallId =
|
|
421670
|
+
const toolCallId = stringValue5(toolCall?.tool_call_id);
|
|
421340
421671
|
if (!toolCallId) {
|
|
421341
421672
|
continue;
|
|
421342
421673
|
}
|
|
421343
421674
|
fragments.push({
|
|
421344
421675
|
toolCallId,
|
|
421345
|
-
name:
|
|
421346
|
-
argumentsDelta:
|
|
421676
|
+
name: stringValue5(toolCall?.name),
|
|
421677
|
+
argumentsDelta: stringValue5(toolCall?.arguments)
|
|
421347
421678
|
});
|
|
421348
421679
|
}
|
|
421349
421680
|
return fragments;
|
|
@@ -421463,7 +421794,7 @@ function buildDraftId(seed) {
|
|
|
421463
421794
|
function asRecord10(value) {
|
|
421464
421795
|
return value && typeof value === "object" ? value : null;
|
|
421465
421796
|
}
|
|
421466
|
-
function
|
|
421797
|
+
function stringValue5(value) {
|
|
421467
421798
|
return typeof value === "string" ? value : undefined;
|
|
421468
421799
|
}
|
|
421469
421800
|
var MESSAGE_CHANNEL_TOOL_NAMES, DEFAULT_DRAFT_DEBOUNCE_MS = 1000, MIN_DRAFT_TEXT_LENGTH = 1;
|
|
@@ -424331,14 +424662,14 @@ var exports_channel_gateway = {};
|
|
|
424331
424662
|
__export(exports_channel_gateway, {
|
|
424332
424663
|
runChannelGatewaySubcommand: () => runChannelGatewaySubcommand
|
|
424333
424664
|
});
|
|
424334
|
-
import { parseArgs as
|
|
424665
|
+
import { parseArgs as parseArgs21 } from "node:util";
|
|
424335
424666
|
function isGatewayCommandEnvelope(value) {
|
|
424336
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");
|
|
424337
424668
|
}
|
|
424338
424669
|
async function runChannelGatewaySubcommand(argv) {
|
|
424339
424670
|
let values3;
|
|
424340
424671
|
try {
|
|
424341
|
-
({ values: values3 } =
|
|
424672
|
+
({ values: values3 } = parseArgs21({
|
|
424342
424673
|
args: argv,
|
|
424343
424674
|
strict: true,
|
|
424344
424675
|
allowPositionals: false,
|
|
@@ -424477,6 +424808,7 @@ function subcommandNeedsEarlyBackendMode(command) {
|
|
|
424477
424808
|
case "sandbox":
|
|
424478
424809
|
case "secret":
|
|
424479
424810
|
case "server":
|
|
424811
|
+
case "server-mcp":
|
|
424480
424812
|
case "shared-memory":
|
|
424481
424813
|
case "skills":
|
|
424482
424814
|
case "teleport":
|
|
@@ -424519,6 +424851,8 @@ async function runSubcommand(argv) {
|
|
|
424519
424851
|
return runTeleportSubcommand(rest4);
|
|
424520
424852
|
case "server":
|
|
424521
424853
|
return runServerSubcommand(rest4);
|
|
424854
|
+
case "server-mcp":
|
|
424855
|
+
return runServerMcpSubcommand(rest4);
|
|
424522
424856
|
case "remote":
|
|
424523
424857
|
return runListenSubcommand(rest4);
|
|
424524
424858
|
case "connect":
|
|
@@ -424564,6 +424898,7 @@ var init_router = __esm(async () => {
|
|
|
424564
424898
|
init_messages10();
|
|
424565
424899
|
init_sandbox2();
|
|
424566
424900
|
init_secret();
|
|
424901
|
+
init_server_mcp();
|
|
424567
424902
|
init_shared_memory();
|
|
424568
424903
|
init_skills4();
|
|
424569
424904
|
init_teleport2();
|
|
@@ -442523,7 +442858,7 @@ var init_mcp_client = __esm(() => {
|
|
|
442523
442858
|
init_streamableHttp();
|
|
442524
442859
|
DEFAULT_CLIENT_INFO = {
|
|
442525
442860
|
name: "letta-code",
|
|
442526
|
-
version: "0.31.
|
|
442861
|
+
version: "0.31.2"
|
|
442527
442862
|
};
|
|
442528
442863
|
});
|
|
442529
442864
|
|
|
@@ -462400,110 +462735,6 @@ var init_LettaLoginOverlay = __esm(async () => {
|
|
|
462400
462735
|
jsx_dev_runtime63 = __toESM(require_jsx_dev_runtime(), 1);
|
|
462401
462736
|
});
|
|
462402
462737
|
|
|
462403
|
-
// src/backend/api/mcp-servers.ts
|
|
462404
|
-
function withTimeout2(promise2, timeoutMs, label) {
|
|
462405
|
-
let timer;
|
|
462406
|
-
const timeout = new Promise((_4, reject2) => {
|
|
462407
|
-
timer = setTimeout(() => reject2(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
462408
|
-
});
|
|
462409
|
-
return Promise.race([promise2, timeout]).finally(() => {
|
|
462410
|
-
if (timer !== undefined)
|
|
462411
|
-
clearTimeout(timer);
|
|
462412
|
-
});
|
|
462413
|
-
}
|
|
462414
|
-
function listServerMcpServers(client, timeoutMs = 1e4) {
|
|
462415
|
-
return withTimeout2(client.mcpServers.list(), timeoutMs, "Listing server-side MCP servers");
|
|
462416
|
-
}
|
|
462417
|
-
async function listLiveServerMcpTools(client, serverName, timeoutMs = 15000) {
|
|
462418
|
-
const result2 = await withTimeout2(client.get(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/tools`), timeoutMs, `Listing tools for MCP server "${serverName}"`);
|
|
462419
|
-
if (!Array.isArray(result2))
|
|
462420
|
-
return [];
|
|
462421
|
-
return result2.filter((tool) => typeof tool === "object" && tool !== null && typeof tool.name === "string");
|
|
462422
|
-
}
|
|
462423
|
-
async function loadServerMcpEntries(client, timeoutMs = 15000) {
|
|
462424
|
-
const servers = await listServerMcpServers(client, timeoutMs);
|
|
462425
|
-
return Promise.all(servers.map(async (server2) => {
|
|
462426
|
-
try {
|
|
462427
|
-
const tools = await listLiveServerMcpTools(client, server2.server_name, timeoutMs);
|
|
462428
|
-
return { server: server2, tools };
|
|
462429
|
-
} catch (cause) {
|
|
462430
|
-
return {
|
|
462431
|
-
server: server2,
|
|
462432
|
-
tools: [],
|
|
462433
|
-
toolsError: cause instanceof Error ? cause.message : String(cause)
|
|
462434
|
-
};
|
|
462435
|
-
}
|
|
462436
|
-
}));
|
|
462437
|
-
}
|
|
462438
|
-
function parseMcpMetadata(tool) {
|
|
462439
|
-
const metadata = tool.metadata_;
|
|
462440
|
-
const mcp = metadata?.mcp;
|
|
462441
|
-
if (typeof mcp !== "object" || mcp === null)
|
|
462442
|
-
return null;
|
|
462443
|
-
const { server_id, server_name } = mcp;
|
|
462444
|
-
return {
|
|
462445
|
-
...typeof server_id === "string" && { serverId: server_id },
|
|
462446
|
-
...typeof server_name === "string" && { serverName: server_name }
|
|
462447
|
-
};
|
|
462448
|
-
}
|
|
462449
|
-
async function listAgentMcpAttachments(client, agentId) {
|
|
462450
|
-
const attachments = [];
|
|
462451
|
-
for await (const tool of client.agents.tools.list(agentId, { limit: 100 })) {
|
|
462452
|
-
if (tool.tool_type !== "external_mcp" || !tool.id || !tool.name)
|
|
462453
|
-
continue;
|
|
462454
|
-
attachments.push({
|
|
462455
|
-
toolId: tool.id,
|
|
462456
|
-
toolName: tool.name,
|
|
462457
|
-
...parseMcpMetadata(tool)
|
|
462458
|
-
});
|
|
462459
|
-
}
|
|
462460
|
-
return attachments;
|
|
462461
|
-
}
|
|
462462
|
-
function attachmentsForEntry(entry, attachments) {
|
|
462463
|
-
return attachments.filter((attachment) => attachment.serverId && entry.server.id ? attachment.serverId === entry.server.id : attachment.serverName === entry.server.server_name);
|
|
462464
|
-
}
|
|
462465
|
-
function attachedToolNamesForEntry(entry, attachments) {
|
|
462466
|
-
return new Set(attachmentsForEntry(entry, attachments).map((attachment) => attachment.toolName));
|
|
462467
|
-
}
|
|
462468
|
-
async function registerServerMcpTool(client, serverName, toolName) {
|
|
462469
|
-
const result2 = await client.post(`/v1/tools/mcp/servers/${encodeURIComponent(serverName)}/${encodeURIComponent(toolName)}`);
|
|
462470
|
-
if (typeof result2?.id !== "string") {
|
|
462471
|
-
throw new Error(`Registering MCP tool "${toolName}" on server "${serverName}" returned no tool id`);
|
|
462472
|
-
}
|
|
462473
|
-
return { id: result2.id };
|
|
462474
|
-
}
|
|
462475
|
-
async function attachServerMcpTools(client, agentId, serverName, toolNames) {
|
|
462476
|
-
await Promise.all(toolNames.map(async (toolName) => {
|
|
462477
|
-
const { id: id2 } = await registerServerMcpTool(client, serverName, toolName);
|
|
462478
|
-
await client.agents.tools.attach(id2, { agent_id: agentId });
|
|
462479
|
-
}));
|
|
462480
|
-
}
|
|
462481
|
-
async function detachServerMcpTools(client, agentId, toolIds) {
|
|
462482
|
-
await Promise.all(toolIds.map((toolId) => client.agents.tools.detach(toolId, { agent_id: agentId })));
|
|
462483
|
-
}
|
|
462484
|
-
function refreshServerMcpServer(client, mcpServerId, agentId) {
|
|
462485
|
-
return client.mcpServers.refresh(mcpServerId, { agent_id: agentId });
|
|
462486
|
-
}
|
|
462487
|
-
function planServerMcpToggle(entry, attachments) {
|
|
462488
|
-
const attached = attachmentsForEntry(entry, attachments);
|
|
462489
|
-
if (attached.length > 0) {
|
|
462490
|
-
return {
|
|
462491
|
-
action: "detach",
|
|
462492
|
-
toolIds: attached.map((attachment) => attachment.toolId)
|
|
462493
|
-
};
|
|
462494
|
-
}
|
|
462495
|
-
return { action: "attach", toolNames: entry.tools.map((tool) => tool.name) };
|
|
462496
|
-
}
|
|
462497
|
-
function describeServerMcpTarget(server2) {
|
|
462498
|
-
if ("server_url" in server2 && server2.server_url) {
|
|
462499
|
-
return server2.server_url;
|
|
462500
|
-
}
|
|
462501
|
-
if ("command" in server2 && server2.command) {
|
|
462502
|
-
return [server2.command, ...server2.args ?? []].join(" ");
|
|
462503
|
-
}
|
|
462504
|
-
return "";
|
|
462505
|
-
}
|
|
462506
|
-
|
|
462507
462738
|
// src/cli/components/McpSelector.tsx
|
|
462508
462739
|
function buildMcpRows(localStates, serverEntries) {
|
|
462509
462740
|
return [
|
|
@@ -462620,6 +462851,7 @@ var import_react87, jsx_dev_runtime64, SOLID_LINE12 = "─", DISPLAY_PAGE_SIZE2
|
|
|
462620
462851
|
var init_McpSelector = __esm(async () => {
|
|
462621
462852
|
init_backend2();
|
|
462622
462853
|
init_client2();
|
|
462854
|
+
init_mcp_servers2();
|
|
462623
462855
|
init_truncate_text();
|
|
462624
462856
|
init_use_terminal_width();
|
|
462625
462857
|
init_mcp_oauth();
|
|
@@ -472249,7 +472481,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
472249
472481
|
let shellSemanticKind = null;
|
|
472250
472482
|
let hasShellDescription = false;
|
|
472251
472483
|
if (!isQuestionTool(rawName)) {
|
|
472252
|
-
const
|
|
472484
|
+
const parseArgs22 = () => {
|
|
472253
472485
|
if (!argsText.trim()) {
|
|
472254
472486
|
return { formatted: null, parseable: true };
|
|
472255
472487
|
}
|
|
@@ -472263,7 +472495,7 @@ var init_ToolCallMessageRich = __esm(async () => {
|
|
|
472263
472495
|
return { formatted: null, parseable: false };
|
|
472264
472496
|
}
|
|
472265
472497
|
};
|
|
472266
|
-
const { formatted, parseable } =
|
|
472498
|
+
const { formatted, parseable } = parseArgs22();
|
|
472267
472499
|
const argsComplete = parseable || line.phase === "running" || line.phase === "finished" || !isStreaming;
|
|
472268
472500
|
if (!argsComplete) {
|
|
472269
472501
|
args = "(…)";
|
|
@@ -474479,7 +474711,7 @@ function updateCommandResult(buffersRef, refreshDerived, cmdId, input, output, s
|
|
|
474479
474711
|
buffersRef.current.byId.set(cmdId, line);
|
|
474480
474712
|
refreshDerived();
|
|
474481
474713
|
}
|
|
474482
|
-
function
|
|
474714
|
+
function parseArgs22(msg) {
|
|
474483
474715
|
return msg.trim().split(/\s+/).filter(Boolean);
|
|
474484
474716
|
}
|
|
474485
474717
|
function formatConnectUsage() {
|
|
@@ -474861,7 +475093,7 @@ ${formatBedrockUsage2()}`, false);
|
|
|
474861
475093
|
}
|
|
474862
475094
|
}
|
|
474863
475095
|
async function handleConnect(ctx, msg) {
|
|
474864
|
-
const parts =
|
|
475096
|
+
const parts = parseArgs22(msg);
|
|
474865
475097
|
const providerToken = parts[1];
|
|
474866
475098
|
if (!providerToken) {
|
|
474867
475099
|
addCommandResult(ctx.buffersRef, ctx.refreshDerived, msg, formatConnectUsage(), false);
|
|
@@ -505797,9 +506029,7 @@ USAGE
|
|
|
505797
506029
|
letta -p "..." One-off prompt in headless mode (no TTY UI)
|
|
505798
506030
|
|
|
505799
506031
|
# maintenance
|
|
505800
|
-
letta update
|
|
505801
|
-
letta upgrade Alias for \`letta update\`
|
|
505802
|
-
letta --update/--upgrade Aliases for \`letta update\`
|
|
506032
|
+
letta update Check for updates and install (aliases: upgrade, --update, --upgrade)
|
|
505803
506033
|
letta memory ... Memory filesystem subcommands
|
|
505804
506034
|
letta agents ... Agents subcommands (JSON-only)
|
|
505805
506035
|
letta environments ... List available remote environments (JSON-only)
|
|
@@ -505808,6 +506038,7 @@ USAGE
|
|
|
505808
506038
|
letta mods ... List and manage local mods
|
|
505809
506039
|
letta sandbox ... Transfer files to or from the current Cloud sandbox
|
|
505810
506040
|
letta server ... Run a remote environment, channels, or the App Server
|
|
506041
|
+
letta server-mcp ... Use MCP servers connected to an agent
|
|
505811
506042
|
letta connect ... Connect providers from terminal
|
|
505812
506043
|
letta backend ... Show or set the default backend
|
|
505813
506044
|
letta setup Re-run first-run setup
|
|
@@ -505839,6 +506070,7 @@ SUBCOMMANDS
|
|
|
505839
506070
|
letta mods enable <package-spec>
|
|
505840
506071
|
letta mods disable <package-spec>
|
|
505841
506072
|
letta mods remove <package-spec>
|
|
506073
|
+
letta server-mcp list|tools|run ... [--agent <id>]
|
|
505842
506074
|
letta server [--env-name <name> | --listen [url]] [options]
|
|
505843
506075
|
letta connect <provider> [options]
|
|
505844
506076
|
letta install <thing> [--agent <id> | -n <name>]
|
|
@@ -509659,4 +509891,4 @@ function registerBunOAuthFlows() {
|
|
|
509659
509891
|
registerBunOAuthFlows();
|
|
509660
509892
|
await init_src5().then(() => exports_src2);
|
|
509661
509893
|
|
|
509662
|
-
//# debugId=
|
|
509894
|
+
//# debugId=48BEECE3782D14CC64756E2164756E21
|