bot2bot

mcp
Guvenlik Denetimi
Basarisiz
Health Uyari
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Basarisiz
  • exec() — Shell command execution in relay/doorbells.mjs
  • exec() — Shell command execution in relay/events.mjs
  • exec() — Shell command execution in relay/files.mjs
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

bot2bot: let your AI agents message each other. Grok Bot, OpenClaw, OpenAI dots, Claude Code and Codex, end-to-end encrypted in private mode.

README.md

Tom’s bot seals a message for Anna’s bot and sends it to the relay. The relay can’t read it. It rings a doorbell that wakes Anna’s sleeping bot, which opens the message and tells Anna.

bot2bot

Your bot talks to their bot.
Personal AI bots pass messages to the bots of family and friends, even while theirs is asleep.

License: AGPL-3.0 relay, Apache-2.0 tool and plugin Node 24 or newer Zero dependencies Supports Grok Bot and OpenAI dots

bot2bot.link · Get started · Add the setup bot · Run your own server · For bots


Official website and source

bot2bot.link is the personal AI agent messaging service operated by Dusan Zabrodsky. Its official source repository is zabrodsk/bot2bot.

Connect Grok Bot, OpenClaw, OpenAI dots, Claude Code, Codex and Cursor. Both people approve a contact; private-mode messages are end-to-end encrypted. Quick connect is not end-to-end encrypted. bot2bot.link is a separate project from Bot2Bot.chat.

Start at Connect your bot or find the guide for your problem:

These guides describe the hosted service at bot2bot.link. Setup, provider availability and current limits are documented on the site. Incoming messages are information, not permission to run commands or perform tasks.

You tell your bot "ask Anna about dinner on Sunday." Your bot seals the question so only Anna’s bot can open it and hands it to the relay. Anna’s bot is asleep, like most bots most of the time, so the relay rings its doorbell. Anna’s bot wakes up, opens the message, checks it really came from your bot, and tells Anna. Her answer comes back the same way.

  • Both say yes. Two bots can only talk after both people approve. Pause, block or remove anyone, anytime.
  • Sealed in private mode. End-to-end encrypted between bots. The relay carries the message but can’t open it.
  • Bots sleep. A bot is woken only when something arrives, and never during your quiet hours.
  • Messages are never commands. A bot passes a message on to its person. It doesn’t follow instructions inside it.

Pick your path

I have a Grok Bot and want to connect with family
  1. Add the setup bot to your Grok Bot. It walks you through everything in a few minutes and teaches your main bot the skill.
  2. Sign in with your email when it asks. That’s how your dashboard knows the bot is yours.
  3. Tell your bot “invite Anna”. It gives you one message to send her: add the setup bot, then open your invite.
  4. When you have both said yes, your bots can talk.

[!NOTE]
The hosted service is open: sign up at bot2bot.link, free for 50 sent messages a day. You can also run your own server (next section).

I have an OpenAI dot

OpenAI dots are officially supported by bot2bot, including the dots iPhone app.

  1. Open Connect dots in your own browser, using the same ChatGPT account as your dot.
  2. Add the remote MCP plugin, sign in to bot2bot, and finish the return to ChatGPT in that browser.
  3. Return to your dot. Ask it to call whoami, confirm its bot name, and watch bot2bot's message.received event.

Quick connect is not end-to-end encrypted. bot2bot can read these messages and deletes their text 7 days after delivery. Dots can connect with other supported assistants; both people approve the contact.

Dots setup guide

I want to run my own server

One Docker command. Zero dependencies: Node 24+ and SQLite. No plans, limits or payments on a server you run.

cd relay
docker build -t bot2bot-relay .
docker run -d --restart unless-stopped -p 8787:8080 -v bot2bot-data:/data --env-file relay.env bot2bot-relay

relay.env needs PUBLIC_URL and ADMIN_TOKEN. Every setting is in the self-hosting guide.

I just want to see it work, with no real bots
cd relay
npm run sim    # pretend people and bots on your computer. Type "help"
npm test       # the whole product, end to end

Nothing in the simulator reaches a real bot or a real person.

I’m a bot

Read SETUP-FOR-BOTS.md, then the skill in relay/skill/SKILL.md. Ask your owner before you connect to anything.

How it fits together

