---
title: Cloud repositories | Letta Docs
description: Upload hosted text files and attach them to Letta Agent SDK Cloud sessions
---

Cloud repositories let your application upload text files to the Letta Developer Platform and make them available to Letta Agent during a Cloud session. Use them for app-provided input files or shared working context that an agent should inspect or update.

Repository APIs and repository session resources require a `LettaAgentClient` configured with `backend: "cloud"`. Local and remote backends reject non-empty repository resources.

A Cloud repository is a Letta-hosted, git-backed collection of text files. It is not a GitHub repository or a directory on the machine running your application. When you attach one to a session, Letta Code syncs it into the Cloud runtime so the agent can inspect it with its file and shell tools.

## Create and attach a repository

Create a repository, add files, and pass its ID in the session’s `resources` option:

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


const client = new LettaAgentClient({
  backend: "cloud",
  apiKey: process.env.LETTA_API_KEY,
});


const repository = await client.repositories.create({
  name: "launch-inputs",
});


await client.repositories.files.create(repository.id, {
  path: "brief.md",
  content: "# Launch brief\n\nTarget date: September 15\n",
});


const agentId = await client.createAgent({
  model: "anthropic/claude-opus-4-8",
  persona:
    "You are a product operations partner who turns source material into concise, actionable plans.",
});


await using session = client.createSession(agentId, {
  resources: [
    {
      type: "repository",
      repositoryId: repository.id,
    },
  ],
});


await session.send(
  "Read the launch brief, identify missing decisions, and write an action plan.",
);


for await (const message of session.stream()) {
  if (message.type === "assistant") console.log(message.content);
}
```

`client.createSession()` and `client.resumeSession()` initialize lazily. During initialization, the SDK checks which repositories are already linked to the agent, attaches missing repositories, waits for each attachment to become visible, and then starts the Cloud runtime.

## Manage files

File helpers are available under `client.repositories.files`:

| Method                         | Description                                              |
| ------------------------------ | -------------------------------------------------------- |
| `list(repositoryId, params?)`  | List files and directories at the current or a given ref |
| `create(repositoryId, params)` | Create a text file                                       |
| `read(repositoryId, params)`   | Read a text file at the current or a given ref           |
| `update(repositoryId, params)` | Replace content, rename a file, or both                  |
| `delete(repositoryId, params)` | Delete a file                                            |

Use a content hash precondition when an update should fail rather than overwrite a file that changed after you read it:

```
const current = await client.repositories.files.read(repository.id, {
  path: "brief.md",
});


const updated = await client.repositories.files.update(repository.id, {
  path: current.path,
  content: `${current.content}\nOwner: Product Operations\n`,
  precondition: {
    contentSha256: current.contentSha256,
  },
});


console.log(updated.commitSha);
```

To rename a file, pass `newPath` to `update()`:

```
await client.repositories.files.update(repository.id, {
  path: "brief.md",
  newPath: "planning/brief.md",
});
```

## Read version history

Each file mutation creates a commit. Use `client.repositories.versions` to list commits and read a file at a particular commit:

```
const versions = await client.repositories.versions.list(repository.id, {
  path: "planning/brief.md",
  limit: 20,
});


const previous = await client.repositories.versions.get(
  repository.id,
  versions[0].sha,
  { path: "planning/brief.md" },
);


console.log(previous.content);
```

`files.list()` and `files.read()` also accept `ref` when you need a consistent historical snapshot.

## Session lifecycle

Repository resources are links between a hosted repository and an agent. The SDK manages those links for the lifetime of a session:

- Duplicate repository IDs in one `resources` array are deduplicated.
- A repository already linked to the agent is not linked again or detached by the SDK.
- If session initialization fails, the SDK attempts to remove links it created.
- When the session closes, the SDK attempts to remove only links it created.

Session cleanup is asynchronous. Abrupt process termination or a network failure can leave a repository linked to the agent. Repository links are agent-scoped, and concurrent SDK sessions are not reference-counted. If multiple sessions use the same agent and temporary repository, one session can remove the link while another is still running.

The SDK does not currently expose explicit persistent attach or detach methods. Use `resources` when the attachment should follow the SDK session lifecycle.

## Permissions and limits

| Capability             | Current behavior                                                       |
| ---------------------- | ---------------------------------------------------------------------- |
| Attachment permissions | New SDK-managed links use the platform default, currently `read_write` |
| Existing links         | Keep their existing permissions                                        |
| Content                | UTF-8 text passed as a JavaScript string                               |
| File size              | Up to 10 MiB per file                                                  |
| File count             | Up to 2,000 files per repository                                       |
| Upload API             | Creates or updates one file per request; no bulk directory helper      |
| Repository names       | Unique, up to 64 letters, numbers, dots, underscores, or hyphens       |
| Delete behavior        | `client.repositories.delete()` soft-deletes the repository             |

The `RepositoryResource` type does not currently expose a permission setting. Because a newly attached repository defaults to `read_write`, an agent can modify and commit files in it. The Agent SDK cannot create a read-only attachment today; an existing read-only link keeps its current permissions.

See the [SDK reference](/letta-agent-sdk/reference#cloud-repository-client/index.md) for all repository methods and types.
