Ermöglicht KI-Agenten eine sichere Kommunikation über stabile Adressen und dauerhafte Mailboxes mittels verschlüsselter, signierter und versiegelter Message-Envelopes.
Auch bekannt als usebag/bag, @usebag/bag
- Stars
- 7
- Tools
- —
- Downloads, 30 Tage
- —
- Neueste Version
- —
- Letzter Commit
- 14. Nov. 2026
- Lizenz
- Apache-2.0
Was ist bag MCP?
bag ist ein MCP server. Ermöglicht KI-Agenten eine sichere Kommunikation über stabile Adressen und dauerhafte Mailboxes mittels verschlüsselter, signierter und versiegelter Message-Envelopes.
Zusammenfassung generiert aus dem README des Projekts
Über bag MCP server
Entwickler können eine sichere, asynchrone Kommunikation zwischen KI-Agenten mit bag aufbauen, einem Protokoll, das stabile Adressen und dauerhafte Mailboxes bereitstellt. Durch die Nutzung von Ed25519-Keypairs als Identitäten können Agenten verschlüsselte, signierte und versiegelte Message-Envelopes über austauschbare Store-and-Forward-Relays austauschen. Dieses Setup stellt sicher, dass Relays lediglich als passiver Speicher fungieren und nicht auf den Inhalt der Nachrichten zugreifen können, die durch HPKE-Verschlüsselung geschützt sind.
Nutzer können mit dem System über einen Coding-Agenten oder via CLI mit Tools wie send, inbox und audit verify interagieren. Das System ist auf Resilienz ausgelegt: Empfänger können mehrere Relays hinterlegen, um die Konnektivität aufrechtzuerhalten, falls ein Relay offline geht. Nachrichten werden von den Relays bis zu 7 Tage lang gespeichert, sodass offline befindliche Agenten ihre Mails nach der Wiederverbindung abrufen können. Das Protokoll enthält ein Hash-Chained Audit Log, um die Integrität jedes Schritts während eines Austauschs zu verifizieren.
Was du damit machen kannst
- 1Sicheres Agent-to-Agent MessagingEin KI-Agent kann eine versiegelte, verschlüsselte Nachricht an die stabile Adresse eines anderen Agenten senden, ohne dass das Relay den Inhalt sieht.
- 2Verifizierung der KommunikationsintegritätEin Entwickler kann das Audit-Tool nutzen, um sicherzustellen, dass kein Teil der Nachrichtenverlaufshistorie verändert oder umgeordnet wurde.
- 3Asynchroner NachrichtienabrufEin Agent kann mit dem inbox-Befehl sein Postfach auf Nachrichten prüfen, die gesendet wurden, während er offline war.
Geschrieben aus dem README des Projekts. Jeder Use Case wurde gegen ein Zitat daraus geprüft.
So installierst du bag MCP
Formate geprüft am 10. Nov. 2026Zu Cursor hinzufügenZu Goose hinzufügenbag MCP in Claude Code installieren
$ claude mcp add bag -- npx -y @usebag/bagbag MCP in Cursor installieren
~/.cursor/mcp.json
{
"mcpServers": {
"bag": {
"command": "npx",
"args": [
"-y",
"@usebag/bag"
]
}
}
}bag MCP in VS Code installieren
.vscode/mcp.json
{
"servers": {
"bag": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@usebag/bag"
]
}
}
}bag MCP in VS Code CLI installieren
$ code --add-mcp '{"name":"bag","type":"stdio","command":"npx","args":["-y","@usebag/bag"]}'bag MCP in Claude Desktop installieren
claude_desktop_config.json
{
"mcpServers": {
"bag": {
"command": "npx",
"args": [
"-y",
"@usebag/bag"
]
}
}
}bag MCP in Codex installieren
$ codex mcp add bag -- npx -y @usebag/bagbag MCP in Codex config.toml installieren
~/.codex/config.toml
[mcp_servers.bag] command = "npx" args = ["-y", "@usebag/bag"]
bag MCP in Gemini CLI installieren
$ gemini mcp add -s user bag npx -- -y @usebag/bagbag MCP in Gemini settings.json installieren
~/.gemini/settings.json
{
"mcpServers": {
"bag": {
"command": "npx",
"args": [
"-y",
"@usebag/bag"
]
}
}
}Konfiguration
AC_HOME
| Name | Beschreibung | Typ |
|---|---|---|
| AC_HOME | — |
Automatisierte Checks
Geluften am 14. Nov. 2026Vollständiger Bericht →Unsere automatisierten Checks bestanden. Das ist kein Security-Audit: Lies den Code und gib dem Server nur den minimal notwendigen Zugriff. Wie die Checks funktionieren
- Source Repository verknüpft und erreichbarusebag/bag is public and reachablegithub.com/usebag/bag ↗Bestanden
- Paket nennt dieses Repository als Quelle@usebag/bag names usebag/bag as sourcenpmjs.com/package/@usebag/bag ↗Bestanden
- Build-Provenienz (Sigstore-Attestierung)Sigstore attestation for @usebag/bagnpmjs.com/package/@usebag/bag/v/0.4.1#provenance ↗Bestanden
- Open Source Lizenz (OSI)Apache-2.0spdx.org/licenses/Apache-2.0.html ↗Bestanden
- Commit oder Release im letzten JahrLast commit or release 2026-11-12github.com/usebag/bag ↗Bestanden
- OpenSSF ScorecardNicht geprüft
- Package-Name ähnelt keinem populären PackageNo popular package one edit away from @usebag/bagBestanden
- Keine kritischen Advisories im Paket oder seinen AbhängigkeitenNicht geprüft
- Keine versteckten Anweisungen an das Modell0 tool descriptions and the README read; no override phrases, credential paths or hidden charactersBestanden
- Destruktive Tools sind markiertNicht geprüft
- Remote-Endpoint beantwortet den MCP-HandshakeNicht geprüft
README
Auf GitHub ansehenbag
A small protocol that gives an agent a stable address and a durable mailbox. Install it with your coding agent; use it from the agent, or from the command line.
Quick start · Usage · How it works · Specification · Install guide · Security
From an agent, you say what you want in plain words, and the agent calls the bag server's tools:
The same exchange by hand, with the command line: alice sends bob one sealed envelope through a relay, bob reads it,
and his audit log is verified from its first line. Here c runs the command line and R holds the relay's URL. The
Quick start runs the same steps from a clean machine, and the output lines are the ones
docs/partner-install.md documents.
$ c send --as alice --to "$(c address bob)" --relay "$R" --body '{"text":"hi"}'
<envelope id>
published <relay> tries=1
$ c inbox --as bob --relay "$R" --once --trust-root "$(c address alice)"
accept <id> <from> <root> chat.v1 {"text":"hi"}
$ c audit verify "$AC_HOME/state/bob/audit.jsonl"
ok <n> lines
Contents: What bag is · Why · Status · Limits · Quick start (with your agent, by hand) · Usage (from an agent, from the command line) · How it works · What is in this repository · Documentation · The checks · Security · Contributing · Licence
What bag is
An identity is an Ed25519 key pair whose address is its public key, and its mailbox is kept by the relays its signed address record lists: you never reach a machine, you reach its mailbox. A message is a signed and sealed, threaded envelope, and relays are dumb, interchangeable store-and-forward servers that enforce only the policy a mailbox's owner signed. An authority chain that anyone can verify offline says who may speak for whom.
Why
- A relay never sees the content. The sender seals the type, thread and body to each recipient with HPKE (RFC 9180: X25519, HKDF-SHA256, AES-256-GCM). A relay sees who writes to whom and when, not what they say.
- A relay cannot forge or change mail. Every envelope and record is signed with Ed25519, and an address is a public key. The recipient checks each signature and the authority chain itself.
- The mailbox's owner decides who may write. A signed accept-from record names the roots the mailbox takes mail from. A relay refuses mail under any other root.
- More than one relay. A recipient lists its relays in its signed address record. The sender publishes the same bytes to up to three of them, and the recipient reads every one and drops duplicates by envelope id. An identity that lists two relays keeps working while one is down.
- Mail waits for an offline recipient. A relay keeps each envelope for up to 7 days. The sender keeps the exact
bytes in its outbox, and a running edge retries each relay until 7 days after the envelope's
ts. - Each step is audited. The edge writes every step it takes to a hash-chained log, accepted or refused, each line
with its decision and reason.
audit verifyrecomputes the chain and names the first line that was edited, removed or reordered. - The spec is the contract. Its test vectors bind three implementations: the TypeScript reference, the Rust crate and relay, and a Python participant written from the spec alone.
Status
[!WARNING] Security preview, review in progress: no outside cryptographic review has signed, the audit package is public, and nothing here says "reviewed" until a reviewer signs.
This is a security preview of version 0 of the wire format. Nothing here is supported or stable yet. Treat it as
something to read, test and attack, not to depend on. What changed in each published cut is in
CHANGELOG.md.
Limits
- Two public relays, each one Machine. The project runs two public relays, each a single Fly.io Machine in one region
(Paris and Amsterdam) with its store in one SQLite file on one volume. Neither copies the other. An identity that
lists both keeps working while one is down: a sender publishes each message to up to three of the relays its
recipient lists, and a recipient reads every relay it lists (
spec/SPEC.md§4.3). When no listed relay takes a message, the sender's outbox keeps the sealed envelope and a running edge retries it until 7 days after the envelope'sts, then marks it failed and keeps the bytes forresend(packages/edge/README.md). - Limits count per client address, not per actor. A relay counts its limits per client address: an IPv4 address,
or on IPv6 a /56 for the rates and quotas and a /64 for the connection cap. The public relays keep the reference
relay's defaults: 79 open WebSocket connections per address; 600 publishes a minute per address, 120 per signing key
and 1,200 per root; 6,000 fetches a minute per address, counted before any signature is checked; 100 MB of stored
envelopes a UTC day per address; 100 new record signers a day per address; and 10,000 envelopes a day per sender
domain. Past a rate or a quota the relay answers 429
rate-limitedwithRetry-After. A client that holds many addresses, such as an IPv6 block larger than a /56, gets a set of limits for each. Beyond them, a relay's shared bounds are the connection limit of the proxy in front of it, a ceiling of 30,000 fetches a minute for all clients together, and its store cap. - The proxy limit is the first ceiling. The proxy in front of each public relay takes at most 3,000 connections at once, for all clients together. Every online agent holds one for its subscription, and each call takes one while it lasts. At that limit no new connection reaches the relay, for anyone.
- Measured capacity. On one such Machine (shared CPU, 512 MB), with the proxy limit and the per-address limits raised for the run and all load from one client machine, the relay held 100 publishes a second in 30-second steps with 1,000 live subscriptions, and took 20 a second for 9 minutes. At 100 a second the publish p99 was 213 ms and the fetch p99 266 ms, measured over the internet. It held 3,966 subscriptions without refusing one; that is a lower bound set by the client's network path. Sustained rates above 20 a second, load from many addresses, and the Machine's CPU and memory under load are not measured (the project's load measurement of 2026-11-01).
- A full store refuses everyone's new mail. The store cap is one number for the whole relay. When the store
reaches it, the relay refuses every new envelope, from any sender, and every record from a signer it does not yet
hold, with 503
store-full, until stored mail expires or the operator raises the cap. A signer it already holds may still update its records, so rotation and revocation go on. The daily byte quota holds what one address can add to 100 MB a day; many addresses together can still fill the store. A second relay adds uptime, not room: a message goes to each relay its recipient lists, so the relays fill together. - One writer per relay. A relay keeps one SQLite connection behind one lock. Every publish, fetch, subscription read, acknowledgement and expiry sweep takes its turn on it, so a relay's throughput is that of one writer, and a flood of any one call slows the others.
- Mail is kept up to 7 days, read or not. A relay keeps each envelope until it expires: 7 days after it arrives by
default, the public relays' setting, or sooner when the recipient's accept-from record sets a shorter
ttl. An acknowledgement moves the recipient's cursor; it does not delete the envelope. Until it expires, the relay holds the sealed bytes and their outer parts (SECURITY.md, "Threat model in one paragraph"). - Domain roots make a relay fetch from hosts others name. An accept-from record may name a
domain:root, and the relay then fetches that domain's record. So anyone can make a relay send HTTPS GET requests to a public host they name. The relay bounds them: HTTPS only, no redirect, at most 8 domains for one publish, at most one fetch of a domain a minute, at most 256 KiB within the time limit (10 seconds by default), and never to an address that is not public. - A backup is only as safe as its relay. Where the project backs up a relay (Litestream, streaming its database to an object-storage bucket), the relay process holds the bucket's key and the bucket keeps no older versions, so a relay that is taken over can delete its own backup. A restore loses the mail the relay acknowledged after its last upload, unless another relay the recipient lists took it.
- Windows is untested. No check or install step here has been run on Windows.
- Claude Code and omp have hosted the MCP server. omp 18.17.0 was checked with
host install omp(docs/host-omp.md); the Codex and opencode entries inpackages/mcp/README.mdare not checked. A host that does not declare MCP elicitation cannot pair: the pairing tools refuse it asno-elicitation. - The spec still changes. A change can alter a verdict or add a rule an edge must follow, as two decisions on relay restores did on 2026-10-31; an edge installed before such a change has to be updated to follow it.
Quick start
With your agent (recommended)
Paste this prompt into your coding agent:
Fetch and follow the instructions to set me up on bag.dev from https://bag.dev/install
Your agent fetches the guide at bag.dev/install, which is written for a coding agent, and
follows it step by step: it runs bag, the npm package @usebag/bag at the version the guide names, with npx,
checks that the package is the published commit, makes your identity, publishes its records at the two public relays,
and registers the bag MCP server in a working folder. After you restart Claude Code
in that folder, you ask it to pair with your peer: the pairing dialogs and the six check digits are yours to answer,
never the agent's. Once you are paired, you ask it to send a hello, and it sends and reads through the server's tools.
The guide is written for Claude Code, the one host that has run the MCP server so far (see Limits); the
prompt itself is also served at bag.dev/prompt.
By hand with the command line
This is the manual path, and the reference for what the agent does. From a clean machine to audit verify: one relay,
two identities and one sealed message, all on your own machine.
1. Get bag. You need Node 24 or later. bag is the npm package @usebag/bag, one bundle with no dependency and no
install script; npx runs it without installing anything globally. Name the version and the program every time:
c() { npx --yes --package=@usebag/bag@0.4.0 bag "$@"; }
c --version # prints: bag 0.4.0 <the commit it was built from>
The package is published from a commit of this repository by a workflow with npm provenance, and
npm view @usebag/bag@0.4.0 gitHead names that commit. To run from source instead, see From source.
2. Get a relay. The relay is Rust and is not in the package: build it from source (cargo build --release --locked -p ac-relay, as From source says) or run its container image (docs/self-host.md, "Run it with
Docker"). The next step runs the binary from a build.
3. Start a relay. In terminal 1, a relay on port 8787 with its own database file (it prints
AC_RELAY_URL=http://127.0.0.1:8787):
target/release/ac-relay --port 8787 --db "${TMPDIR:-/tmp}/ac-cut-relay.sqlite"
4. Make two identities. In terminal 2, two local identities, alice and bob, with their keys in a throwaway home:
R=http://127.0.0.1:8787
export AC_HOME="${TMPDIR:-/tmp}/ac-cut-home"
c health "$R" # prints: ok
c keygen alice && c keygen bob # each prints the address only, never a key
5. Publish bob's records. Bob publishes his address record (with his sealing key) and an accept-from record that
lets alice's root write to him. Each publish prints ok <kind> <signer>.
c record address bob --relay "$R" --sealing-key --out "$AC_HOME/bob.json" && c publish "$R" "$AC_HOME/bob.json"
c record accept-from bob --root "$(c address alice)" --max-bytes 65536 --ttl 604800 --out "$AC_HOME/bob.accept.json" \
&& c publish "$R" "$AC_HOME/bob.accept.json"
6. Send, read and verify. Alice sends one sealed envelope (it prints the envelope id, then
published <relay> tries=1), bob reads it from his inbox (accept <id> <from> <root> <type> <body>), and bob's
audit log is verified from its first line:
c send --as alice --to "$(c address bob)" --relay "$R" --type chat.v1 --body '{"text":"hi"}'
c inbox --as bob --relay "$R" --once --trust-root "$(c address alice)"
c audit verify "$AC_HOME/state/bob/audit.jsonl" # prints: ok <n> lines
Stop the relay with Ctrl-C. The throwaway files are ${TMPDIR:-/tmp}/ac-cut-home and ${TMPDIR:-/tmp}/ac-cut-relay.sqlite.
For the longer walk, from the same clean machine to a first exchange with another installation, a relay of your own
and your records at your own origin, read docs/partner-install.md.
From source
Every byte the package runs can be built and checked here. Clone the repository and check out the commit the
package names (c --version prints it): git clone https://github.com/usebag/bag.git bag, cd bag, git checkout --detach <commit>.
If you received this copy as one file, a git bundle, clone the file instead: git clone <file>.bundle bag, cd bag,
then check it with git bundle verify ../<file>.bundle, which must print ../<file>.bundle is okay.
You need Node 24 or later, rustup (the toolchain version is pinned in rust-toolchain.toml, and rustup installs it
on the first cargo call), and bash. Run everything from the root of this directory:
npm ci
cargo build --release --locked -p ac-relay
c() { node packages/cli/src/main.ts "$@"; }
c help # prints every command
From source, the command line is node packages/cli/src/main.ts, the MCP server node packages/mcp/src/main.ts and
the A2A bridge node packages/a2a/src/main.ts. npm run build -w packages/bag builds the package's bundle from the
checkout into packages/bag/dist/; node packages/bag/dist/bag.js --version then prints the version and this
checkout's commit, and npm pack -w packages/bag makes the package file.
Usage
The command line and the MCP server are two ways to be one identity. Run one receiver per identity: of an MCP server
and inbox --watch on the same identity, whichever starts second is refused as busy.
From an agent
This is the recommended way to use bag. Your agent uses it through the bag MCP server: you say what you want in plain words, and the agent calls the server's tools. The setup prompt in the Quick start installs the server and registers it for you.
packages/mcp is one MCP server over stdio. It gives an agent in an MCP host an address and a mailbox, as ten tools:
send, receipts, inbox, wait, ask, handoff, status, lookup, pair_invite and pair_accept, and an
eleventh, delegate, only when started with --allow-delegate. One server holds up to 64 identities. host install
writes the registration, and nothing it writes holds a key. Run from the package, it first copies bag to the
package folder of the bag home and writes that path, so the registration does not depend on npm's cache:
c host install claude-code --as alice --relay "$R" --project /path/to/your/project
It writes the server into the project's .mcp.json, and a SessionStart and a Stop hook into its
.claude/settings.json, which let a waiting session see new mail. packages/mcp/README.md,
"Install", gives the same by hand and for other hosts.
| say to your agent | the tool it calls |
|---|---|
| "Pair with my peer, and call them ben." | pair_invite or pair_accept, with dialogs only you answer |
| "Send ben a hello." | send, to the petname you gave |
| "Ask ben what 6 x 7 is, and wait for the answer." | ask, which waits up to 300 seconds a call for the answer |
| "Wait for a message." | wait, up to 300 seconds a call, then again with its resume token |
| "What is in my bag inbox?" | inbox: the accepted messages, oldest first |
| "Show the bag status." | status: the address, relays, trust roots, counts and subscriptions |
Claude Code plugin
The plugin is not in this release. The MCP server it wraps is: packages/mcp gives an agent in Claude Code, or in any
MCP host that runs a server over stdio, an address and a mailbox. c host install claude-code --as <name> --relay <relay URL> --project <project dir> writes the registration for a project;
docs/partner-install.md, section 5c, walks through it, and packages/mcp/README.md, "Install", gives the same by hand
(claude mcp add) and for other hosts.
From the command line
The package's command line is the bin bag; the guides wrap it in a shell function, c:
c() { npx --yes --package=@usebag/bag@0.4.0 bag "$@"; }
c help # prints every command
From source it is node packages/cli/src/main.ts (From source).
| to | commands |
|---|---|
| make and list identities | keygen, address, keys list, keys rotate |
| sign and publish records, and keep them alive | record address, record accept-from, publish, record keep |
| send and receive | send, resend, inbox --once, inbox --watch |
| pair with another person's identity | peer invite, peer accept, unpair |
| name peers and find their records | name add, lookup |
| put an agent on your organisation's domain | onboard, delegate |
| connect an agent host | host install claude-code, host install codex, host install omp |
| check | health, status, audit verify |
Errors exit 1 with bag: <code>: <detail> on stderr. packages/cli/README.md documents
the commands and their flags, and Appendix A of spec/SPEC.md lists every code.
Public relays
Two public relays run: https://relay1.bag.dev, in Paris, and https://relay2.bag.dev, in Amsterdam. Either can
stand in for a relay of your own as --relay, and c health https://relay1.bag.dev checks one. Each is a single
machine with the limits listed under Limits.
Pairing with another installation
Two people on two machines pair their identities with a one-use code and six check digits, through a rendezvous relay.
From an agent, ask it to pair with your peer and say what to call them. It calls pair_invite or pair_accept, and
the host opens dialogs that only you answer, for the peer's address, the pairing code and the six check digits; the
agent never sees the digits. A host that cannot show those dialogs cannot pair (see Limits).
From the command line, one side runs peer invite, which prints a pairing code. The other side runs peer accept
with that code and reads the six digits it shows to the inviter, by another way than the code. The inviter types them.
Then each side trusts the other, and either can send to the other by the petname it gave. Here R is a relay both
machines can reach:
c peer invite --as me --relay "$R" --name ben # prints: pairing code <code>
c peer accept --as me --relay "$R" --name ana '<pairing code>' # on the other machine
c send --as me --to ben --relay "$R" --type chat.v1 --body '{"text":"hello"}'
When you already know the peer's address, add --for <address> to bind the invitation to it.
docs/partner-install.md, section 5b, walks through the whole exchange.
The A2A binding
packages/a2a lets an unmodified A2A 1.0 client complete a task with a bag agent through the caller's own local
bridge, and every relay between them carries ciphertext only. packages/a2a/README.md
describes the bridge and the message type.
A participant in Python
examples/python-join is a participant written in Python from the spec alone, sharing no code with the reference.
Its check script sends and receives through the reference relay, to and from the reference CLI
(examples/python-join/README.md).
bag MCP Fragen
Wie füge ich bag MCP zu Claude Code hinzu?
Führe claude mcp add bag -- npx -y @usebag/bag in deinem Terminal aus. Füge --scope user hinzu, damit der Server in jedem Projekt verfügbar ist.
Wie füge ich bag MCP zu Cursor hinzu?
Öffne ~/.cursor/mcp.json und füge den Server unter mcpServers hinzu, mit der Cursor-Config aus dem Installationsabschnitt oben.
Ist das Protokoll aktuell stabil für den Produktiveinsatz?
Nein, es befindet sich derzeit in einer Security Preview Phase (Version 0) und sollte eher als etwas betrachtet werden, das getestet und angegriffen werden kann, anstatt sich darauf zu verlassen.