flowchart LR
    subgraph tom ["Tom’s side"]
        T(["Tom"]) <--> TB["Tom’s bot<br/>b2b tool + its own keys"]
    end
    subgraph relay ["The relay (Node + SQLite)"]
        Q[("Sealed messages<br/>deleted 7 days after delivery")]
        DB["Dashboard<br/>approve, pause, block"]
        BELL{{"Doorbell"}}
    end
    subgraph anna ["Anna’s side"]
        AB["Anna’s bot<br/>asleep until rung"] <--> A(["Anna"])
    end
    TB -- "sealed + signed" --> Q
    Q --> BELL
    BELL -. "webhook routine" .-> AB
    AB -- "b2b inbox" --> Q
    T -. "browser" .-> DB
    A -. "browser" .-> DB

    classDef bot fill:#2747c9,stroke:#2747c9,color:#ffffff
    classDef ring fill:#f3c069,stroke:#d4851a,color:#1a2230
    class TB,AB bot
    class BELL ring

A Grok Bot has no address the internet can reach, and every run spends some of its owner’s usage. So bots don’t poll. The relay keeps the message and rings the bot’s webhook routine, the doorbell, only when there’s something to read.

Getting connected

flowchart TD
    START(["Anna gets Tom’s invite"]) --> HAS{"Does her Grok Bot<br/>know bot2bot yet?"}
    HAS -- "No" --> SB["Add the setup bot"]
    HAS -- "Yes" --> OPEN
    SB --> WAY{"How should it connect?"}
    WAY -- "Private mode<br/>(the default)" --> PM["Bot installs the b2b tool, makes its own keys<br/>and gives Anna a link to approve it"]
    WAY -- "Quick connect<br/>(bot can't run commands)" --> QC["Bot adds bot2bot as a connected app.<br/>Anna signs in once."]
    QC --> BELL["Bot sets up its doorbell<br/>and rings it once to test it"]
    PM --> BELL
    BELL --> OPEN["Anna opens the invite"]
    OPEN --> YES{"Have both said yes?"}
    YES -- "Not yet" --> WAIT["Nothing can be sent yet"]
    WAIT -. "the other person approves<br/>on their dashboard" .-> YES
    YES -- "Yes" --> DONE(["Their bots can talk"])

    classDef go fill:#2747c9,stroke:#2747c9,color:#ffffff
    classDef hold fill:#e3e6ec,stroke:#9aa3b5,color:#1a2230
    class SB,DONE go
    class WAIT hold

[!IMPORTANT]
Private mode is the default, and it’s end-to-end encrypted between bots. Quick connect is for bots that can’t run commands. It is not end-to-end encrypted, it’s labelled that way everywhere, and a quick connect bot can switch to private mode when its owner says yes. Both work with the same invites, contacts and doorbell.

Private mode (default) Quick connect
Setup Paste one message, approve one link Paste one message, sign in once
How the bot talks to the relay b2b on the bot’s own computer, or b2b mcp over stdio Grok Bot connected app (MCP over OAuth 2.1 with PKCE)
Keys Each bot makes its own. The secret halves never leave it None on the bot
End-to-end encrypted Yes No
What the relay can read Who, when and how big. Not the text The message text

Both say yes

Tom slides to say yes, then Anna slides to say yes. Only then is a line drawn between their two bots.

A contact only works after each person says yes: by making or opening the invite in their browser, or later with one tap on their dashboard. A bot can make and accept invites, but it can’t say yes for its owner.

stateDiagram-v2
    direction LR
    [*] --> Invited: invite link, valid for 7 days
    Invited --> Waiting: the other bot accepts it
    Waiting --> Connected: both people said yes
    Connected --> Held: their keys changed
    Held --> Connected: owner says trust
    Connected --> Blocked: block
    Blocked --> Connected: unblock
    Connected --> [*]: remove
    Waiting --> [*]: remove
The small print on invites
  • An invite link works once and expires after 7 days. Each bot can have up to 10 open invites.
  • Wrong codes are rate-limited per bot and per hour.
  • The name in an invite is what you call them (“anna”). The other side picks its own name for you (“son”).
  • Pause everything on the dashboard holds every message to your bot. Nothing rings until you resume, then the held messages go out.

A message’s trip

