Skip to content

GitHub Storage

strands-github-storage is a Storage backend that persists each entry as a file in a GitHub repository, at the entry’s key path on a branch. Because the store is a git repository, its contents are browsable in the GitHub UI, diffable per change, and versioned in history.

It implements the SDK’s four-method Storage interface (write, read, delete, list), so it plugs in anywhere a Storage is accepted — session snapshots, context offloading, and file-backed memory stores such as FileMemoryStore.

Terminal window
npm install strands-github-storage

@strands-agents/sdk is a peer dependency; @octokit/rest is bundled.

import { GithubStorage } from 'strands-github-storage'
const storage = new GithubStorage({
owner: 'myorg',
repo: 'agent-memory',
branch: 'main', // optional, defaults to 'main'
token: process.env.GITHUB_TOKEN, // required for writes and private repos
})
await storage.write('facts/note.md', new TextEncoder().encode('remember this'))
const bytes = await storage.read('facts/note.md') // Uint8Array | null
const keys = await storage.list('facts/') // ['facts/note.md']
await storage.delete('facts/note.md')

Pass it as the storage for a FileMemoryStore so an agent’s knowledge lives in a browsable, versioned repo:

import { Agent, MemoryManager } from '@strands-agents/sdk'
import { FileMemoryStore } from '@strands-agents/sdk/vended-memory-stores/file-memory-store'
import { GithubStorage } from 'strands-github-storage'
const memoryStore = new FileMemoryStore({
name: 'agent-memory',
storage: new GithubStorage({ owner: 'myorg', repo: 'agent-memory', token }),
})
const agent = new Agent({ model, memoryManager: new MemoryManager({ stores: [memoryStore] }) })
ParameterRequiredDescription
ownerYesRepository owner (user or organization login).
repoYesRepository name.
branchNoBranch to read from and commit to. Defaults to main.
tokenFor writesGitHub token. Needed for any write and for reading private repos.
octokitNoA pre-configured Octokit client, as an alternative to token (e.g. to add retry/throttling plugins).
  • One commit per operation. Each write and delete is its own commit (update <key> / delete <key>). A burst of writes produces a burst of commits.
  • Single writer per branch. Commits advance the branch ref without a compare-and-swap retry, so a concurrent writer that moves the branch head surfaces GitHub’s non-fast-forward rejection as a StorageError rather than being retried.
  • read is limited to files under 1 MB — the ceiling of the GitHub contents API’s inline response. Markdown memory is far below this.
  • list fails loud on truncation. GitHub’s git-tree API caps very large trees and does not paginate; rather than return a silent partial listing, list throws a StorageError.
  • No built-in rate-limit handling. To add exponential backoff on 429/5xx, pass an octokit client configured with @octokit/plugin-throttling / @octokit/plugin-retry.