CLI tool
ccpopy/antissh avatar
ccpopy/antissh

antissh routes the Antigravity agent through a proxy by wrapping its binaries

反重力Agent代理一键脚本,支持WSL、SSH远程

589 stars38 forksShellMIT

At a glance

What is it?
antissh is a Bash script that configures a proxy for the Antigravity IDE remote agent or the Antigravity CLI on Linux, using graftcp to intercept outbound traffic. It works by backing up the agent binary and replacing it with a wrapper that launches the original through the proxy, and it does nothing on macOS or Windows because graftcp needs ptrace.
Who is it for?
Adopt antissh if you run the Antigravity agent on Linux, or in WSL with mirrored networking, and you need its outbound traffic to go through a local proxy without reconfiguring the agent itself. Do not adopt it on macOS or Windows, where graftcp cannot run and the README points to Proxifier or a TUN mode instead.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 64 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two targets, one mechanism, and Linux only

antissh is a one-shot configuration script for the Antigravity agent, and the README is precise about what it configures. There are two possible targets, chosen when the script starts. The first is the Antigravity IDE remote agent, the language_server process, and the second is the Antigravity CLI, the agy command, which the README says is installed by default at ~/.local/bin/agy.

Both are Go programs that share the same agent engine, and the script proxies their outbound traffic uniformly through a graftcp wrapper.

The platform support table is blunt. Linux is supported, using graftcp for automatic proxying, and the script is Bash and requires Bash 4 or newer. macOS is not supported, because graftcp depends on the Linux ptrace system call, and the README recommends Proxifier or a TUN mode there. Windows is likewise not supported, with the same recommendation plus DLL injection, and it notes that WSL can be used the Linux way.

That constraint is the whole scope of the project. This is not a cross-platform network tool, it is a script that automates one configuration on one operating system and tells you what to do instead on the others.

The download and run sequence is three commands

The README's Linux instructions start by fetching the script and making it executable:

bash
curl -O https://raw.githubusercontent.com/ccpopy/antissh/main/antissh.sh
bash
chmod +x antissh.sh

Then the script itself is run interactively:

bash
bash ./antissh.sh

Running it again is also how you change the proxy later, since the README says under the section on changing the proxy that you simply run the script again to update the settings. That is a convenient property, since the alternative would be editing the wrapper by hand.

The interactive prompts are documented in order. The script asks whether you want to configure a proxy, then which target to configure, offering the IDE remote agent as the default, the CLI, or both. It then asks for the proxy address, which must be in the form socks5://127.0.0.1:10808 or http://127.0.0.1:10808, and then asks for a DNS resolution strategy, with the system DNS forced by default. After that it installs dependencies, compiles graftcp, detects which graftcp runtime mode applies, locates the target binary, backs it up, writes a wrapper, cleans up leftover processes, and tests that the proxy path works.

The two repository files reflect that flow. antissh.sh is the main script, and installAntigravity.sh sits beside it.

graftcp v0.8 changed the shape of the whole configuration

The most operationally interesting detail in the README is the graftcp version split, because it decides whether you need a local port at all.

With graftcp v0.8 and later, the official project ships a single binary at local/graftcp and the old graftcp plus graftcp-local pair is no longer produced. The script detects the newer structure and starts the agent with that binary directly, so no local listening port is required. With the v0.7 legacy layout, the script configures a graftcp-local listener, and that listener needs a local port, 2233 by default.

The legacy path is where the interaction gets complicated, and the README documents it in detail. If the script finds a valid record in ~/.graftcp-antigravity/last_graftcp_local_port, it offers to reuse that port with a Y or n confirmation where the default is yes. If there is no valid record, or you decline, it asks for a port number with 2233 as the default, and entering a number such as 2234 or 2235 selects a different one. If the chosen port is held by another graftcp-local service, the script reuses that service, and if it is held by some other process, the script asks for a different value.

The script also cleans up processes belonging to the current user, removing stale graftcp-local instances, and it preserves the instance matching the port you just selected. The multi-user note in the README is worth repeating: with graftcp v0.8 and later there is no port conflict between users, but if you point GRAFTCP_DIR at a v0.7 legacy directory the port record is shared per system account, so two people sharing one Linux account will interfere with each other.

The agent binary is replaced by a wrapper, and the .bak file is the undo

The mechanism is a binary swap, and the README explains it plainly. The script backs up the original file and generates a wrapper, and the wrapper starts the detected graftcp executable to launch the .bak file.

That is why the README notes that seeing .bak files is expected behaviour. The .bak is the original binary, the language_server_* file is replaced by the wrapper, and the wrapper invokes the .bak through graftcp. It is a normal part of the flow, not a symptom of a failed run.

The undo is equally simple, and the README gives the two commands. For the IDE agent you move the backup over the wrapper:

bash
mv /path/to/language_server_xxx.bak /path/to/language_server_xxx

And for the CLI it is the same idea against the agy binary:

bash
mv ~/.local/bin/agy.bak ~/.local/bin/agy

The actual paths are printed when the script finishes, so you do not have to guess them. The script also removes leftover language_server processes as part of the configuration, with one deliberate exception: the README notes that agy is an interactive process and the script does not actively clean up a running agy.

The script can also find the CLI binary on PATH, not only at the default location, and it supports multiple versions of the IDE remote agent coexisting, which matters because the IDE keeps a separate binary per installed version.

