Antigravity CLI¶
Antigravity CLI is used as an AI agent that can be used directly in a terminal.
I use the Antigravity CLI to help generate bash script files and markdown documents for zensical. It is my preferred coding agent for homelab automation.
I also use the Antigravity CLI to provision Proxmox containers using the provided MCP servers.
Installation¶
Config path: ~/.antigravity/
Config¶
- Obtain an API key for your preferred AI model.
- Set it as an environment variable in your terminal. Replace
YOUR_API_KEYwith your generated key. - My current settings.json can be found in my dotfiles repository.
Syntax Files¶
Syntax files are used to customize the iutput from Antigravity.
docs/ANTIGRAVITY.md
# AI Agent Instructions (AGENTS.md)
This file serves as the primary entry point for AI agents interacting with this repository.
## Project Context & Architecture
Homelab is a centralized, automated repository managing home infrastructure across Proxmox VE, LXC containers, and Docker applications.
### Directory Layout
- `docker/`: Docker applications with `compose.yaml`, `.env.tmpl`, and `Taskfile.yml`.
- `lxc/`: Proxmox LXC system container configurations, update scripts, and service definitions.
- `pve/`: Proxmox VE node configurations (AdGuard Home, Traefik, Reprepro).
- `docs/`: Technical documentation built with Material for MkDocs / Zensical.
- `scripts/`: Python (`uv`) and Bash automation tooling.
- `vm/`: Virtual machine definitions.
### Infrastructure & Engineering Standards
- **Proxmox LXC Defaults:** Unprivileged (`--unprivileged 0`), Debian Trixie template, DHCP with SLAAC IPv6, nesting enabled (`--features nesting=1`), root SSH key access.
- **Docker Conventions:** Explicit pinned versions (no floating `latest`), `.env.tmpl` templates with SOPS-encrypted `.env.enc`, non-root execution where possible.
- **Scripting:**
- **Bash:** `#!/usr/bin/env bash`, `set -o pipefail`, ShellCheck compliant, 2-space indent, `main "$@"` entrypoint, Catppuccin Mocha logging with terminal detection.
- **Python:** Always execute via `uv run python <script>`. Strict PEP 8, type hints, docstrings.
- **Documentation:** MkDocs / Zensical with emoji headings (`# :emoji: Title`), relative `.md` links, Mermaid diagrams.
- **Idempotency & Safety:** All automation must be safe to rerun. Always ask before introducing new programming languages or performing destructive changes.
- **Task & Issue Management:** Track all new features and bug fixes using remote GitHub Issues via `gh` instead of Conductor tracks. Always pipe `gh` commands to `cat` (e.g., `rtk gh issue list | cat`, `gh issue view 123 | cat`) to avoid interactive prompts. Commits must contain `Fixes #<number>` to automatically close issues.
<!-- caveman-begin -->
## Caveman Mode
Respond terse like smart caveman. All technical substance stay. Only fluff die.
Rules:
- Drop: articles (a/an/the), filler (just/really/basically), pleasantries, hedging.
- Fragments OK. Short synonyms. Technical terms exact. Code unchanged.
- Pattern: [thing] [action] [reason]. [next step].
- Not: "Sure! I'd be happy to help you with that."
- Yes: "Bug in auth middleware. Fix:"
Switch level: /caveman lite|full|ultra|wenyan-lite|wenyan-full|wenyan-ultra
Stop: "stop caveman" or "normal mode"
Auto-Clarity: drop caveman for security warnings, irreversible actions, user confused. Resume after.
Boundaries: code/commits/PRs written normal.
<!-- caveman-end -->
<!-- ponytail-begin -->
## Ponytail (Lazy Senior Dev Mode) Guidelines
- **Stop at first rung that holds**:
1. Need to build at all? (YAGNI)
2. Already in codebase? Reuse existing helpers/utils/patterns.
3. Stdlib does it? Use it.
4. Native platform feature covers it? Use it.
5. Installed dependency solves it? Use it.
6. Can be one line? One line.
7. Only then: write minimum working code.
- **Bug fix = root cause, not symptom**: Fix shared function/path rather than individual callers.
- **Rules**:
- No unrequested abstractions, boilerplate, or avoidable dependencies.
- Deletion over addition. Boring over clever. Fewest files possible.
- Shortest working diff wins once problem understood.
- Mark deliberate simplifications cutting real corner with `ponytail:` comment naming ceiling and upgrade path.
- Output: `[code] → skipped: [X], add when [Y].`
<!-- ponytail-end -->
<!-- context-mode-begin -->
## Context-Mode Routing Guidelines
- **Derive, Do Not Dump**: Do NOT use `ctx_execute_file` or `ctx_execute` to dump whole file or full config. Print only specific value, matches, count, or known line range needed.
- **Tool Call Surface**: When using MCP wrappers, call `call_mcp_tool` with `ServerName: "context-mode_context-mode"` (or `"context-mode"`) and `ToolName: "ctx_execute"`, `"ctx_execute_file"`, `"ctx_batch_execute"`, `"ctx_fetch_and_index"`, `"ctx_search"`, or `"ctx_index"`.
- **Mandatory Routing**:
- For analyze/count/filter/compare/search/parse/transform tasks, write code with `ctx_execute` and print only final answer.
- For analyzing/exploring inside file, use `ctx_execute_file`. Use native `read_file` only when editing requires exact bytes or small known range.
- Use `ctx_batch_execute` for multi-command repository reconnaissance.
- Use `ctx_execute` for shell commands whose output may exceed short fixed answer.
- Use `ctx_fetch_and_index` for web content, then `ctx_search` to query it.
- Return only derived answers, concise summaries, selected snippets, or file paths.
<!-- context-mode-end -->
<!-- codegraph-begin -->
## CodeGraph
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
- **MCP tool** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
- **Shell** (always works): `codegraph explore "<symbol names or question>"` prints the same output.
If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision.
<!-- codegraph-end -->
<!-- serena-begin -->
## Serena Semantic Code Tools
Serena MCP provides Language Server Protocol (LSP) backed semantic coding tools, token-efficient AST symbol search, reference-aware refactoring, and persistent project memories:
- **Project Activation**: When Serena is available, ensure the workspace is active before querying code. If Serena returns `No active project`, call `activate_project` with the project root directory.
- **Symbol Inspection Over File Dumps**: Do not dump entire source code files into context. Use `get_symbols_overview` for a high-level view of symbols in a file, or `find_symbol` to retrieve specific classes, functions, or methods with their bodies.
- **Pattern & Reference Search**: Use `search_for_pattern` to locate symbols when the exact path is unknown, and `find_referencing_symbols` to analyze blast radius and callers.
- **Atomic Refactoring**: Prefer Serena's reference-aware editing tools (`rename_symbol`, `safe_delete_symbol`, `replace_symbol_body`) over manual regex or line-based text edits when refactoring existing symbols.
- **Persistent Memory**: Use `read_memory`, `write_memory`, and `list_memories` to retrieve or store durable project facts and conventions across agent sessions (`mem:core`).
- **Diagnostics**: Use `get_diagnostics_for_file` to inspect LSP compiler/linter warnings and errors on modified files.
<!-- serena-end -->
<!-- headroom-begin -->
## Headroom MCP (Context Window Compression)
Use Headroom (`headroom`) MCP tools to manage context window consumption on large payloads:
- `headroom_compress`: Shrink large tool outputs or raw data.
- `headroom_retrieve`: Retrieve original content by hash if specific details needed.
- `headroom_stats`: Monitor headroom cache usage.
<!-- headroom-end -->
<!-- ripwire-begin -->
## Ripwire CLI Guidelines
Use `ripwire` CLI (prefixed with `rtk ripwire`) for AST codebase mapping, call graphs, blast radius, and structural queries:
- **CLI First**: Always invoke `rtk ripwire <dir> [flags]` via CLI; do NOT use MCP server.
- **Task Orientation**: `rtk ripwire <dir> --for="<task>"` for ranked signatures and bodies.
- **Task Bundle**: `rtk ripwire <dir> --pack-task="<task>" --legend=compact`.
- **Stack Trace / Error**: `rtk ripwire <dir> --from-trace=FILE --legend=compact` (`-` for stdin).
- **Call Graph**: `rtk ripwire <dir> --callers=SYM`, `--callees=SYM`, `--uses=SYM`.
- **Blast Radius**: `rtk ripwire <dir> --impact=SYM --legend=compact` before changing shared code.
- **Quality Delta & Gate**: `rtk ripwire <dir> --quality-delta --legend=compact` and `--test-gate --legend=compact`.
- **Atomic Edits**: `rtk ripwire <dir> --replace-symbol-body=SYM --edit-payload=FILE` without whole-file re-reading.
<!-- ripwire-end -->
<!-- ripgrep-guidelines-begin -->
## Ripgrep Guidelines
- **Pattern Searching**: Always use `rg` (ripgrep) or `rtk rg` instead of standard `grep` to search text inside files quickly and save token output.
- **Scope**: Use `-t py` for Python files, `-l` for file listing, keep context small (`-C 1`).
<!-- ripgrep-guidelines-end -->
<!-- taplo-rules-begin -->
## Taplo TOML Rules
- **Format**: Run `rtk taplo fmt` to format TOML files in-place.
- **Validation**: Run `rtk taplo lint` to validate TOML syntax and schema.
<!-- taplo-rules-end -->
<!-- uv-rules-begin -->
## Python Tooling & Execution with `uv`
When executing Python scripts in this workspace, always use `rtk uv run python <script>` instead of just `python` to ensure the correct virtual environment and dependencies are used. Do not use pip; use `rtk uv add` for managing dependencies. Keep `uv.lock` and `pyproject.toml` synchronized and committed.
<!-- uv-rules-end -->
## OpenMediaVault (OMV) Networking
When configuring or modifying network settings on an OpenMediaVault (OMV) system, never edit `/etc/netplan` or `/etc/systemd/network` files directly, as they will be overwritten. Instead, read and update the OMV database using `omv-confdbadm` (e.g., `omv-confdbadm read conf.system.network.interface`). After updating the database, apply the changes by running `omv-salt deploy run systemd-networkd`.
## LXC Application Updates
When asked to update LXC web applications, run `scripts/lxc_update.py` directly with `rtk` without probing nodes or manual container inspection:
- `drawio`: `rtk uv run python scripts/lxc_update.py drawio [-v <version>]`
- `localsend`: `rtk uv run python scripts/lxc_update.py localsend`
- `wallos`: `rtk uv run python scripts/lxc_update.py wallos --node pve03`
- `changedetection`: `rtk uv run python scripts/lxc_update.py changedetection --node pve04`
- `stirling-pdf`: `rtk uv run python scripts/lxc_update.py stirling-pdf --node pve04 [-v <version>]`
- `homepage`: `rtk uv run python scripts/lxc_update.py homepage --node pve04 [-v <version>]`
- `convertx`: `rtk uv run python scripts/lxc_update.py convertx --node pve04 [-v <version>]`
- `reactive-resume`: `rtk uv run python scripts/lxc_update.py reactive-resume --node pve04 [-v <version>]`
- `withoutbg`: `rtk uv run python scripts/lxc_update.py withoutbg --node pve03 [-v <version>]`
- `gitea`: `rtk uv run python scripts/lxc_update.py gitea --node pve03 [-v <version>]`
- `bentopdf`: `rtk uv run python scripts/lxc_update.py bentopdf --node pve03`
- `pocket-id`: `rtk uv run python scripts/lxc_update.py pocket-id --node pve03`
- `homebox`: `rtk uv run python scripts/lxc_update.py homebox --node pve03`
- `omni-tools`: `rtk uv run python scripts/lxc_update.py omni-tools --node pve04`
- `gatus`: `rtk uv run python scripts/lxc_update.py gatus --node pve04`
- `vaultwarden`: `rtk uv run python scripts/lxc_update.py vaultwarden --node pve03 [-v <version>]`
- `freshrss`: `rtk uv run python scripts/lxc_update.py freshrss --node pve03`
- `yamtrack`: `rtk uv run python scripts/lxc_update.py yamtrack --node pve03`
- `solidcraft`: `rtk uv run python scripts/lxc_update.py solidcraft --node pve03 [-v <version>]`
- `installer`: `rtk uv run python scripts/lxc_update.py installer --node pve04`
When updating any web app not yet saved, set up its `update.sh` and persist its details across the 3 layers (Rules in `AGENTS.md` / `.agents/rules/`, Serena memories in `mem:core` / `mem:suggested_commands`, and RTK filters in `.rtk/filters.toml`) to streamline future runs.
## LXC Webhook & Auto-Update Hooks
To configure automated updates for an LXC application via ChangeDetection and Webhook:
- Scaffold, deploy, and register: `rtk uv run python scripts/lxc_webhook.py scaffold <app> && rtk uv run python scripts/lxc_webhook.py deploy <app> && rtk uv run python scripts/lxc_webhook.py cd-watch <app> --repo <owner/repo>`
- Skill: `.agents/skills/webhook-add/SKILL.md` (`/webhook add <app> <repo>`).
<!-- sensitive-information-protection-begin -->
## Security & Sensitive Data Invariants
- **NEVER commit sensitive data**: Never stage or commit passwords, secrets, API tokens, access keys, private keys, authentication credentials, unencrypted `.env` files, or configuration/settings files containing plain-text secrets.
- **Use SOPS for Secret Storage**: All secrets must be encrypted with SOPS (`.env.enc`, `secret.txt.enc`). Commit only `.enc` encrypted files and templates (`.env.tmpl`), never unencrypted secrets.
- **Pre-Commit Verification**: Run `rtk git diff --staged` or `rtk uv run python scripts/check_secrets.py` before committing to verify no plain-text secrets or passwords leak into git.
- **Explicit Staging**: Never use `git add .` when untracked secret files exist; stage explicitly by name.
<!-- sensitive-information-protection-end -->
<!-- rtk-begin -->
## RTK Command Guidelines
Prefix shell commands with `rtk` whenever a filter exists to save context tokens:
- **Git Operations**: `rtk git status`, `rtk git diff`, `rtk git log`, `rtk git commit`, `rtk git push`.
- **GitHub CLI**: `rtk gh issue list | cat`, `rtk gh pr status | cat` (always pipe to `cat` to bypass interactive pagers).
- **File Inspection**: `rtk ls`, `rtk read`, `rtk tree`, `rtk find`.
- **Search**: `rtk rg <pattern>` (preferred over grep).
- **Build & Tests**: `rtk test <cmd>`, `rtk err <cmd>`.
- **Tooling**: `rtk uv run <script>`, `rtk npx <cmd>`.
- **Sandbox Exception**: Inside `ctx_execute` / `ctx_batch_execute` sandbox code, skip `rtk` (only printed output enters context). Drop `rtk` when exact raw bytes or patch required (`git diff` patch).
<!-- rtk-end -->
AGENTS.md files can also be used to enable the use of other AI agents.
Enable antigravity-cli to use AGENTS.md files.
MCP Servers¶
MCP servers are used to extract information from my homelab.
GitHub MCP Server¶
The GitHub MCP Server can be used to allow Antigravity to interact with GitHub repositories.
~/.antigravity/settings.json
GITHUB_PERSONAL_ACCESS_TOKEN: This environment variable must be set with your GitHub PAT for thegithubMCP server.
proxmox-mcp-plus¶
The proxmox-mcp-plus can be used to allow Antigravity to interact with Proxmox VE.
~/tools/antigravity/pve01.config.json
{
"proxmox": {
"host": "ENC[AES256_GCM,data:p1JsfjpZkEwwp9GSbw==,iv:19OCjBzm+rggO6JDRuYLdWBAOwifDn1UZFveKFw9jvM=,tag:U0sk0ddTbhXLVlazVJBGzA==,type:str]",
"port": "ENC[AES256_GCM,data:Upli9w==,iv:85gGYw40tVWeNYdFKWrBy7zwDzXWxki7v1OeCGRCi5o=,tag:9jgzMRH1sc+ewMzlMzwH3g==,type:float]",
"verify_ssl": "ENC[AES256_GCM,data:9E3aBGY=,iv:fbkdC5uoqzBo9XMJ6C9KQ6Xiigjt3lBvL5P9VU7FXF8=,tag:LMVWTWo20yByl15lsTawHw==,type:bool]",
"service": "ENC[AES256_GCM,data:fiGp,iv:igDOzuamxL3sJ/x3qE91WkWPaEWjy17WvfIy3jPntbs=,tag:tDaHwo0D5GSjX4dbpgRYYQ==,type:str]"
},
"auth": {
"user": "ENC[AES256_GCM,data:stPJolzn/7g=,iv:QaKasMzFmAFwgdr17zPY8EpJqdvXp7t+kqFs/eBoOUI=,tag:zVZ5+MqE7bgZmSDkwbrthg==,type:str]",
"token_name": "ENC[AES256_GCM,data:FSCVnjSKyg==,iv:pf3w4QYycx0+BDg/27W6gQoGQwO3Ryon05NHin9DvkY=,tag:zg8AiEGXFLez6al1VM0RRg==,type:str]",
"token_value": "ENC[AES256_GCM,data:V34BdG52Tp6r8an037LhtkseN0RhTVr1wfaqvtDV6x+ur0p6,iv:WK0gydJJ8iSm/Y7g5Whzas6jgILdGu7okdulRBDmS+o=,tag:URAcl2W+N2s+LuQ+/NO+pw==,type:str]"
},
"logging": {
"level": "ENC[AES256_GCM,data:kRTZMao=,iv:N+qrI5sSg4vQnoNjdhKrYxbhTznSuoDNortnwMqi+ws=,tag:aP9q9fXkLPfK1ZhoGb9GHg==,type:str]",
"format": "ENC[AES256_GCM,data:edU1YRDAmNOK+WTV9zf/QfTAiFe4qIlXoj39Rz1m4I+uariJGkkmwgy6+Lqx5hyJok1/Cg==,iv:baxSMa5v8FyLrvy7fd4+Mlu+jnR/lhHgDPy48ZPWOyg=,tag:Zak82d+xqosPhGsBLyetWQ==,type:str]",
"file": "ENC[AES256_GCM,data:HVj8gPfVQ5/Yc02yjUMNgwn596RZ,iv:kHvXTf8OIAXsp/oGIecSavFvgeiQ0cpsw18AjPZvlXc=,tag:UeJ0Pw1+ZFQPY2Y1dSQ8pw==,type:str]"
},
"sops": {
"age": [
{
"recipient": "age1x2at6wwq2gks47fsep9a25emdeqd93e3k0gfsswtmhruqrteu5jqjvy7kd",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2ZmFHNEVoTGdvUTN1dnNW\nd0ZHSThxWFZRNW1GdldMU1hlU0pTVHBkUFcwCkxRK05vdkxWSVNuVVJtZVllWXlE\nQWpWL212RTZKM0ZIbU5MOG5NSDVNNUkKLS0tIHlMTDlhN2Q5T2swRTFqbGdIQm9h\nSU94Q3ZONENQVVBqejJaYTV0NnVmUFUKlhwFiEVav0Zt3dT4Bfht8FlqQmjGg03b\nmGi/LBqf5BSVhOyxAf8Z2Fd8PnMrm+4SumUUXYOik/TXRs57blycwg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-01-03T05:07:08Z",
"mac": "ENC[AES256_GCM,data:5z6FRCjmME6KTEJALOrfyaQbB0Su8NI07+i2lFIrWRqeyRPjTV1HvkJYuR/G26wk20Le92+Q1+C7YdhevXuKEHQe5J8Gmyt+J4TexSP+X1b8S5/3Dg4ZQ3Qm5kJNjcaO/z5caYMz+AfxYM8OEldVggaMtzHD123KAwuTi8bsuxc=,iv:rRiqQpN5AkocheMoi1BPVAjJuZcEydjUM4n8iTTrZ+k=,tag:qLSMV452n4/ME1yneRjoMg==,type:str]",
"pgp": [
{
"created_at": "2026-01-03T05:07:08Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhF4D9lXjpzPw+n0SAQdAUQb8DdMYWe+BKI8Iz6oZzGPOCdebP+o/ANdSLbU3MhIw\nyfwKA8x+lVWzAFDoAPnoVGEDmExBokfBPFAoOOGB3Ic8kIyoxDupfHBiILF/3RDf\n0l4BdrKmEY+okJ+Dz/V3yOUKBJSKsJ3JaQv9vxz609GmcMMUcuSQLcPmKah9hMKZ\n8GZ3vOhgFMD+lGiQgXNw0jbY70gq0PB4LRIbweCutYEJguoSez9v7FFAZypY9lWc\n=9eJb\n-----END PGP MESSAGE-----",
"fp": "78E2E084522FB8A14C0D9AED800C8DB8B299A622"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.11.0"
}
}
~/.antigravity/settings.json
{
"mcpServers": {
"pve01": {
"command": "${HOME}/.local/share/uv/tools/proxmox-mcp/bin/python",
"args": ["-m", "proxmox_mcp.server"],
"env": {
"PROXMOX_MCP_CONFIG": "${HOME}/git/nicholaswilde/homelab/tools/antigravity/pve01.config.json"
}
},
"pve04": {
"command": "${HOME}/.local/share/uv/tools/proxmox-mcp/bin/python",
"args": ["-m", "proxmox_mcp.server"],
"env": {
"PROXMOX_MCP_CONFIG": "${HOME}/git/nicholaswilde/homelab/tools/antigravity/pve04.config.json"
}
}
}
}
Build and Load¶
The Docker image for proxmox-mcp-plus needs to be built and loaded manually.
UniFi Network MCP¶
The UniFi Network MCP allows Antigravity to interact with UniFi Network controllers.
~/.antigravity/settings.json
Tip
To find the UNIFI_SITE value, check the URL in the UniFi GUI. For example, in https://unifi.l.nicholaswilde.io/network/154bj8wf/dashboard, the site ID is 154bj8wf.
AdGuard Home MCP¶
The AdGuard Home MCP allows Antigravity to interact with AdGuard Home for DNS management.
~/.antigravity/settings.json
Home Assistant MCP¶
The Home Assistant MCP allows Antigravity to interact with Home Assistant for IoT device control.
Activation¶
- Add Integration: Go to your Home Assistant instance, navigate to Settings -> Devices & Services, and click Add Integration. Search for "Model Context Protocol" and add it.
- Generate Token: Click on your user profile icon in the bottom left corner of the sidebar. Scroll down to the "Long-Lived Access Tokens" section and click Create Token. Give it a name (e.g., "Antigravity MCP") and copy the generated token.
~/.antigravity/settings.json
Nanobanana MCP¶
The Nanobanana MCP is used to watch for repository commit updates.
~/.antigravity/settings.json
Theme¶
The Catppuccin theme can be used to customize the appearance of the Antigravity CLI.
- Download the mocha flavor of the Catppuccin theme.
- Add the
themeproperty to yoursettings.jsonfile.
Usage¶
Once installed and authenticated, start interacting with Antigravity from the shell. See Antigravity CLI Commands for custom commands available in this project.
Example
Pipe content to the CLI from stdin
UniFi Network MCP
List Models¶
References¶
- https://github.com/nicholaswilde/antigravity-cli
- https://github.com/nicholaswilde/proxmox-mcp-plus
- https://github.com/sirkirby/unifi-network-mcp
- https://github.com/fcannizzaro/mcp-adguard-home
- https://github.com/zhongweili/nanobanana-mcp-server
- https://github.com/nicholaswilde/dotfiles2/blob/main/.antigravity/settings.json