Skip to content

About

Depot — Claude Code plugin that syncs session transcripts to your team's Depot (institutional memory).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

28 Commits

Folders and files

Repository files navigation

Depot uploader (Claude Code plugin)

Ships your new Claude Code transcript records to your team's Depot server, so Depot can distill them into cited, per-project Memories. Uploads are incremental (only lines added since the last run) and idempotent (safe to run repeatedly and safe to interrupt).

It is three things in one directory:

  • A standalone CLI — bin/depot-upload.ts — runnable with bun or node, with zero dependencies. Use it from a shell, a cron job, or --watch.
  • A Claude Code plugin that runs the CLI automatically after each session via a SessionEnd hook, plus a /depot:depot-sync slash command for on-demand syncs.
  • Depot's MCP server, so the loop closes: your transcripts flow out to Depot, and Depot's distilled memory flows back in as tools your agent calls before it works. Bundled via .mcp.json — installing the plugin wires it up.
  • The push channel — memory the agent doesn't have to ask for. A SessionStart hook injects the project's cited brief into every session that starts inside a repo Depot knows, and a PreToolUse hook injects a file's failure dossier the first time the agent is about to edit a file with recorded friction. Pull (the MCP tools) answers when the agent asks; push means it never had to know there was something to ask.

Agent tools (MCP)

