Use GitHub Gists as a persistent key-value filesystem — ideal for AI agent memory.
pip install gistfsWith optional integrations:
pip install gistfs[llamaindex] # LlamaIndex KVStore
pip install gistfs[langgraph] # LangGraph BaseStore
pip install gistfs[all] # everythingNo need to create a gist manually — bootstrap one from code:
from gistfs import GistFS
gfs = GistFS.create(description="my agent memory")
print(gfs.gist_id) # save this for later
# Or with GistMemory:
from gistfs import GistMemory
mem = GistMemory.create(description="my agent memory")from gistfs import GistFS
with GistFS(gist_id="your_gist_id") as gfs:
gfs.write("config.json", {"model": "gpt-4", "temperature": 0.7})
config = gfs.read("config.json")
print(gfs.list_files())
gfs.delete("config.json")with GistFS(gist_id="your_gist_id") as gfs:
with gfs.open("notes.txt", "w") as f:
f.write("hello world")
with gfs.open("notes.txt", "r") as f:
content = f.read()
with gfs.open("notes.txt", "a") as f:
f.write("\nappended line")from gistfs import GistMemory
with GistMemory(gist_id="your_gist_id") as mem:
mem.put("conversation_1", {"messages": [{"role": "user", "content": "hi"}]})
history = mem.get("conversation_1")
all_data = mem.get_all()
mem.delete("conversation_1")from gistfs.integrations.llamaindex import GistKVStore
store = GistKVStore(gist_id="your_gist_id")
store.put("doc1", {"text": "hello world"}, collection="docstore")
doc = store.get("doc1", collection="docstore")from gistfs.integrations.langgraph import GistStore
store = GistStore(gist_id="your_gist_id")
store.put(("user", "prefs"), "theme", {"value": "dark"})
item = store.get(("user", "prefs"), "theme")Install with encryption support:
pip install gistfs[encryption]File content is encrypted (Fernet) and base64-encoded before being sent to GitHub, and decrypted transparently on read. Pass an encryption_key to any class:
from gistfs import GistFS, derive_key
from gistfs.integrations.langgraph import GistStore
# Derive a key from a password (store the salt for later reuse)
key, salt = derive_key("mypassword", salt=b"gistfs-demo-salt")
# GistFS — files are encrypted at rest in the gist
with GistFS(gist_id="your_gist_id", encryption_key=key) as gfs:
gfs.write("secrets.json", {"api_key": "sk-123"})
assert gfs.read("secrets.json") == {"api_key": "sk-123"}
# LangGraph store — same key, same transparent encryption
store = GistStore(gist_id="your_gist_id", encryption_key=key)
store.put(("user", "prefs"), "theme", {"value": "dark"})Set the GITHUB_TOKEN environment variable with a GitHub personal access token that has gist scope. Read-only operations on public gists work without a token.
export GITHUB_TOKEN=ghp_your_token_hereOr pass it directly:
gfs = GistFS(gist_id="abc123", token="ghp_...")