Skip to content

Security and data

The short version: the adapter runs on your machine and reads git there. The server is told what happened and never touches your repository. Docket is never sent the contents of a file.

This page is the long version. It lists every field.

The adapter, @usedocket/mcp, is the only part of Docket that runs on your machine. It sends something only when your agent calls one of its tools. Every call carries three things.

1. What your agent wrote. The tool’s arguments, exactly as the agent gave them: a card’s title, goal, constraints, scope and acceptance command, a note, a report. The tool reference lists every argument of every tool. If the agent passes workdir, the path of the folder it is working in, that path is sent too.

2. Seven facts about the repository, read from git in the directory the adapter was started in, or in workdir:

Field What it is
remote The address of the origin remote, reduced to host, owner and name: github.com/acme/billing-api. A user name or password in the address is removed before it is sent.
owner The owner part of that address.
repo The name part of that address.
head The id of the commit that is checked out.
branch The name of the branch that is checked out.
dirty Whether there are uncommitted changes: yes or no.
in_worktree Whether the directory is a git worktree: yes or no.

Nothing else about the directory can be sent. The adapter keeps a fixed list of these seven and drops everything that is not on it.

3. A label for the agent: the name of your client and four random characters, such as claude-code-3fa9. It is how the board says who holds a card.

Two tools add more.

When a card is claimed, the commit id and branch are recorded as where the work started.

When a card is finished, the adapter reads these from git and sends them, so that the report does not rest on the agent’s word alone:

Field What it is
tip_sha The id of the last commit of the work.
base_sha The id of the commit the work started from.
branch The branch the work is on.
dirty Whether there are uncommitted changes.
pushed Whether the branch is on the remote.
files_changed The names of the files that changed between those two commits. Names only.
card_trailers The card references found in Card-Id trailers on those commits.
pr_url, pr_base The address of the pull request and the branch it targets, if GitHub’s command-line tool is installed and there is one.
default_branch The name of the repository’s main branch.
workdir The folder’s path, when the agent gave one.

Before claim_next, get_card and list_cards, the adapter checks whether finished cards have been merged. For each one it finds on a branch, it sends the card’s reference, the id of the commit whose trailer names it, the branch’s name and the id of the branch’s last commit.

  • The contents of any file, or any diff. The adapter runs git diff --name-only: it asks git for names.
  • Commit messages. The adapter reads them on your machine, looking for Card-Id trailers. Only the card references it finds and the commit ids leave.
  • The output of the acceptance command. The adapter never runs it. Your agent runs it and says how it went, in its own words.
  • Your prompts, your agent’s replies, and your model provider’s key. The adapter is given tool calls and nothing else.
  • Environment variables, other than its own key, which it sends to prove who is calling.

Signing in asks GitHub for one scope, read:user: your public profile. Docket reads your GitHub user id, your login and your public email address if you have set one.

Docket never asks for access to a repository, public or private. It does not keep the token GitHub issues: the token is used once, to read the profile, and discarded.

Everything is in one database. In plain words, table by table:

Kept What is in it
Your account Your GitHub user id, login and public email, which plan the account is on, and when you joined.
API keys For each key: a hash of it, its first eight characters so you can tell keys apart, its label, when it was made, when it was last used (to within five minutes) and when it was deleted. Never the key.
Projects For each repository: a name and short key, the repository’s address, owner and name as above, a counter for numbering cards, and the project’s settings.
Cards Title, goal, constraints, scope (file patterns and symbol names), acceptance command, status, position, version and feature, with the times it was made, changed and deleted. Two further fields are reserved and empty.
Dependencies Which card waits on which, who added it (an agent, a person or Docket) and when.
Files The exact file paths each card has named or taken.
Features Name, short name and description.
Claims Which card, the agent’s label, the commit id and branch it started from, when its lease runs out, and how it ended: finished, released or expired.
The log One entry for everything that happens to a card: made, changed, linked, unlinked, started, files taken, note left, finished, released, merged, orphaned, deleted, lease expired. Each entry says who did it and when. A note’s entry holds the note. A finish’s entry holds the report and the git facts listed above.
Housekeeping A queue of the server’s own recurring jobs, such as expiring leases.

The log cannot be edited. The database refuses any change to an entry, and refuses to delete one, with a single exception: deleting your account deletes its log.

Not stored: your code, the key itself, a GitHub token, and any record of your sessions. A session is a signed cookie in your browser; there is nothing on the server to look up.

On app.usedocket.dev:

  • A session cookie, signed, lasting 14 days. It is sent only to that address.
  • A cookie holding your choice of light or dark.
  • A cookie that lasts ten minutes while you are signing in with GitHub.

This site, usedocket.dev, sets no cookies. It keeps your choice of light or dark in your browser’s local storage.

A key is dk_ followed by 32 random bytes. It is shown once, when it is made.

What is stored is a hash of the key combined with a secret that is held in the application’s configuration and not in the database. Someone who obtained a copy of the database alone could not use, or recover, a single key.

Deleting a key stops it working at once.

Every table that holds your data has row-level security switched on and forced, in the database itself. Each request runs in a transaction that names the account it is for, and the database returns and changes only that account’s rows. This does not depend on the application remembering to filter.

Requests are limited to 300 a minute for an account. A key that fails to authenticate is limited to ten attempts a minute.

A card. Deleting a card hides it. It stays in the database, with its log, until the account is deleted.

A key. It stops working at once. Its hash and label stay, marked deleted, until the account is deleted.

Your account. Account → Delete account shows a count of what will go and asks you to type your login. It then removes your account and everything under it from the database at once: projects, cards, dependencies, files, features, claims, the whole log and every key. Your keys stop working at that moment.

Backups. Copies of the database are taken, and a deleted account remains in the copies made before it was deleted. No limit has been set yet on how long those copies are kept.

  • The app and its database run on Railway, in the United States.
  • Sign-in is GitHub’s.
  • The adapter is downloaded from npm.
  • This site is served by Cloudflare, which also counts visits to it without cookies.

The server’s logs hold errors and, when an account is deleted, the counts of what was removed. Docket does not write card contents or tool calls to its logs as it runs; an error is logged with the message that caused it.

If Docket does something with your data that is not written here, that is a fault in this page.