Antigravity CLI Companion for JetBrains IDEs
A JetBrains plugin that bridges the Antigravity CLI
(agy) with JetBrains IDEs (IntelliJ IDEA, PhpStorm, WebStorm, PyCharm, GoLand,
and other IntelliJ-based IDEs) so the agent can see your active file, selection,
open tabs, and inspection diagnostics on demand.
Not the official Google extension. This is an independent, third-party plugin. Google's own Antigravity agent installs from JetBrains AI → Settings → Agents and requires IDE 2026.2.1+ — see Google's official setup guide. If that is what you are looking for, use it. This plugin serves a different purpose: it runs the Antigravity CLI (
agy) in an IDE terminal and feeds it editor context over MCP, on IDE 2023.2 and up, with no JetBrains AI dependency.
Features
The plugin exposes four MCP tools to agy:
When you click the Open Antigravity CLI toolbar button, agy launches in
an IDE-embedded terminal already wired to the current project — no manual
configuration steps. By default the button focuses the existing Antigravity
terminal tab if one is open; toggle Always open a new tab in settings to
spawn a fresh session on every click.
Requirements
- A JetBrains IDE built on IntelliJ Platform 232+ (PhpStorm, IntelliJ IDEA, WebStorm, GoLand, RustRover, … — anything from 2023.2 through the current release).
- The Antigravity CLI installed locally. The plugin will look for
agy(oragy.exeon Windows) on$PATH, then in~/.local/bin,/opt/homebrew/bin, and/usr/local/bin. You can override the location in the plugin settings. - macOS, Linux, or Windows. The plugin's stdio bridge uses the IDE's bundled
JBR (Java) — no external tools like
ncare required.
Installation
From a release ZIP
- Grab or build an
antigravity-companion-<version>.zip(see Building from source if you don't have one). - In the IDE: Settings → Plugins → ⚙ → Install Plugin from Disk…
- Pick the ZIP and restart when prompted.
From source
See Building from source.
Configuration
Open Settings → Tools → Antigravity CLI Companion.
- Path to agy executable — absolute path to the
agybinary the plugin should launch. Leave blank to auto-detect ($PATH+ common install dirs). The settings panel tells you which path it currently resolves to. - Always open a new tab — when off (default), clicking the toolbar focuses
the existing Antigravity terminal tab if one is open; when on, every click
spawns a fresh
agysession. - Fix prompt editing in the IDE terminal — on by default (not shown on
Windows). Launches
agyunder a non-xtermterminal name so it stops emittingCSI Z, which the IDE's terminal emulator ignores. See Prompt editing workaround. Turn it off if you runsshor containers from insideagyand needTERMpassed through unchanged. - Auto-approve tool calls (skip permission prompts) — off by default.
Launches
agywith--dangerously-skip-permissions, so it runs shell commands and other tool calls without stopping to ask — the closest thing it has to an auto mode. Only affects sessions started from this IDE: anagyyou launch in a plain terminal is unchanged, and nothing is written toagy's own configuration. Two things still stop for you regardless — admin escalation always prompts, and access outside the workspace root stays governed byagy's ownallowNonWorkspaceAccesssetting. Takes effect for the next session you open; terminal tabs already running keep the mode they started with. Leave it off unless you are watching the session. - Keyboard shortcut — no shortcut is bound by default (no chord is safe
across every bundled keymap). Click Configure shortcut in Keymap settings…
in the panel, or open Settings → Keymap directly and search for
Open Antigravity CLI, to assign one. Multiple parallel
agysessions are still supported regardless of how the action is triggered.
No other configuration is required. The plugin manages
~/.gemini/config/mcp_config.json on its own and cleans up after itself when
projects close.
Usage
- Open a project and the file you want
agyto see. - Click the lightning ⚡ toolbar button (top-right) or invoke
Open Antigravity CLI from Find Action (
⇧⌘A/Ctrl+Shift+A). - A terminal tab opens with
agyrunning. Ask it about your code — when it needs context it will call the plugin's MCP tools transparently.
A useful first prompt: "What file am I looking at? Use ide_get_active_editor."
How it works
agy reads MCP server definitions from ~/.gemini/config/mcp_config.json. On
project open the plugin:
- Starts a small JSON-RPC server on
127.0.0.1:<random>(line-delimited MCP over a plain TCP socket). - Writes a per-project bridge script —
jetbrains-mcp-bridge-<productCode>-<projectHash>.shon Unix or.baton Windows — under~/.gemini/antigravity-cli/.<productCode>is the JetBrains IDE code (iu,ps,ws,py,go, …) so two IDEs opening the same project don't collide. The script uses the IDE's bundled JBR to run a tiny pure-Java stdio↔TCP relay, soagy(which speaks stdio MCP) can reach the in-IDE TCP server with no external dependencies. - Merges its entry into
mcp_config.jsonundermcpServers.jetbrains-companion-<productCode>-<projectHash>(preserving any other entries).
On project close it removes the config entry and deletes the bridge script.
┌────────────────────┐ stdio ┌──────────────────┐ TCP ┌─────────────────┐
│ agy CLI (terminal) │ ─────────► │ bridge script │ ───────► │ Plugin MCP svr │
│ │ ◄───────── │ (JBR StdioBridge)│ ◄─────── │ (in JetBrains) │
└────────────────────┘ └──────────────────┘ └─────────────────┘
Where things live
Troubleshooting
The "Open Antigravity CLI" button shows a notification "agy executable
not found".
Open Settings → Tools → Antigravity CLI Companion and set the path explicitly,
or install agy to one of the auto-detected locations.
agy answers "I don't have visibility into your IDE".
The plugin probably isn't registered. Check:
- Settings → Plugins — make sure the plugin is enabled.
idea.logforMCP server listening on 127.0.0.1:<port>.~/.gemini/config/mcp_config.jsoncontains ajetbrains-companion-*entry.
agy log shows Connection refused or socket errors on startup.
The IDE (or that project) closed while agy was still running. Quit agy and
relaunch it from the toolbar button — the plugin re-registers a fresh port
each time a project opens.
mcp_config.json is corrupted.
Delete it; the plugin will recreate it on the next project open.
Editing in the middle of the agy prompt garbles the text.
Make sure Fix prompt editing in the IDE terminal is enabled under
Settings → Tools → Antigravity CLI Companion, then open a new Antigravity tab —
the terminal name is chosen when the session starts. See below for what is
actually going on.
Prompt editing workaround
agy is a charmbracelet (Bubble Tea) TUI whose renderer picks the cheapest
encoding for each cursor move: backspace for one column, CSI n D for a few,
and CSI Z — CBT, cursor backward tabulation — to jump back by tab stops.
JediTerm, the emulator behind both the classic and the reworked JetBrains
terminal, parses CSI Z but does not implement it: it falls through to the
default branch, logs Unhandled Control Sequence and does nothing. The cursor
silently stays put while agy believes it moved, so the next repaint — which
writes <new char><rest of line> and then walks the cursor back — lands several
columns too far right and paints the tail of the line over itself.
agy's own buffer is never wrong, which is why the text looks correct again the
moment you submit it. Switching terminal engines in Settings does not help
(TerminalStarterEx extends TerminalStarter, whose createEmulator() returns
a JediEmulator).
You can confirm the gap in any terminal — the * belongs at column 9:
printf 'ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\033[17G\033[Z*\n'
A working terminal prints ABCDEFGH*JKLMNOPQRSTUVWXYZ; JetBrains prints
ABCDEFGHIJKLMNOP*RSTUVWXYZ.
agy enables the tab optimisation purely on TERM carrying an xterm prefix —
the terminfo database is never consulted, so cancelling cbt on an
xterm-named entry changes nothing. The plugin therefore launches agy under a
terminal name that is not xterm*: a private agyterm-256color entry
(literally xterm-256color under a different name, compiled into ~/.terminfo
on first use) so anything agy spawns still gets exactly the xterm key
encodings it expects, falling back to nsterm-256color from the standard
ncurses database when tic is unavailable. The byte cost is unmeasurable, and
alt-screen, kitty keyboard and bracketed paste all still negotiate.
The -256color suffix is load-bearing, not cosmetic. The IDE terminal exports
TERM=xterm-256color and no COLORTERM, so TERM is the only signal agy has
for colour depth. Its detector (charmbracelet/colorprofile) splits TERM on
- and matches the parts against a fixed table; a bare agyterm matches
nothing and drops agy to the 16-colour ANSI profile, where its greys and
slates collapse onto the nearest ANSI colour and the whole UI turns blue. Only
the first part is tested for the xterm prefix, so <name>-256color keeps the
full palette and keeps CSI Z suppressed. If you rename the entry, keep the
suffix.
agy's light/dark palette is a separate matter and is not something the plugin
sets: it comes from colorScheme in ~/.gemini/antigravity-cli/settings.json,
changed via /settings → Color Scheme. JediTerm does not answer OSC 11
background-colour queries, so agy cannot detect your IDE theme on its own —
pick the scheme that matches it.
The real fix belongs in JediTerm, where Tabulator.previousTab(int) is already
implemented in JediTerminal$DefaultTabulator and called by nothing.
Building from source
Prerequisites
- Git
- JDK 17 (Temurin, Zulu, or the IDE's bundled JBR all work).
JAVA_HOMEmust point at it. - Internet access on first build — the IntelliJ Gradle plugin downloads a
sandboxed IDE matching
platformVersioningradle.properties.
Steps
git clone https://github.com/matasarei/antigravity-companion.git
cd antigravity-companion
./gradlew buildPlugin
The signed (unsigned in dev) plugin archive will be at:
build/distributions/antigravity-companion-<version>.zip
Install it via Settings → Plugins → ⚙ → Install Plugin from Disk….
Useful Gradle tasks
./gradlew runIde # launch a sandbox IDE with the plugin pre-loaded
./gradlew verifyPlugin # IntelliJ Plugin Verifier — static checks
./gradlew clean buildPlugin # full rebuild
./gradlew runIde is the fastest dev loop: it starts a fresh sandbox IDE,
side-loads the plugin, and tears down on exit. Edit code, rerun, repeat.
Project layout
src/main/
├── java/dev/matasar/antigravity/bridge/
│ └── StdioBridge.java ← pure-Java stdio↔TCP relay
└── kotlin/dev/matasar/antigravity/
├── action/StartSessionAction.kt ← toolbar button
├── service/AntigravityCompanionService.kt ← MCP server + tool impls
├── settings/AntigravitySettings.kt ← persistent state
├── settings/AntigravitySettingsConfigurable.kt ← Settings panel
├── terminal/TerminfoCompat.kt ← JediTerm CSI Z workaround
└── startup/AntigravityStartupActivity.kt ← eager-init on project open
src/main/resources/
├── META-INF/plugin.xml ← plugin manifest
└── icons/ ← toolbar / plugin icons
build.gradle.kts, gradle.properties, settings.gradle.kts
Known limitations
- WSL2 on Windows. When running the JetBrains IDE natively on Windows but working on a project located in a WSL2 path (
\\wsl.localhost\<distro>\...), the plugin cannot spawn a Linuxagybinary directly. The only supported workaround is to run the JetBrains IDE itself inside WSL2 (e.g. using JetBrains Gateway or WSLg) and install the plugin andagyinside WSL. - Pull-based only. The IDE does not push selection changes to
agymid-conversation;agycalls back over MCP when it decides it needs IDE state. - Multi-project. Each open project registers a separate
jetbrains-companion-<productCode>-<projectHash>entry. A runningagyin workspace A will also see workspace B's tools in its catalog; only the live project's bridge succeeds, but the duplicate tool names can confuse the model.
License
MIT — see LICENSE.