Let a remote AI agent work on your machines, safely. safe-grokbot-bridge is a small daemon
that gives an agent such as a Grok Bot a narrow, authenticated HTTP API to your
computers. Through it the agent can read your project folders and git history, see the Claude
Code, Codex and Hermes sessions running there, talk to them, and start new ones.
You keep using your agents as before. The remote agent becomes a coordinator that can hand work to them and follow up while you are away from the keyboard, for example from your phone.
Warning
This is remote access to your machine. Depending on your configuration, the remote agent can read files and git history in the folders you expose, and through the coding agents it starts or messages it can make the machine run programs and commands and change files: with the agents' permission prompts, or without them where you allow that. Use the bridge deliberately, only where this is acceptable, and grant as little as the work needs. Run it, together with the agents it drives, in an isolated environment such as a virtual machine, a dedicated WSL 2 distribution or a separate computer, not on your primary workstation with your personal data and credentials. See Where to run it.
flowchart LR
subgraph cloud["Grok Bot's cloud computer"]
bot["skill + curl<br/>secrets: URL, token"]
end
subgraph cf["Cloudflare"]
edge["HTTPS edge<br/>optional Access"]
end
subgraph machine["Your machine"]
cfd["cloudflared"]
bridge["safe-grokbot-bridge<br/>127.0.0.1:4765<br/>token, lockout, rate limit<br/>workspace capabilities"]
tmux["tmux: Claude Code, Codex,<br/>Hermes you can attach to"]
headless["headless runs:<br/>claude -p, codex exec"]
external["sessions outside tmux<br/>(experimental)"]
files[("allowed folders:<br/>files and git, read-only")]
end
bot -- "HTTPS + bearer token" --> edge
edge -- "tunnel, opened from the machine" --> cfd
cfd --> bridge
bridge --> tmux
bridge --> headless
bridge --> external
bridge --> files
- The bridge listens on
127.0.0.1only.cloudflaredopens an outbound tunnel, so no port is opened on the machine. (A public address with TLS and key pinning works too.) - The bot calls the API with
curland a bearer token kept in a Grok secret. Every request is authenticated, rate limited and checked against the folders you allowed. - The bridge lists, starts and drives agent sessions there, and serves files and git history read-only. The bot long-polls a session until the agent has answered.
- Agent sessions. List, start, message and stop Claude Code, Codex CLI and Hermes Agent
sessions, or any other terminal program in tmux.
- tmux: the agent runs in a live terminal you can attach to at any time
(
tmux attach -t β¦). - Headless: every message is one non-interactive run, continued by the agent's session id.
- Start options: model, reasoning effort, permission bypass (only where you allow it),
resume of an earlier conversation, and
keep_alive: falseto close a session once it has answered. - Reliable state: state comes from Claude Code's own status, per-session turn-complete hooks and terminal activity, so the client knows when an agent is working, waiting for an answer or done. It long-polls instead of guessing.
- tmux: the agent runs in a live terminal you can attach to at any time
(
- Read-only project access. Directory listings (respecting
.gitignore), text files by line range,git status,log,diffandshow. The file endpoints never serve secrets such as.envfiles and private keys. Git output is not filtered, so anything committed to a repository you expose is visible. - Security first. - 256-bit bearer tokens (only their hashes are stored), with per-IP lockout after failed attempts and per-token rate limits.
- Per-folder capabilities (
files,git,sessions,input,start). - TLS required on any public address. A self-signed certificate with public-key pinning works out of the box, no CA needed.
- Every request is written to an audit log, and no generic shell endpoint exists.
- Per-folder capabilities (
- Made for LLM clients. A completeOpenAPI 3.1 description. Every response says when it is incomplete and what to do next, and aready-made skill teaches Grok Bot to use it and to connect new machines.
- One binary for Linux, macOS and Windows. Configuration is one TOML file.
Recommended: two skills do it. Follow the quick setup:
- Install the skills : one into Grok Bot, one into Claude Code, Codex or Hermes on the machine.
- Tell Grok Bot "Use the safe-grokbot-bridge-client skill to connect a new machine named pc1." It creates the Cloudflare Tunnel and gives you a setup message. Paste that into your coding agent on the machine: it asks which folders to expose and what the bot may do there, then installs and configures everything. You only move two secrets by hand.
Step by step with prompts: Setup with Grok Bot and Cloudflare.
By hand:
cargo install --locked --git https://github.com/janreges/safe-grokbot-bridge
safe-grokbot-bridge init --workspace ~/projects
safe-grokbot-bridge check
safe-grokbot-bridge serve
Then connect Grok Bot, or call the API from anything that speaks HTTP.
Tip: start your agents with safe-grokbot-bridge launch claude (or codex) instead of claude.
They then run in tmux with the bridge's turn hooks, so the remote agent can follow and continue
your sessions.
The repository holds two skills, and is a plugin marketplace for Claude Code and Codex.
safe-grokbot-bridge, for the coding agent on the machine: it installs the bridge, agrees with you on the folders it exposes and what the bot may do there, writes and later changes the config, runs it as a service, connects the Cloudflare Tunnel, upgrades and troubleshoots it. It shows you every plan before it applies it, asks before it widens access, and never handles your secrets.safe-grokbot-bridge-client, for Grok Bot or another client: it uses the API, finds your machines by their secrets, and connects new machines.Connecting Grok Bot shows how to install it.
| Agent on the machine | Install safe-grokbot-bridge |
|---|---|
| Claude Code | claude plugin install safe-grokbot-bridge --marketplace janreges/safe-grokbot-bridge (2.1.292 or newer; before that,claude plugin marketplace add janreges/safe-grokbot-bridge andclaude plugin install safe-grokbot-bridge@safe-grokbot-bridge ) |
| Codex | codex plugin marketplace add janreges/safe-grokbot-bridge , thencodex plugin add safe-grokbot-bridge@safe-grokbot-bridge |
| Hermes Agent | hermes skills install janreges/safe-grokbot-bridge/skills/safe-grokbot-bridge --force (Hermes blocks community skills that set up services; read it first withhermes skills inspect ) |
| Cursor, Gemini CLI, GitHub Copilot, OpenCode and others | npx skills add janreges/safe-grokbot-bridge --skill safe-grokbot-bridge -g |
| Any agent, by hand | Copy skills/safe-grokbot-bridge/ into the agent's skills folder, such as~/.claude/skills/ or~/.agents/skills/ |
Then start a new session and say, for example, "Set up safe-grokbot-bridge on this machine" or "Let the bot also start agents in ~/projects/app."
To update the skill later: claude plugin update safe-grokbot-bridge@safe-grokbot-bridge in
Claude Code; codex plugin marketplace upgrade safe-grokbot-bridge, then the codex plugin add
command again in Codex; hermes skills update in Hermes; npx skills update elsewhere.
Every request except GET /healthz needs Authorization: Bearer <token>. All paths are absolute.
B=https://bridge.example.com; H="Authorization: Bearer $SGB_TOKEN"
curl -sH "$H" $B/v1/info # machine, agents, workspaces, limits
curl -sH "$H" "$B/v1/sessions?path=/home/me/projects/app" # who is already working there?
curl -sH "$H" -H 'content-type: application/json' $B/v1/sessions -d @- <<'EOF'
{"cwd": "/home/me/projects/app", "agent": "claude", "prompt": "Run the tests and fix failures."}
EOF
curl -sH "$H" "$B/v1/sessions/sgb-app-claude-3f9a1c?wait=60" # state, last_message, screen
curl -sH "$H" -H 'content-type: application/json' $B/v1/sessions/sgb-app-claude-3f9a1c/input \
-d '{"text": "Also update the changelog."}'
curl -sH "$H" -H 'content-type: application/json' $B/v1/sessions/sgb-app-claude-3f9a1c/input \
-d '{"keys": ["Enter"]}'
curl -sH "$H" "$B/v1/files?path=/home/me/projects/app&depth=2"
curl -sH "$H" "$B/v1/files/content?path=/home/me/projects/app/README.md"
curl -sH "$H" "$B/v1/git/log?dir=/home/me/projects/app&limit=10"
| Endpoint | Purpose |
|---|---|
GET /v1/info |
Machine, version, agents, workspaces and their capabilities, limits |
GET /v1/files ,GET /v1/files/content |
Directory listing, text file by line range |
GET /v1/git/{status,log,diff,show} |
Read-only git |
GET /v1/sessions |
Sessions in the workspaces you may see |
POST /v1/sessions |
Start a session ( cwd ,agent ,runner ,prompt ,model ,effort ,bypass_permissions ,keep_alive ,resume ) |
GET /v1/sessions/{id}?wait=&lines= |
State, last answer, terminal screen; long-poll while working |
POST /v1/sessions/{id}/input |
text and/orkeys |
DELETE /v1/sessions/{id} |
Stop a session the bridge started |
GET /openapi.json |
The OpenAPI document ( also in the repo ) |
| Runner | When | How you get answers |
|---|---|---|
tmux |
Default when tmux is installed. A live terminal UI; a person can attach. | last_message from the turn hook (Claude Code, Codex), plus the terminalscreen |
headless |
Without tmux (e.g. native Windows), or on request. One non-interactive run per message. | last_message ; progress while the turn runs |
external |
Sessions started outside tmux, e.g. in a terminal tab. | Claude Code: state always; with [experimental] external_sessions also messaging and answers. Codex: experimental. |
Session states: working, waiting (a permission prompt or question; read screen and answer
with keys), idle, finished (closed after its answer with keep_alive: false), exited,
failed, unknown.
The bridge types only into panes where nothing but the agent can receive the text: sessions it
started, and panes whose program is the agent (or a wrapper that ends with it). An agent you
started from a shell inside tmux is listed but not typed into, because text sent after the agent
exits would reach the shell; with [experimental] external_sessions, Claude Code and Codex there
take messages through their own inbox or queue instead. resume continues a conversation only in
the folder where it was held.
A token lets its holder make coding agents work on your machine, possibly without permission prompts if you allow that. Treat it like an SSH key. In short:
- Isolation: the agents the bridge drives run with your user's rights. Give them a virtual machine, a dedicated WSL 2 distribution or a separate computer that holds only the projects and credentials the work needs; seeWhere to run it .
- Tokens: 256-bit, stored as SHA-256 hashes, compared in constant time. A client IP is blocked after repeated failures, and each token has a request rate limit.
- Network: plain HTTP only on loopback. Publish it through a Cloudflare Tunnel, optionally with an Access service token as a second factor, or enable TLS with key pinning.
- Folders: capabilities per folder; access is read-only by default. Paths are canonicalized,
so
..and symlinks cannot escape. - No shell endpoint: the bridge itself never runs arbitrary commands, and git runs with options that keep a repository's own config from executing programs. The coding agents it starts do run commands, under their own permission systems.
Read the threat model and SECURITY.md.
| Linux / WSL 2 | macOS | Windows | |
|---|---|---|---|
| API, TLS, files, git, headless sessions | β | β | β |
| tmux sessions | β | β | best effort with psmux (sessions the bridge started, one pane each) |
| External Claude Code sessions | β | β | β |
-
Setup with Grok Bot and Cloudflare : the guided setup, with prompts to paste
-
Agent skill for Claude Code and Codex : how a coding agent sets up and maintains the bridge
-
agent_exitedwhen starting a session. Run the agent once by hand in that folder. It may need a login, or the agent'sargsin the config contain a flag it does not know. -
A new session waits on a "trust this folder" dialog. That is normal on the first start in a folder. Answer with
{"keys": ["Enter"]}. -
The bridge runs as a service and cannot find
claudeorcodex. Services get a minimalPATH. Set absolutecommandpaths in[agents.*], or setPATHin the service definition, and runsafe-grokbot-bridge checkin the same environment. -
A Claude Code session outside tmux does not react to messages (experimental). A session that runs without permission prompts may hold a message from another process for local approval, and drops it after a few minutes. Approve it in that session. For unattended use, set
"crossSessionInbound": "accept"on purpose, in~/.claude/settings.json(all your sessions) or with--settingsfor one session you start; a project or local settings file cannot grant it. It applies to every cross-session message the session receives. Thedesign has the details.
Issues and pull requests are welcome. See CONTRIBUTING.md.
safe-grokbot-bridge is an independent project. It is not affiliated with, endorsed by or sponsored by xAI, Cursor, Anthropic, OpenAI, Nous Research or Cloudflare. Grok, Cursor, Claude, Claude Code, Codex, Hermes and Cloudflare are trademarks of their respective owners.