Catenary

mcp
Security Audit
Fail
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.

SUMMARY

Giving AI coding agents LSP-powered code intelligence.

README.md

Catenary

CI
CD

github_catenary_hero_image

Catenary hands an AI coding agent a small, opinionated set of
code-intelligent commands — and a hook that keeps it on them. Reach for
grep 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 PreToolUse hook 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
    (grepcatenary grep,
    ls/findcatenary glob).
  • Edits flow through the host's tracked Edit/Write tools, so LSP
    diagnostics come back automatically when the agent runs catenary 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 single
rust-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 PreToolUse allowlist 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)?
Run cargo uninstall catenary-mcp first — ~/.cargo/bin usually
precedes brew's bin dir on PATH, 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 run catenary doctor after: 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

License

AGPL-3.0-or-later — see LICENSE for details.

Commercial licensing available for proprietary use — see
LICENSE-COMMERCIAL. Contact [email protected].

Reviews (0)

No results found