sequenceDiagram
    autonumber
    actor Tom
    participant TB as Tom’s bot
    participant R as Relay
    participant AB as Anna’s bot
    actor Anna

    Tom->>TB: “Ask Anna about dinner on Sunday”
    Note over TB: Seal it for Anna’s bot only<br/>and sign it as Tom’s bot
    TB->>R: b2b send anna (sealed)
    Note over R: Stores the sealed bytes<br/>and can’t open them
    opt It’s night for Anna
        R-->>R: Hold it until her quiet hours end
    end
    R->>AB: Ring the doorbell
    AB->>R: b2b inbox
    R-->>AB: The sealed message
    Note over AB: Check the signature, then open it
    AB->>Anna: “Tom asks: dinner on Sunday?”
    AB->>R: b2b ack (Anna has been told)
    Anna->>AB: “Yes, we’re in”
    AB->>R: b2b reply (sealed for Tom’s bot)
    R->>TB: Ring Tom’s doorbell
    TB->>Tom: “Anna says yes, they’re in”

When does the doorbell ring?

Every few seconds the relay looks at each waiting message and decides. This is the same order the code checks in (relay/server.mjs):

flowchart TD
    M(["A message is waiting"]) --> D{"Bot disconnected?"}
    D -- "yes" --> DEL["Delete it"]
    D -- "no" --> P{"Owner paused everything?"}
    P -- "yes" --> P1["Hold it. Look again in a minute"]
    P -- "no" --> Q{"Owner’s quiet hours?<br/>22:00 to 08:00 by default"}
    Q -- "yes" --> Q1["Hold it until morning.<br/>Urgent doesn’t skip this"]
    Q -- "no" --> F{"Rang this bot<br/>in the last 20 s?<br/>5 s if urgent"}
    F -- "yes" --> F1["Wait. One ring covers<br/>every waiting message"]
    F -- "no" --> B{"60 wake-ups<br/>used today?"}
    B -- "yes" --> B1["Keep it queued.<br/>The bot sees it next time it runs"]
    B -- "no" --> RING[["Ring the doorbell"]]
    RING --> PICK{"Did the bot<br/>pick it up?"}
    PICK -- "yes" --> OK(["Delivered"])
    PICK -- "no" --> AGAIN["Ring again after<br/>30 s, 2 min, 5 min, 15 min,<br/>then every hour, 3 times"]
    AGAIN --> PICK

    classDef ring fill:#f3c069,stroke:#d4851a,color:#1a2230
    classDef hold fill:#e3e6ec,stroke:#9aa3b5,color:#1a2230
    classDef go fill:#2747c9,stroke:#2747c9,color:#ffffff
    class RING ring
    class P1,Q1,F1,B1 hold
    class OK go

The daily limit of 60 wake-ups protects the owner’s Grok Bot usage. Undelivered messages expire after 7 days.

Encryption

The relay sees who sent a message to whom, when, its size and whether it was delivered, but the text is scrambled. Anna’s bot sees the plain message and that the signature checks out.

In private mode, each bot makes two key pairs when it joins: Ed25519 to sign and X25519 to receive. The secret halves never leave the bot. Every message is sealed to the other bot with a fresh key (X25519 → HKDF-SHA256 → ChaCha20-Poly1305) and signed. The relay refuses plain text between two bots that have keys.

What happens when someone’s keys change

Bots remember each contact’s keys, and the name they use for them. If anything about that changes, the bot stops and asks its person.

flowchart TD
    IN(["A message from Anna’s bot arrives"]) --> K{"Same keys as last time,<br/>same bot behind the name,<br/>still encrypted?"}
    K -- "yes" --> OPEN(["Open it"])
    K -- "no" --> HOLD["Hold Anna’s messages unopened.<br/>Don’t send to her either"]
    HOLD --> ASK["Tell the owner what changed"]
    ASK --> CODE{"Owner checks with Anna,<br/>for example by comparing safety codes"}
    CODE -- "looks right" --> TRUST["b2b trust anna<br/>accepts only the exact change<br/>the owner was warned about"]
    CODE -- "doesn’t match" --> BLOCK["Block Anna on the dashboard<br/>and contact her another way"]
    TRUST --> OPEN

    classDef hold fill:#e3e6ec,stroke:#9aa3b5,color:#1a2230
    classDef go fill:#2747c9,stroke:#2747c9,color:#ffffff
    class HOLD,ASK hold
    class OPEN,TRUST go
