Catenary
Health Warn
- License — License: AGPL-3.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 8 GitHub stars
Code Fail
- rm -rf — Recursive force deletion command in .github/workflows/conformance.yml
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Giving AI coding agents LSP-powered code intelligence.
Catenary
Catenary hands an AI coding agent a small, opinionated set of
code-intelligent commands — and a hook that keeps it on them. Reach forgrep and you're redirected to catenary grep; reach for ls or find
and you get catenary glob. Every command the agent can run is backed by a
language server, so it navigates code by meaning instead of brute-forcing
text. The generic path isn't blocked for safety — it's off the menu, so
the code-intelligent one is the only path left.
Why Catenary
Exposing language-server tools to an agent isn't novel anymore — most
coding CLIs do it, and Catenary did it early. But having a tool and
using it are different things. Give an agent grep, find, raw file
reads, and LSP navigation, and it reaches for whatever's nearest —
usually brute-force text scanning that burns context and misses structure.
Catenary takes the choice away. It exposes one curated, code-intelligent
surface and enforces it:
- A
PreToolUsehook runs an allowlist over every shell command the
agent issues. - Denied commands aren't dead ends — each denial names the
code-intelligent command to run instead (grep→catenary grep,ls/find→catenary glob). - Edits flow through the host's tracked Edit/Write tools, so LSP
diagnostics come back automatically when the agent runscatenary diagnostics.
The result is a workflow the agent follows by construction, not by
prompt-engineering.
This is enforcement of a workflow, not a security sandbox. The hook is
a cooperative contract — a Makefile can still run anything, and Catenary
doesn't isolate the filesystem or environment. Its job is narrower and
more useful: keep the agent's reads on code-intelligent search and its
writes on a tracked path, so navigation is structural and diagnostics are
free.
Less context, more signal
A grep-and-read loop pulls whole files into the agent's context window and
re-processes them every turn. catenary grep answers with the symbol, its
signature, and where it's used — tens of tokens instead of thousands.
Diagnostics arrive through catenary diagnostics stdout, so the agent
never re-reads a file just to check whether its edit compiled.
The surface
Search — always available, no setup beyond installation:
| Command | What it does |
|---|---|
catenary grep <pattern> |
Symbol, reference, and text search — LSP-enriched within tracked roots |
catenary glob <path> |
File outlines, directory listings, glob matches |
The edit → diagnostics loop — run in the host's shell tool:
# Edit files with the host's native Edit/Write tools. Editing starts
# automatically on the first change to a server-covered file — there is
# no start step.
catenary diagnostics # print LSP diagnostics for every file you
# touched, then clear the set
catenary diagnostics is the end of an edit batch: it opens the
modified files on their servers, waits for each to settle, and prints the
errors and warnings — like a linter, it's silent on success. For sweeps
too broad for per-file edits, reach for native sed -i — the hook
resolves its write-set and folds the changed files into the same
diagnostics batch.
Workspace roots — manage which directories are indexed:
catenary roots add <path> # index a directory
catenary roots rm <path>
catenary roots ls
How it fits together
One daemon per host manages a shared pool of language servers. Multiple
agents connect over a Unix socket and share those servers — a singlerust-analyzer serves every session on the same project. Catenary reaches
the agent through four decoupled surfaces; none depends on the others.
agents ──▶ Catenary daemon ──▶ shared LSP server pool
rust-analyzer · pyright · gopls · …
reached through four decoupled surfaces:
CLI grep · glob · diagnostics — via the host's shell tool
Hooks allowlist enforcement — one PreToolUse hook
MCP heartbeat + workspace roots — no query tools
TUI live observability — protocol & trace traffic
- CLI — the code-intelligent commands above, invoked through the
host's shell tool. Stateless: each command connects to the daemon,
delegates to the right language servers, and prints to stdout. - Hooks — the
PreToolUseallowlist that enforces the workflow and
tracks edited files for the diagnostics batch. - MCP — a heartbeat only: the protocol handshake, the workspace-roots
channel, and user-facing notifications. It advertises no query tools. - TUI — real-time observability across every session and language
server.
Quick Start
1. Install
Homebrew (macOS and Linux):
brew install twowells/tap/catenary
Switching from a
cargo install(the previously recommended path)?
Runcargo uninstall catenary-mcpfirst —~/.cargo/binusually
precedes brew's bin dir onPATH, so the stale binary keeps
answering otherwise.
Prebuilt binary (Linux x86_64 / macOS arm64):
curl -fsSL https://raw.githubusercontent.com/TwoWells/Catenary/main/install.sh | sh
From source (any platform with a Rust toolchain):
cargo install catenary-mcp
The catenary binary must be on your PATH before configuring any
client. Plugins and extensions provide hooks and the MCP declaration but
do not include the binary — this step is required.
Upgrading from 1.x? Every breaking change in 2.0 is to user
configuration — read the
migration guide
before upgrading, and runcatenary doctorafter: it flags each stale
config form with the exact rename.
2. Configure language servers
Add your language servers to ~/.config/catenary/config.toml:
# The [lsp.server.*] section key IS the binary Catenary spawns; bind a
# language to it under [lsp.language.*]. Add `path = "/abs/path"` only to
# relocate a binary that is not on PATH.
[lsp.server.rust-analyzer]
[lsp.server.pyright-langserver]
args = ["--stdio"]
[lsp.language.rust]
servers = ["rust-analyzer"]
[lsp.language.python]
servers = ["pyright-langserver"]
Catenary can install the servers itself. Opt in with:
[servers]
auto_install = true
Any configured server that has passed Catenary's conformance gate is then
installed at its vetted, pinned version into a Catenary-owned directory —
in the background, at session start, with no per-server install step.
Servers already on PATH are left alone. The opt-in is honored from your
user config only; a project .catenary.toml can never switch it on.
(catenary install is unrelated: it installs host plugins, not language
servers.)
3. Connect your agent
Claude Code
claude plugin marketplace add TwoWells/Catenary
claude plugin install catenary@catenary
Antigravity CLI — copy plugins/catenary-antigravity/ to.agents/plugins/catenary/ in your workspace.
4. Verify
catenary doctor
doctor reports each configured server's status (ready, command not found, spawn failed, initialize failed) and whether the host's hooks
are installed and current. Managed installs count as installed, and a
system-installed server whose version drifts from the vetted pin draws an
advisory finding naming both versions. Pass a server name (catenary doctor rust-analyzer) for verbose single-server diagnostics.
Observability
Run catenary in a terminal to launch the TUI dashboard — a live view of
every session, every language server, and the protocol traffic between
them. Catenary keeps a state.json snapshot of live state and streams
full protocol and trace detail to a sharded JSONL telemetry firehose; the
TUI reads the snapshot, and catenary query reads the firehose. (There is
no SQLite database — a legacy one is drained on startup.)
| Command | Description |
|---|---|
catenary |
Launch the TUI dashboard |
catenary query |
Query the telemetry firehose (by session, server, tool, time, …) |
catenary doctor |
Verify language servers and hook installation |
catenary version |
Show the CLI and running-daemon versions |
catenary stop |
Stop the running daemon |
Documentation
Full documentation at twowells.github.io/Catenary
- Installation — setup for Claude Code and Antigravity CLI
- Configuration — language servers, routing, command allowlist
- CLI & Dashboard — the command surface and TUI dashboard
License
AGPL-3.0-or-later — see LICENSE for details.
Commercial licensing available for proprietary use — see
LICENSE-COMMERCIAL. Contact [email protected].
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found