Letta Agent SDK — the SDK for stateful agents

Create an agent once.Resume it from anywhere.

The TypeScript SDK for stateful agents. Identity and memory stay with the agent — not the process, the model, or the machine.

Get started npm install @letta-ai/letta-agent-sdk

deploy.ts · Mondaycloud · agent-3f97…

import { LettaAgentClient }  
  from "@letta-ai/letta-agent-sdk";
const client = new LettaAgentClient({
  backend: "cloud",
});
// Create the agent once...
const agentId = await client.createAgent({
  persona: "You are Nora, an analyst.",
});
// → "agent-3f97f111-…"

anywhere.ts · Thursdaycloud · agent-3f97…

// ...then resume it, from anywhere.
await using session =
  client.resumeSession(agentId);
await session.send(
  "What changed since last week?");
for await (const msg of session.stream()) {
  if (msg.type === "assistant")
    process.stdout.write(msg.content);
}
// → streams Nora's Thursday brief

Same agent, different process. Nora already knows who she is, what changed since last week, and how you like your briefs.

Built by the team behind MemGPT, the paper that introduced memory management for LLM agents. Open source on GitHub.

Memory is part of the agent, not the app

Memory is a git repository the agent owns. It follows the agent everywhere it works, and the agent edits it as it learns.

create-quinn.tscloud · agent-8c21…

const agentId = await client.createAgent({
  model: "anthropic/claude-opus-4-8",
  memory: [{\
    label: "persona",\
    value: "You are Quinn, an analyst.",\
  }, {\
    label: "team-context",\
    value: "The team ships on Thursdays.",\
  }],
});

agent-8c21d04a · memory (git)

├── system/
│   ├── persona.mdin context every turn
│   └── team-context.mdin context every turn
└── notes/
    └── competitors.mdread on demand

4d1c2ea learned: launch moved to Sept— Quinn, 2h ago

This repository follows the agent, not your repo.

Read how MemFS works→ Shared memory repositories→ Installing skills→

One interface. Three backends.

One client, three backends. Swap one string — nothing else changes.

"cloud""local""remote"

client.tscloud · agent-3f97…

// Managed everything. State lives
// in Letta Cloud; tools in a sandbox.
const client = new LettaAgentClient({
  backend: "cloud",
  apiKey: process.env.LETTA_API_KEY,
});

client.tslocal · agent-local-3f97…

// No account, no server to start —
// the SDK owns a local App Server.
// State stays on this machine.
const client = new LettaAgentClient({
  backend: "local",
});

client.tsremote · agent-3f97…

// letta server --backend local
//   --listen ws://127.0.0.1:4500
const client = new LettaAgentClient({
  backend: "remote",
  url: "http://127.0.0.1:4500",
  authToken:
    process.env.LETTA_APP_SERVER_TOKEN,
});
"cloud" "local" "remote"
Agent state lives Letta Cloud Current machine Determined by the App Server backend
Tools execute Managed sandbox, or a computer you connect Current machine App Server machine
Account required Letta API key None Your own auth token
Runtime you run None SDK-owned subprocess (Node 22.19+) App Server you operate (Node 22.19+)
Best for Managed everything Fully local state and execution A runtime under your control

No account required for the local backend. Your code doesn't change when you swap the backend string.

TypeScript and JavaScript today; Python applications use the App Server WebSocket protocol directly.

Deployment guide→

Pick the computer. Keep the agent.

A computer is where the agent works — separate from who the agent is. Managed sandbox by default, or connect your own machine.

byom.tscloud · agent-3f97…

// Managed sandbox by default,
// kept warm across reconnects —
// or bring your own machine:
await using session =
  client.resumeSession(agentId, {
    computer: { name: "work-laptop" },
    cwd: "/workspace/project",
  });

agent-3f97f111

↓ works on

One agent, three places it can work today.

Computers and sandboxes→ MCP & client tools→

Typed events in, render-ready rows out

Streaming, queueing, and optimistic updates — in the same client the browser uses. The accumulator turns the event stream into rows your UI renders.

transcript.tscloud · agent-3f97…

import { createTranscriptAccumulator }
  from "@letta-ai/letta-agent-sdk";

const transcript =
  createTranscriptAccumulator();

await session.send(
  "Summarize yesterday's deploys.");

for await (const msg of session.stream()) {
  const rows = transcript.apply(msg);
  render(rows);
}

agent-3f97f111 · one turn

user"Summarize yesterday's deploys."

reasoning"The user wants me to run a…"

tool_callBash · "command": "echo hello…

tool_resulthello-from-docs

The command printed: hello-from-docs.

resultsuccess · end_turn · 3371ms · run-fd5e…

The stream contract→ Explore the Expo mobile app→ Browser, React Native & Expo clients→

Human approvals are part of the turn

Gate any tool call on your own UI. The turn waits for the human's Allow or Deny — and approvals left pending survive a dropped connection.

approvals.tscloud · agent-3f97…

// inside createSession(agentId, { … }):
canUseTool: async (tool, args, ctx) => {
  // your approval UI:
  const ok = await askUser(tool, ctx);
  return ok
    ? { behavior: "allow" }
    : { behavior: "deny", interrupt: true };
},

Edit wants to change deploy.yaml

- staging+ production

AllowDeny

Your UI shows the tool call and its diff; the turn waits for the human's Allow or Deny.

Permission modes and rules→

Start from a running app

Every example is a complete application in the SDK repository. Clone it, install, run.

web-chat→ \ A web UI for chatting with an agent — streaming to the browser. bug-fixer→ \ A stateful agent that finds and fixes bugs, remembering the codebase and past fixes across sessions. research-team→ \ A multi-agent research system — shared memory and collaborative agents that improve over time. release-notes→ \ Release notes from git commits, learning your formatting preferences over time. custom-tools→ \ Client tools that execute locally in your process while the agent runs in a cloud sandbox. dungeon-master→ \ A stateful DM that creates its own game system and keeps campaigns in MemFS.

shell

git clone \
https://github.com/letta-ai/letta-agent-sdk
cd letta-agent-sdk/examples/web-chat
npm install

All nine examples→

Your first stateful agent is one npm install away

npm install @letta-ai/letta-agent-sdk

Read the quickstart Browse the SDK reference

No account needed for the local backend. Cloud needs an API key. Node.js 22.19+ only if you run the runtime yourself.