An IDE upgrade moves the binary and breaks the proxy

There is a section of the README dedicated to a failure mode that will hit you eventually. After an IDE upgrade, a new version directory can appear under ~/.antigravity-server/bin/ for the 1.x line, or under ~/.antigravity-ide-server/bin/ from 2.0 onward, and the proxy configuration that pointed at the old directory stops working. The README notes that Antigravity 2.0 renamed the remote server directory from .antigravity-server to .antigravity-ide-server, and the script handles both.

The README then explains how to find the new version directory. You open the Antigravity client, go to Help then About, and use the Copy button to copy the version information. In the copied text you look for the line that starts with Electron:, and the hash value on that line, for example a 40 character hex string, is the Commit ID. The remote server version directory is named with the version number and that commit ID, so the hash is the second half of the directory name.

There are two ways out. The recommended one is to run the script again, because it detects the new directory and reconfigures, and it will offer the last used port so you do not have to remember it. The manual alternative is to enter the new directory, rename language_server_linux_* to language_server_linux_*.bak, and copy the wrapper script from the old directory into the new one, which preserves the full configuration including the port because the wrapper contains it.

WSL needs mirrored networking, and DNS is the usual casualty

The troubleshooting section is the most practically useful part of the README, because it deals with the two things that actually break.

The first is WSL2 networking. The recommendation is to enable Mirrored network mode so that WSL uses the host proxy directly at 127.0.0.1. The configuration lives in a .wslconfig file in the Windows user directory:

ini
# %USERPROFILE%\.wslconfig
[wsl2]
networkingMode=mirrored

And then WSL is restarted with:

powershell
wsl --shutdown

After that the proxy address can be used directly, for example socks5://127.0.0.1:10808 or http://127.0.0.1:10808. The README notes that Mirrored mode needs Windows 11 22H2 or later and WSL 2.0.0 or later, and that without it you need the WSL virtual adapter gateway address, which is usually the nameserver entry in /etc/resolv.conf.

The second is DNS. The README describes a case where curl reaches Google through the proxy but the language_server still reports a DNS error, and explains why: curl may be relying on the proxy to resolve the name, for example with an HTTP proxy or socks5h, while the wrapper forces the system DNS with netdns=cgo, and the two are not equivalent. The suggested fix is to choose the option that does not force system DNS during the script run and let your own resolver, such as smartdns or dnscrypt-proxy, take over. For WSL2 in Mirrored mode, Google resolution problems are said to be uncommon, so the advice is to only change it if you hit a special network restriction.

For cleaning up stale processes, the README gives a two step approach, first looking at what is running and only then killing it:

bash
pgrep -a graftcp-local || true
pgrep -a language_server || true
bash
pkill -f graftcp-local || true
pkill -f language_server || true

For the IDE proxy itself on Windows and macOS, the README offers two choices, using Proxifier to proxy the IDE process, or using the proxy's TUN mode. The last point is the one to keep in mind before reaching for any of this: the script configures the agent, and it does nothing about the local IDE's own connection, so a remote agent that cannot load a model is often a local IDE proxy problem rather than a script problem.

Editorial conclusion

Adopt antissh if you run the Antigravity agent on Linux, or in WSL with mirrored networking, and you need its outbound traffic to go through a local proxy without reconfiguring the agent itself. Do not adopt it on macOS or Windows, where graftcp cannot run and the README points to Proxifier or a TUN mode instead. Verify first that you have Bash 4 or newer on Linux, that your proxy is reachable from the machine where the agent runs, and that you keep the .bak files the script creates, since restoring the original binary is the documented way to undo the change.

Frequently asked questions

What does the antissh script do on Linux?

It configures a proxy for the Antigravity IDE remote agent, the language_server, or the Antigravity CLI, the agy command, by backing up the agent binary and replacing it with a wrapper that starts the original through graftcp. The script requires Bash 4 or newer and runs interactively.

Does antissh work on macOS or Windows?

No. graftcp depends on the Linux ptrace system call, so macOS and Windows are listed as unsupported, and the README recommends Proxifier or the proxy's TUN mode there, plus DLL injection as a further option on Windows. WSL can be used the Linux way.

How do I change or undo the proxy configuration set by antissh?

To change the proxy, run the script again. To undo it, move the backup over the wrapper, for example mv /path/to/language_server_xxx.bak /path/to/language_server_xxx for the IDE agent or mv ~/.local/bin/agy.bak ~/.local/bin/agy for the CLI. The script prints the real paths when it finishes.

Why does the proxy stop working after an Antigravity IDE upgrade?

The IDE can create a new version directory under ~/.antigravity-server/bin/ for 1.x, or ~/.antigravity-ide-server/bin/ from 2.0 onward, and the wrapper configured for the previous directory no longer applies. The fix is to run the script again so it detects the new directory, or to rename language_server_linux_* in the new directory and copy the old wrapper across.

What is the difference between graftcp v0.8 and the v0.7 legacy layout in antissh?

From v0.8 the official project ships a single local/graftcp binary and no longer produces the graftcp plus graftcp-local pair, so no local listening port is needed. The v0.7 legacy layout needs a graftcp-local listener on a port, 2233 by default, which the script records in ~/.graftcp-antigravity/last_graftcp_local_port and offers to reuse.

Official sources

  1. ccpopy/antissh on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ccpopy-antissh.svg)](https://hysenlabs.com/projects/ccpopy-antissh)

Was this useful?