agentreach

作者 bojieli已验证

AgentReach (reach): Point your coding agent at any box you can SSH into. The server never gets your agent.

90
Stars
4
Forks
Go
语言
2026/8/24
添加时间

⚠️ 第三方软件声明

本 Skill 为第三方开源软件,独立托管于 GitHub。SkillTip 仅为信息目录,不控制或维护底层仓库。所显示的安全检查为自动化且范围有限,安装前请自行审查源码。

阅读服务条款

安装

添加到你的 Claude Code skills 目录:

# Add to your Claude Code skills
git clone https://github.com/bojieli/agentreach

快速入门

使用 agentreach 等 Skills 的指南。

安全报告

已验证

上次扫描:—

{
  "status": "PASSED",
  "issues": []
}

README.md

AgentReach

Point your coding agent at any box you can SSH into. The server never gets your agent.

CI Go 1.25.8+ License Zero dependencies

The coding agent runs on your machine. reach catches its Bash, Read, Write and Edit calls before they touch the local disk and runs them over one ssh connection on the target instead. The API key and the conversation never leave your machine, and the target needs nothing but the sshd it already runs.

Why this exists

Think about the last time you SSHed somewhere to fix something. A build box, a client's staging VM, a container you spun up this morning and will throw away tonight. You'd get through it faster with an agent riding along.

So you install one there. That's a 300 MB Node binary on a machine that isn't yours, plus an API key pasted in so the thing can actually do anything. Now your key lives on a box where other people have root, in a shell history you won't clear, in an env file you'll forget about by Friday. If that server gets popped next month, your key goes with it.

Dev containers are the same story on repeat. New branch, new container, and each one wants its own copy of the agent. Baking it into the Dockerfile bloats an image that should have stayed small. Mounting it in from the host works right up until the morning it doesn't.

What reach actually does

The agent stays where it is. What moves is the work it hands off. An agent only touches a machine two ways — it runs shell commands, and it reads or writes files — and reach gets in the middle of both, on your side, before either one reaches your disk.

Commands. reach takes over whatever the harness spawns as a shell, unwraps the command, runs it over ssh on the target, and hands back stdout and an exit code. As far as the model can tell, it called Bash. Every harness offers some door in — a seam, a place where behaviour can be changed without editing the binary:

  • Claude Code — CLAUDE_CODE_SHELL_PREFIX
  • Goose — GOOSE_SHELL
  • Codex — its remote-environment protocol
  • opencode — a custom tool shadowing the built-in one
  • anything else — reach's own bash, earlier on PATH, winning the lookup

Files. Depends on the mode:

  • exec mode — the agent's own Read, Write and Edit are switched off. They call the local filesystem directly and there is no seam to redirect them through, so the agent falls back to its shell, which is already remote.
  • mirror mode — reach answers those calls itself, pulling the file over the same ssh connection when a tool opens it and pushing it back when it changes. Wired up for Claude Code today.

What this isn't. No syscall tracing. No filesystem in any of it: no SSHFS, no FUSE, no mount, no file synchronisation between the two machines. reach sits at the seam where the agent hands work to the operating system, one request and one response at a time.

HOW-IT-WORKS.md walks a single tool call through the whole path, in figures.

What it looks like

$ reach build-box claude
probing build-box ...
session "build-box" -> build-box:/home/you
  target   Linux x86_64
  fileops  pipe (negotiated; nothing written to the target)
  search   ripgrep (fast, structured)
  connect  multiplexed (one authenticated connection, reused)
reach: Claude Code -> build-box:/home/you (bash runs on the target)

> what's eating disk on this box?

Claude Code is running locally. The df and du and grep it decides to run happen on build-box. Files it reads come from build-box. If it rewrites a config, the new bytes land on build-box. Your own filesystem is untouched unless you specifically ask for something local.

Everything it did is on the record:

