Session awareness
Every connection is a named session the daemon can see. When a file changes underneath an agent, one call names who wrote it, what they touched and when. A baffling failure becomes an obvious write race.
Plumb gives AI coding agents real IDE intelligence from the language servers your editor trusts, plus the write-safety to share a repository: with each other, with your cron jobs, and with you.
With native tools, the last write silently wins; and the first agent keeps reasoning about code that no longer exists. Through plumb, the same race resolves itself:
read_file internal/auth/token.go · mtime captured in the response headeredit_file token.go · per-path lock, atomic temp-file → renamelandededit_file token.go with expected_mtime from its read; the file changed underneath itrejected; stale readworkspace_sessions · “topology-fix wrote token.go one second ago”explainedNothing corrupted, nothing silently overwritten, no human untangling. Per-path locks, optimistic concurrency, atomic transactions, session isolation; the substrate agent fleets are missing.
One warm daemon serves every conversation, so plumb assumes it can die. plumb serve is a reconnecting proxy that sits between your agent and the daemon:
kill -9, no warningdownAnd the rest of the envelope: scoped read-only and read-write roots, tiered git gating, per-session rate limits; a write outside the workspace is refused by construction, and destructive git needs explicit opt-in plus a per-call confirmation.
One file from plumb's own source; internal/cli/pool.go, the daemon's language-server pool. The same file, opened three ways.
read_symbol pulls just release(), while file_outline gives the map of the file without every body. The byte counts are one concrete signal of the broader efficiency pattern.wc -c for the source file, plus the byte length of live file_outline and read_symbol responses, headers included. Treat the numbers as an inspectable example, not a promised saving. Real results vary by model, file shape and task: an agent changing a whole file should read the whole file; an agent orienting itself often needs the outline first; an agent editing one function can usually start with that symbol. Reproduce it on your own repo by comparing file_outline, read_symbol, and a full file read.A living semantic graph of the repo in SQLite/FTS5. Ranked search, blast-radius, and the exact tests to run after a change; in milliseconds, mid-refactor, no language server needed. While rust-analyzer spends minutes warming, the map already answers.
The same language servers your editor trusts: real go-to-definition, every reference, scope- and type-aware rename. Answers from the compiler's model of your code; never pattern-matched guesses. Warm in one shared daemon, across every conversation.
Plumb speaks to real language-server binaries. If the server is installed, the daemon can keep it warm and route files to it; topology stays available while heavier servers wake up.
| language | server | tier | active |
|---|---|---|---|
| Go | gopls | first-class | ready |
| Python | pyright | first-class | ready |
| Java | jdtls | validated | ready |
| Rust | rust-analyzer | validated | ready |
| Swift | sourcekit-lsp | validated | ready |
| TS/JS | typescript-language-server | experimental | install-gated |
| Zig | zls | experimental | install-gated |
| Kotlin | kotlin-language-server | experimental | install-gated |
| HTML | vscode-html-language-server | experimental | install-gated |
PATH = active · [lsp.<lang>] enabled = false to excludeFifty structured tools, grouped by what they let an agent actually do; and the agent rarely has to name one, because the right tool surfaces when it's needed.
* Plumb’s own additions; session awareness, atomic transactions, blast-radius mapping; drawn out below.
Every connection is a named session the daemon can see. When a file changes underneath an agent, one call names who wrote it, what they touched and when. A baffling failure becomes an obvious write race.
Edits across many files apply as one unit, under per-path locks. Any rejection rolls the whole batch back and names the failing edit. The repo never holds a half-applied change.
The topology index traces what a change touches; callers, dependents, and the precise test files to run; in milliseconds, even while the code won't compile.
Every conversation runs its own lightweight plumb serve; they all share one daemon that keeps the language servers, locks, index and memory warm across every chat; and across every crash.
serve respawns it and replays the MCP handshake; the agent keeps its stdio open.Plumb's users aren't only people; they're the coding agents that work through it every day. Drawn from real agent sessions and end-of-session reviews.
The hero tool when three agents share one repo.
A build went red on a symbol I never wrote. workspace_sessions showed a peer had edited the file 30 seconds earlier; a baffling failure became an obvious write race.
One call later, fully oriented.
The MCP initialize response told me exactly what to do; call session_start first. One call, and I had the full git status, active diagnostics, and project memories. The most frictionless setup I've met as a CLI agent.
It thinks like a daemon, not a blocking hook.
Background analysis, coalesced work, and differential findings that show up only when they're useful. Plumb makes code quality visible without turning every edit into a full lint gate.
A 780-line file in a few hundred tokens.
One file_outline gave me the whole shape: 90 symbols, signatures only, without reading a single body.
A review can stay narrow and still feel complete.
I inspected the exact commit, verified the current imports, confirmed an intentional duplicate, and ran only the affected package tests. Plumb kept the whole pass focused and evidence-backed.
All-or-nothing edits that name what failed.
A batch of 8–13 edits applies atomically; on rejection it named the exact failing index and confirmed the file was otherwise untouched. That's the right default.
The git safety I didn't know I needed.
With unrelated work in the tree, typed git add with explicit paths let me stage and commit only my changes; a messy multi-task session became one surgical commit.
Surviving a hostile working tree.
Another agent was editing the same file under me. plumb's mtime-header guard caught the stale read before I clobbered anything, and workspace_sessions told me exactly who was there.
plumb setup wires up Claude, Codex, Gemini, Cursor and seven more for you; no JSON to hand-edit. And because plumb is a standard MCP server, any client that speaks the protocol can connect; these eleven just skip the setup.
One plumb setup <client> per agent; or point any MCP client at the daemon yourself.
# 1 · install the binary · Homebrew, macOS + Linux $ brew install plumbkit/plumb/plumb # or: go install github.com/plumbkit/plumb/cmd/plumb@latest # 2 · connect your assistant $ plumb setup claude-code # 3 · optional; pin the root & enable project config $ cd my-project && plumb init ✓ ready; your agents now share one safe workspace
Run plumb tui for an operations view of everything plumb is doing at once: every active session and the file it is touching, per-tool latency, error rates and token efficiency, and the daemon's own CPU, memory, GC and goroutines; the one warm process behind every conversation.