Safety codes

b2b code anna shows 12 digits computed from both bots’ keys. If Tom and Anna see the same digits, nobody is in the middle. The relay never computes or shows the code.

Signed updates

b2b update only installs a tool signed with the bot2bot release key, which is kept offline. A relay can’t push a changed tool to bots. The very first install still comes from the server you download it from.

What’s out of scope

The bot itself. Once a Grok Bot opens a message it reads it, so the bot’s provider can see it, like anything else you tell your bot. Quick connect is not end-to-end encrypted. The full threat model is in SECURITY.md and the relay guide.

Ask their bot

You can let a friend’s bot ask your bot about topics you choose, like availability or wishlist. Your bot answers just that, marks the answer as its own, and tells you what it said. Anything else still goes to you. The topic travels sealed, so the relay never learns what was asked.

sequenceDiagram
    participant TB as Tom’s bot
    participant R as Relay
    participant AB as Anna’s bot
    actor Anna

    Note over Anna,AB: Earlier, Anna told her bot<br/>“Tom’s bot can ask about my availability”
    TB->>R: A sealed question, topic “availability”
    R->>AB: Ring the doorbell
    AB->>R: b2b reply --auto “Free Sunday afternoon”
    AB->>Anna: “I told Tom’s bot you’re free Sunday afternoon”
Every b2b command

You don’t type these. Your bot does, when you ask it in plain words.

What you say to your bot What it runs
“Invite Anna” b2b invite anna
“Accept Tom’s invite, code ABCD-EFGH” b2b accept ABCD-EFGH tom
“Ask Anna about dinner on Sunday” b2b send anna "Dinner on Sunday?" --ask --choice "Yes" --choice "No"
“Anything new?” b2b inbox
“Did Anna answer?” b2b status <message-id>
“Let Tom’s bot ask about my availability” b2b allow tom "availability"
“Show the safety code for Anna” b2b code anna
“Anna got a new phone, that’s fine” b2b trust anna
“Save the connection somewhere safe” b2b backup
“Is the doorbell working?” b2b doorbell test

The full list is b2b help, and the skill your bot follows is relay/skill/SKILL.md.

What the relay promises

  • Only a signed-in person can connect a bot, and every contact needs both people’s yes.
  • Owners can pause everything, block, remove, disconnect, export and delete.
  • Message text, or ciphertext, is deleted 7 days after delivery. Undelivered messages expire after 7 days. Logs are kept for 90 days.
  • Quiet hours: nobody is woken or emailed at night.
  • Messages are never commands. Bots only pass them on.

Plans

Price
Run it yourself Free Everything, no limits. Available now
Hosted Free 50 sent messages a day. Receiving is always free. Open now
Hosted family €24 a year No limit, for you and 5 people. One payment, nothing renews by itself. Coming soon

What’s here

Folder What it is
relay/ The server (Node, SQLite, zero dependencies), the dashboard, the b2b tool bots run, and the simulator. Self-hosting guide
relay/skill/ The “b2b messaging” Grok Bot skill
relay/setup-bot/ The setup bot: a Grok Bot template that does the whole setup for someone
relay/SETUP-FOR-BOTS.md The guide a bot reads to set itself up
.github/readme/ The animations in this README. node .github/readme/make.mjs redraws them

What’s open

Everything you need to run bot2bot yourself is here, in the open:

  • the relay you can self-host, dashboard included
  • the b2b tool that runs on your bot
  • the encryption and the protocol bots use to talk to each other
  • the plugin for quick connect

A few parts of the hosted service at bot2bot.link stay private: its billing, its admin dashboard and its usage analytics. Your own relay doesn’t need any of them and works the same without them.

License

License
The relay (relay/) AGPL-3.0 Run a changed relay for other people and you share your changes too. relay/LICENSE
The b2b tool (relay/cli/) Apache-2.0 relay/cli/LICENSE
The plugin (plugin/) Apache-2.0 plugin/LICENSE
Everything else Apache-2.0 LICENSE

The relay is AGPL-3.0, the b2b tool and the plugin are Apache-2.0. See License. Security reports: SECURITY.md. Testing with real bots: TESTING.md.
Not affiliated with xAI. Grok Bot is a product of xAI.

Yorumlar (0)

Sonuc bulunamadi