$ reach log
WHEN      ACTION  STATUS  DETAIL
14:02:11  exec    ok      df -h /
14:02:19  exec    ok      du -sh /var/log/*
14:02:30  write   ok      /srv/app/logrotate.conf
14:02:31  exec    exit 1  systemctl reload rsyslog

Install

go install github.com/bojieli/agentreach/cmd/reach@latest

Pre-built binaries are on the releases page. From source:

git clone https://github.com/bojieli/agentreach
cd agentreach
make install

There is also a container image on GitHub Packages, for when the machine you drive agents from is itself disposable — a CI job, a devcontainer, a jump box:

docker run --rm -v "$HOME/.ssh:/root/.ssh:ro" ghcr.io/bojieli/agentreach version

It carries an ssh client and the helper binaries for every target platform. Your keys and known_hosts have to be mounted in; there is nothing useful to bake into an image, and reach will not invent credentials it was not given.

The only thing reach needs is the ssh binary you already have. It shells out to that rather than speaking SSH itself, so ProxyJump, IdentityFile, Match blocks, hardware tokens and 2FA all keep working the way you've configured them.

You can sit in front of Linux, macOS or Windows. Targets can be anything POSIX you can reach over user@host:path, ssh://, docker:// or podman://.

Quick start

Name a machine, then name an agent:

reach build-box claude                        # an ssh_config alias; work where a login lands
reach build-box:src/app claude                # ... or in a directory you name
reach client-box:/srv/app codex               # somebody else's server

reach opens one multiplexed SSH connection, asks the host what it can do, and launches the agent locally with its shell quietly redirected there. You talk to it like you always do. Nothing is written to that host unless you ask for the helper tier by name, and reach doctor tells you exactly what was found, which tier got picked, and whether anything is sitting on the target.

Any command takes a target, not just the agents:

reach build-box exec -- go test ./...
reach build-box doctor

Each target gets its own session, named after it, so several machines can be open at once — one terminal per box, and no bookkeeping to keep them apart:

$ reach status
NAME            TARGET                    MODE  FILEOPS  CWD
build-box-app   build-box:/srv/app        exec  pipe     /srv/app
client-box-app  client-box:/srv/app       exec  posix    /srv/app

A second command against a target reuses that session instead of probing again, so running one costs no more than typing it.

When you're finished:

reach down build-box-app

That closes the connection and leaves nothing behind.

For a session meant to outlive one agent — several commands, several days, a name you chose — bind it up front and address it by name:

reach up build-box:/srv/app --name build
reach claude --session build
reach down build

Agents that work today

AgentCommandWhere reach gets inStatus
Claude Codereach claudeCLAUDE_CODE_SHELL_PREFIX, a hook it already shipsverified end-to-end (2.1.233)
Codexreach codexits remote-environment protocol, which carries every tool it hasverified end-to-end (0.148.0)
Kimi Codereach kimia patched npm bundle plus KIMI_SHELL_PATHverified (0.37.2)
opencodereach opencodecustom tools that shadow the built-in bash and readverified (1.18.18)
Goosereach gooseGOOSE_SHELL, a documented overrideverified
Crushreach crushits own server mode, run on the targetverified
Gemini CLIreach geminia bash earlier on PATH, plus excludeTools for the restverified
Grok Buildreach grok$SHELL, plus an agent profile that removes the file toolsverified (1.0.5)

Those fall into three groups, plus one exception, and the group decides how much of the agent survives the trip.

Codex and opencode are the clean ones. Both document a way to change the machine their tools act on, so reach answers at the other end and the model keeps every tool it started with. Codex is the best fit reach has, because it has no file tools at all: apply_patch and the rest run as commands inside exec_command, so intercepting that one protocol leaves nothing behind to deny.

Claude Code, Goose and Kimi hand over the shell and only the shell. Their file tools call straight into Node's fs or Rust's std::fs, so reach denies them and the agent works through its shell instead, or in Claude Code's case mirrors them if you ask for mirror mode.

Gemini gives you no hook at all, so reach wins the PATH lookup for bash and hides the rest of the built-ins through excludeTools in a managed settings.json.

Crush is the exception to the nothing-installed rule. Its server mode is exactly the seam reach wants, and reach crush starts crush server on the target and tunnels the client to it, which means crush itself has to already be there.

Whichever group you land in, nobody logs in again. Subscription logins, OAuth tokens and API keys keep working exactly as they do now, because reach never touches them.

Commands

reach <target> <cmd>    bind a session to the target and run the command there
reach up <target>       bind a session to a target and probe what it supports
reach down [session]    close a session and leave no trace
reach status            show active sessions
reach doctor            explain what a target supports, and why
reach log               what reach has run and changed on the target
reach exec -- <cmd>     run a one-off command there
reach fs read <path>    work with remote files directly
reach helper uninstall  remove anything reach put on the target

Targets look like this:

build-box                      an ssh_config alias, or a name in /etc/hosts
[user@]host:path               scp's spelling
ssh://[user@]host[:port]/path  OpenSSH's URI spelling, when a port is needed
docker://container/path
podman://container/path
local:///abs/path              (this machine, mostly for testing)

Paths mean what the tool each form is borrowed from means by them. reach invents nothing here, because someone who knows what scp box:app copies should not have to learn a second convention to use it.

For a host, a path is relative to where a login lands unless it starts with a slash, and a leading ~ is the target's to expand:

build-box:app          ~/app on build-box
build-box:/srv/app     /srv/app
build-box:~deploy/app  deploy's home, wherever the target says that is
ssh://build-box/app    ~/app — same rule, same as scp
ssh://build-box//app   /app

The second slash in the URI form is not a typo. OpenSSH's own parser treats the slash that ends the host as a delimiter, so what reaches scp and sftp as the path has no leading slash and a second one is what makes it absolute; curl reads sftp:// URLs the same way. Note that git reads ssh:// the other way round, absolute from the first slash. Where the two disagree, reach follows the ssh binary it is shelling out to.

For a container, docker cp's rule holds instead: paths are relative to the container's root, so the leading slash is optional and docker://c/srv/app and docker://c//srv/app are the same directory.

Leave the path off any of them — build-box, ssh://build-box, build-box: — and the session works wherever a login on that machine lands, which reach asks the machine for rather than guessing. A bare word is read as a host only when your own ssh configuration or hosts file names it, or when it is an address or a dotted name; anything else is reported as a mistyped command, which is what it almost always is.

Session flags go between the target and the command, and everything from the command onwards belongs to the command:

reach build-box --mode mirror --fresh claude --resume

Why not SSHFS, an MCP server, or just SSH?

Four things look like they should work. Each breaks somewhere specific.

  • Install the agent on the server. 300 MB of Node on a machine that isn't yours, and your API key with it, on a box where other people have root.
  • Run an MCP file server on the target. The model sees mcp__remote__read_file where it expected Read. You haven't moved the agent, you've retrained it.
  • Let the agent ssh in from its own shell. Every command is a separate login, so cd stops persisting and relative paths drift — and the agent's own Read and Write still edit your laptop.
  • Mount the target with SSHFS or FUSE. macOS wants a kernel extension and a reboot. Worse, when the link stalls the read is stuck inside the kernel: the tool call never returns, and the model gets no error it could retry.

A mount turns one tool call into a stream of syscalls through the kernel's VFS and a FUSE daemon, so a stalled link parks the agent in uninterruptible sleep with no error it can see. reach answers each tool call with one request and one response over ssh, so a timeout comes back as a tool error the model can read, retry or route around. Nothing is mounted and no kernel is involved.

How it works

Three layers, and only the top one knows which agent you're running.

harness  (claude · codex · kimi · opencode · goose · crush · gemini · grok)
    │     native tool calls, no new tools in the model's view
adapter   one per harness, config or plugin, never a fork
    │
reach     session state · cwd · capability probe
    │     file-op tier: posix · pipe · helper
    │  ssh · docker · podman · local
target    stock sshd, nothing installed

There's no daemon. A session is just a file on disk. SSH's ControlMaster already multiplexes the connection at four to five times the speed of reconnecting, so a daemon would buy lifecycle complexity and nothing else.

By default nothing gets written to the target. Two of the three file-operation tiers touch its disk zero times, and those two are the only ones reach will choose on its own. The third uploads a small helper, and only if you ask for it by name.

tierneeds on targetwrites to targetchosen automatically
posixa POSIX shellnothingyes, as fallback
pipepython3nothingyes, preferred
helpercan run an uploaded binaryone cached binarynever

TRANSPORTS.md has the numbers, measured over real links rather than loopback. HOW-IT-WORKS.md follows a single Bash call all the way down and back — the envelope reach takes apart, how cd survives between calls, and where the exit status hides.

Choosing a mode

exec is the default, and it's the one to stay on unless you have a reason not to. --mode mirror earns its keep during heavy editing sessions, when you'd rather use Claude Code's native file tools than push every change through a shell redirect:

reach build-box:/srv/app --mode mirror claude

Mirror keeps a content digest for each file it hands over, so if the file changed on the server between the read and the write, the write is refused rather than clobbering someone else's work. Go in knowing what it is, though: reads can be a little stale, and it copies on demand rather than syncing. For shell-shaped work exec is simpler and has no staleness window at all.

Security

reach assumes the target might be hostile, and the design reflects that.

Your credentials never make the trip. The agent, its API key and the whole conversation stay on your machine.

SSH agent forwarding is off and stays off. A forwarded agent socket on a hostile server lets whoever controls that server authenticate as you everywhere else you can reach, which is a much bigger blast radius than the session you thought you were opening. reach never enables it and there is no flag that does.

Nothing is installed by default. Tier 0 needs a POSIX shell and writes nothing at all.

The agent's shell snapshot gets stripped out of forwarded commands. Claude Code's command envelope sources a file from your home directory, and shipping that to the server would hand over your username and directory layout for no benefit.

What reach can't do anything about is prompt injection. Content from the target flows into the agent's context, and a compromised server can absolutely try to talk to your agent. Keep secrets out of the agent's local environment, and read anything it writes to your local disk during a remote session. The full threat model is in docs/SECURITY.md.

Docs

HOW-IT-WORKS.mdthe implementation in figures, and what reach is deliberately not
ARCHITECTURE.mdhow the pieces fit, and which alternatives got thrown out
TRANSPORTS.mdthe three file-operation tiers, benchmarked on real links
RESEARCH.mdwhat each agent does internally, with transcripts
SECURITY.mdthreat model, and what reach won't save you from
WINDOWS.mdrunning reach from Windows
CONTRIBUTING.mdthe standard of evidence, and the design rules
harnesses/per-agent notes: the seam, verified versions, known limits

Development

make check        # vet plus unit tests. No network, no API key.
make integration  # every file-operation tier against a real sshd
make bench        # what each tier actually costs
make conformance  # do the agent seams still have the shape reach expects?
make e2e          # real agents against a real target (spends tokens)

make integration starts an sshd owned by your own user on a high port. No root, no Docker, no outbound network. If you'd rather test against a box you already have, set REACH_TEST_SSH_HOST=my-box.

Status

The Claude Code path is verified end-to-end against a real agent on real hosts across three continents. The file-operation layer has been through three tiers, six hosts, three userlands and a fuzzer, and it's solid. Every other agent is exactly as far along as its notes say it is.

Interfaces may still move before 1.0. Three things won't: the file-operation protocol, the session format, and the promise that nothing lands on your server unless you asked for it.

Acknowledgements

reach exists because Zihan Zheng (@zzh1996) proposed the idea.

License

MIT. See LICENSE.

常见问题

What is agentreach?

agentreach is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by bojieli. AgentReach (reach): Point your coding agent at any box you can SSH into. The server never gets your agent. It has 90 GitHub stars.

Is agentreach safe to use?

Yes. agentreach passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.

How do I install agentreach?

Clone the repository with "git clone https://github.com/bojieli/agentreach" and add it to your Claude Code skills directory (see the Installation section above).

What programming language is agentreach written in?

agentreach is primarily written in Go. It is open-source under bojieli on GitHub, so you can review or fork the full source.

Are there alternatives to agentreach?

Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh agentreach against similar tools.

评论 (0)

暂无评论,成为第一个分享想法的人!

ECC

by affaan-m

10

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

242,21936,702JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情
15

An agentic skills framework & software development methodology that works.

234,96620,863Shell
AI 智能体ai-agentsbrainstorming
查看详情

hermes-agent

by NousResearch

10

The agent that grows with you

234,43747,175Python
AI 智能体ai-agentsagent-orchestration
查看详情

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

185,94028,768JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情

cc-switch

by farion1231

3

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

128,8688,826Rust
AI 智能体claude-codeai-tools
查看详情

claude-code

by anthropics

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

120,03119,897Shell
AI 智能体
查看详情

开发者还喜欢

基于喜欢此 Skill 的开发者投票和收藏

ECC

by affaan-m

10

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

242,21936,702JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情
15

An agentic skills framework & software development methodology that works.

234,96620,863Shell
AI 智能体ai-agentsbrainstorming
查看详情

hermes-agent

by NousResearch

10

The agent that grows with you

234,43747,175Python
AI 智能体ai-agentsagent-orchestration
查看详情

n8n

by n8n-io

12

Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

201,88160,308TypeScript
MCP 服务器apisai-tools
查看详情

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

185,94028,768JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情

cc-switch

by farion1231

3

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

128,8688,826Rust
AI 智能体claude-codeai-tools
查看详情