The plugin registers a remote MCP server (depot, at https://depot.ingram.tech/api/mcp). It authenticates with the token saved by /depot:depot-login — read at connect time via a headersHelper, so there's no env var to set and the token is never copied or printed. Once you've logged in, your agent gets four read-only tools:

Tool What it answers
depot_list_projects Which projects does Depot have memory for? (find the slug)
depot_project_brief What's the state of this project — decisions, gotchas, and the files where work has hurt most?
depot_file_context Before I edit this file: what already broke here, and what fixed it? Plus the Memories that cite it.
depot_search_memories Have we decided / hit this before? (searches Memories, not raw transcripts)

The high-value move is depot_file_context — it's git blame for intent: the failed edits, their fixes, and the decisions behind a file, each linked to the transcript that proves it. Ask your agent to "check Depot before editing," or add it to your CLAUDE.md.

To use the server without the plugin, add it directly:

claude mcp add --transport http depot https://depot.ingram.tech/api/mcp \
  --header "Authorization: Bearer dpt_…"

The push channel (unprompted context)

Both hooks enter through bin/depot-context.ts and call GET /api/v1/context?remote=… with the saved token — a repo is identified by its origin git remote, the same routing key ingest uses, so the context you get back is for exactly the project this session's transcript will land in.

  • SessionStart injects the project brief (state of mind, load-bearing memories, friction hotspots) as additionalContext, and caches the server's hot-file list under ~/.claude/depot/context/.
  • PreToolUse (Edit|Write|NotebookEdit) checks the file about to be edited against that cached list — an ordinary edit costs zero network calls — and only for a known-hot file fetches its dossier (what failed here, what fixed it) and injects it, once per file per session. The list is keyed by the file's repo, not the directory the session started in: a session that edits across repos gets each repo's dossiers (an unseen repo's list is fetched once, then cached like SessionStart's).

Same contract as everything else in this plugin: every failure — no token, offline, repo unknown to Depot, timeout — is silent and costs nothing. With no token the hooks are inert.

What is and isn't sent (privacy)

Sent to the internal Depot server (over HTTPS, with a bearer token):

  • The raw transcript JSONL records for sessions on this machine — i.e. the full content of your Claude Code conversations and tool calls. This is the whole point: Depot reads transcripts to build memory.
  • A machine fingerprint (a random per-install UUID hashed with the hostname), your hostname, and os (process.platform).
  • Your Claude account identifier (account UUID and email, read from ~/.claude.json), so uploads are attributed per person+machine.
  • Per file: the session id, the directory the session started in, the git origin remote URL of every directory the uploaded records sat in (a session that cds between repos belongs to each of them), the current branch (best effort), and a sha256 of the bytes uploaded.

Kept on this machine: any record whose directory has no git origin remote. Depot only keeps memory for remote-backed repos; a private scratch folder — even one a session wandered into mid-way — never leaves the machine. The sync summary reports these as "kept private".

Never sent: any tokens or secrets. The uploader does not read ~/.claude/.credentials.json or any OAuth/API tokens. Only non-secret account fields (account UUID, email, user id) are read from ~/.claude.json.

If you don't want a transcript uploaded, don't run the plugin in that session (or unset DEPOT_TOKEN) — with no token the uploader exits cleanly and sends nothing.

Requirements

  • bun (preferred) or Node.js ≥ 20. The CLI runs the .ts files directly: bun runs TypeScript natively; Node ≥ 22.6 strips types natively (--experimental-strip-types on 20.x — Node 22+ needs no flag).
  • A connection — easiest via /depot:depot-login (see Getting connected).

Configuration (env vars)

Var Required Default Meaning
DEPOT_TOKEN no* from depot login Bearer token. Overrides the saved credentials file.
DEPOT_URL no https://depot.ingram.tech Depot server base URL.
DEPOT_ACCOUNT_ID no from ~/.claude.json Override the account identifier.
DEPOT_PROJECTS_DIR no ~/.claude/projects Where transcript JSONL files live.
DEPOT_WATCH_SECONDS no 60 Poll interval for --watch.
XDG_STATE_HOME no ~/.claude If set, state lives in $XDG_STATE_HOME/depot.

* Not an env var you must set — /depot:depot-login saves the token to a credentials file that both the uploader and the MCP read. With no token at all, a real run exits non-zero and the auto-sync hook stays silent.

Getting connected

Sign in through the browser — one step, no copy-paste, no token in your chat. Run the login command (or the CLI directly), approve in the browser, and the token is delivered straight back to this machine and saved to <stateDir>/credentials.json (mode 0600). The command prints no token:

/depot:depot-login
# or, fully programmatic (no agent, no model turn):
bun bin/depot-login.ts        # opens your browser; sign in → Authorize

Both the uploader and the MCP tools read the token from that file automatically — the MCP via a headersHelper that runs at connect time — so there is nothing to export and nothing to copy. After logging in, run /reload-plugins (or restart Claude Code) to connect the MCP.

Manual fallback — create a token at https://depot.ingram.tech/tokens and set export DEPOT_TOKEN="dpt_…" in your shell. DEPOT_TOKEN in the environment always overrides the saved credentials file (and the MCP headersHelper honors it too).

CLI usage

# one pass (default); prints a one-line summary
bun bin/depot-upload.ts --once

# see what would be sent — no network, no cursor changes
bun bin/depot-upload.ts --dry-run --verbose

# only a specific project (substring match on the project path)
bun bin/depot-upload.ts --once --project depot.ingram.tech

# run continuously, polling every 60s (good for a long-lived terminal/tmux)
bun bin/depot-upload.ts --watch

# with node instead of bun
node bin/depot-upload.ts --once

Flags: --once (default) · --watch · --watch-seconds N · --dry-run · --project <substr> · --verbose / -v · --help.

Run on a schedule (cron)

# every 10 minutes
*/10 * * * * DEPOT_TOKEN=dpt_… /usr/bin/node /path/to/plugin/bin/depot-upload.ts --once >> ~/.claude/depot/cron.log 2>&1

Install as a Claude Code plugin

The plugin auto-syncs after every session and adds the /depot:depot-sync command.

Via the public marketplace (recommended) — this repo is a single-plugin marketplace, so add it by owner/repo and install:

/plugin marketplace add ingram-technologies/claude-plugin-depot
/plugin install depot@depot

Local / development — point Claude Code at a checkout of this repo:

claude --plugin-dir /path/to/claude-plugin-depot

or add the local checkout as a marketplace:

/plugin marketplace add /path/to/claude-plugin-depot
/plugin install depot@depot

After install, run /depot:depot-login once to connect (see Getting connected). Then, when a session ends, the SessionEnd hook runs depot-upload --once in the background — it never blocks you, and every failure is silent (logged to ~/.claude/depot/sync.log). Run /depot:depot-sync any time to sync on demand and see the summary.

State / cursor

State lives in ~/.claude/depot/ (or $XDG_STATE_HOME/depot):

  • state.json — per absolute file path → { bytesUploaded, linesUploaded, sha256OfLastUpload, lastRunAt }. On each run the uploader reads each transcript, takes everything past bytesUploaded, JSON.parses the new lines (malformed lines are skipped, the rest still upload), and batches them per file. The cursor for a file advances only after that file's upload returns 2xx, so an interrupted run just re-sends the same lines next time and the server dedups them by record uuid. A trailing partial line (a session still appending) is left un-cursored until it's complete.
  • machine.json — the random per-install UUID behind the machine fingerprint.
  • sync.log — rotating log from the auto-sync hook.
  • context/ — the push channel's cache: per-project hot-file lists (refreshed each SessionStart, 12 h TTL) and per-session injected-file sets (pruned after 7 days). Safe to delete; it only ever costs a refetch.

Deleting state.json makes the next run re-upload everything (still idempotent — the server dedups by record uuid).

Files

claude-plugin-depot/
├── .claude-plugin/
│   ├── plugin.json        # plugin manifest
│   └── marketplace.json   # single-plugin marketplace descriptor
├── bin/depot-upload.ts    # CLI entrypoint
├── bin/depot-context.ts   # push-channel hook entry (SessionStart/PreToolUse)
├── src/                   # config, identity, state, scan, upload, run, context
├── hooks/
│   ├── hooks.json         # SessionEnd → sync; SessionStart/PreToolUse → context
│   ├── depot-sync.sh      # background, silent, non-fatal sync
│   └── depot-context.sh   # foreground (returns context), silent, non-fatal
├── commands/depot-sync.md # /depot:depot-sync slash command
└── package.json

About

Depot — Claude Code plugin that syncs session transcripts to your team's Depot (institutional memory).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages