Binsmith
An agent that accumulates small CLI tools in a persistent workspace.
Most chat-style agents are “stateless” in the sense that they don’t leave behind reusable artifacts. Binsmith is configured to turn repeated work into scripts and keep them under workspace/bin (by default ~/.binsmith/workspace/bin), so later tasks can compose existing tools instead of re-solving the same problem.
Binsmith is distributed as a Lattis plugin.
Quick start
export GOOGLE_API_KEY=... # see below for other providers uvx binsmith
This starts a local server and opens the TUI. A web UI is also available at http://localhost:8000 while running.
By default, Binsmith uses a global data directory at ~/.binsmith/ so your tools carry across projects. To keep
storage in the current project directory, run uvx binsmith --project (stores data in .binsmith/).
If you run Binsmith via uvx lattis --agent binsmith, storage follows your Lattis configuration (LATTIS_* env vars).
This does not change where commands run: the agent still runs shell commands in the project directory.
To run the server only (no TUI):
uvx binsmith server
# Open http://localhost:8000 for the web UIOr run via Lattis alongside other agents:
uv pip install binsmith uvx lattis --agent binsmith
What it does
Binsmith is an agent prompt + a workspace.
- It runs commands using a single tool:
bash - Your project workspace has
workspace/binon the PATH - When a task is worth repeating, it writes a script into
workspace/bin - Those scripts persist across sessions and can call each other (Unix-style)
- It can symlink tools into a user-writable bin directory on your PATH (see Configuration)
Over time you end up with a small toolkit of scripts you and the agent can both use.
Example (tools invented over time; names illustrative):
fetch-url https://news.ycombinator.com | html2md | summarize --bullets brief todo add "Review PR #42"
Workspace layout
~/.binsmith/
workspace/
bin/ # Scripts Binsmith creates (persists across sessions)
data/ # Persistent data files
tmp/ # Scratch space
Script format
Scripts are intended to be standalone and “git-friendly”. Python scripts use uv inline metadata so dependencies are declared in the file:
#!/usr/bin/env -S uv run --script # /// script # requires-python = ">=3.12" # dependencies = ["httpx"] # /// """Fetch a URL and extract text content."""
Tool conventions
Binsmith is prompted to keep tools composable and discoverable:
- Prefer stdin/stdout for data flow
- Produce clean text output by default
- Support
--jsonwhen machine-readable output makes sense - Support
--helpand optionally--describe - Exit
0on success, non-zero on failure - Reuse or extend existing tools instead of creating near-duplicates
The point is to make workflows like fetch-url | html2md | summarize viable.
How it works (mechanics)
Binsmith is “just” an agent configuration:
- It can run shell commands inside the project directory
- It can see what’s already in
workspace/bin - It is instructed to:
- use existing scripts when possible
- write scripts when you hit repetition
- improve existing scripts rather than cloning variants
Lattis handles the server, UIs, thread persistence, and session state.
Remote usage
A common setup is to run the server on a machine that stays up and connect from anywhere:
# On the server uvx binsmith server --host 0.0.0.0 # From a client machine (TUI) uvx binsmith --server http://your-server:8000 # Or open http://your-server:8000 in a browser for the web UI
(If you bind to a public interface, keep it on a private network / VPN.)
Interfaces
Binsmith provides two interfaces, both connecting to the same server and sharing threads:
- TUI — Terminal interface, launched by default with
uvx binsmith - Web UI — Browser interface at http://localhost:8000
TUI commands
/help Show help
/threads List threads
/thread <id> Switch to thread
/thread new [id] Create new thread
/thread delete <id> Delete thread
/clear Clear current thread
/model Show current model
/model list [filter] List models
/model set <name> Set model
/quit Exit
Configuration
| Variable | Default | Description |
|---|---|---|
BINSMITH_MODEL |
google-gla:gemini-2.0-flash |
Default model |
BINSMITH_LOGFIRE |
0 |
Enable Logfire telemetry |
BINSMITH_LINK_BINS |
1 |
Link tools into a writable PATH directory |
BINSMITH_BIN_DIR |
Override the link directory (should be on your PATH) |
Binsmith CLI flags:
--global(default) — store data in~/.binsmith/--project— store data in.binsmith/under the current directory
Binsmith only links tools when it can find a writable PATH directory under your home folder, and it skips names
that already resolve on PATH to avoid shadowing existing commands. Set BINSMITH_BIN_DIR to control the link
location when you want a specific directory.
When auto-picking a link directory, Binsmith prefers ~/.local/bin (then ~/bin) if present on your PATH, and
it avoids linking into the Binsmith workspace bin/ directory or an active virtualenv’s bin/.
Lattis configuration (LATTIS_*) controls storage and server settings.
Requirements
- Python 3.12+
- uv
- An API key for at least one model provider
export GOOGLE_API_KEY=... # Google export ANTHROPIC_API_KEY=... # Anthropic export OPENAI_API_KEY=... # OpenAI
Why the name
It forges tools into bin/.