46+ built-in agent tools, part 1: files, search, git, and the web
More tools don't make a better agent. Rysh's rule: a tool earns a slot only when it beats bash. Here's the working half of the toolbox.
Here's an unpopular opinion from a company whose homepage says "46+ built-in agent tools": tool count is a vanity metric.
Every agent platform brags about tool count. But an agent with a hundred overlapping tools is worse than one with a sharp toolbox — every redundant tool is another way to pick the wrong one, another chunk of context window spent on schemas, another decision the model can fumble.
So rysh's toolset is governed by one ruthless rule:
A tool earns a slot only when it offers something
bashcannot.
The agent already has a shell. If bash can do the job cleanly, the job belongs to bash, with guidance in the system prompt. A dedicated tool has to justify itself with at least one of: structured output a program can parse, preview/approval safety, secret redaction, cross-pane coordination, or a genuinely distinct modality. Across the whole platform that discipline still adds up to 46+ tools — this post tours the single-agent half: files, search, git, code intel, environment, testing, and the web. (Part 2 covers the coordination and memory tools — the ones no single-agent CLI has.)
Files: where safety pays the rent
file_read— read a file, with sane limits so one giant file doesn't flood the context window.edit— targeted change: one exact old/new string pair, or an atomic batch of edits to a file. Old text must match exactly and uniquely — no fuzzy matching its way into the wrong block.file_write— create or replace a whole file.
Why not sed and cat > file via bash? Because writes deserve ceremony. edit and file_write are preview-first: the change is rendered as a coloured diff in your pane and waits for your approval before disk changes. You can't build that guarantee on ad-hoc shell writes — which is exactly why file mutation gets tools and file plumbing doesn't.
Search: structured, fast, boring
glob— find files by pattern.grep— find content by regex, results structured for an agent to iterate.
These earn slots by being the highest-frequency calls an agent makes. Investigating a bug is 80% search; giving those calls predictable, parseable output makes every downstream step cheaper.
Git: reads are free, commits are ceremony
Here's the consolidation rule in action. Rysh has exactly one dedicated git tool: git_commit — and it's always approval-gated, because writing history is a decision with your name on it.
Everything else — git status, git diff --color=always, git log, git show — is just bash, and runs prompt-free under the read-only allowlist. There is no git_status tool, no git_diff tool. They'd be wrappers around things the shell already does perfectly. Slots denied.
Code intelligence: one tool, one job
symbol_search— find where a symbol is declared, not just where its name appears.
Grep tells you a string occurs in 40 places; symbol_search tells you which one is the declaration. That's a real modality difference — grep can't know the difference between a definition and a call site. One tool, no overlap. (Directory trees? ls, tree, find — bash.)
Environment: the redaction tool
env_read— read environment variables with secrets redacted before the value ever reaches the model.
This one's the clearest example of the earning-a-slot rule. printenv via bash would happily hand your AWS_SECRET_ACCESS_KEY straight into an LLM conversation. env_read exists precisely so that path is safe: the agent learns the variable exists and its shape, without the value leaving your machine. You cannot retrofit that onto raw shell. (Process and port inspection, meanwhile: ps, lsof — bash.)
Testing: structured results beat scrollback
test_run— run tests and get structured results: what ran, what failed, where.
The consumer of test output is often not you — it's the agent's next step. Structured failures mean the agent goes straight from "these 2 tests failed in pane_group_test.go" to reading the right file, instead of regex-parsing 400 lines of scrollback. Lint and builds, by contrast, stay in bash (go vet, go build, golangci-lint): their output is already terse enough.
The web: a different modality entirely
web_search— search the live web.web_fetch— fetch and read a page.
Bash genuinely can't do this well (curl gives you HTML soup and no search). Fresh docs, changelogs, error messages from three weeks ago — this is how an agent escapes its training cutoff.
The takeaway
Look at the pattern across every family: plumbing goes to bash, and tools exist where they buy safety, structure, or reach. Approval-gated writes. Redacted env reads. Parseable tests. Live web. The rest rides the shell, governed by the same allowlist that keeps mutating commands behind a human.
All of it runs on Claude, with your own API key, on your own machine — rysh is self-hostable, and every tool call is visible in the pane as it happens.
A sharp toolbox, not a big one. Part 2 is where it gets unusual: tools that let agents inspect each other's panes, message each other, and share memory across a workspace.
Opinionated about agent tooling? So are we — come argue with the founders directly as a design partner: rysh.ai/design-partner.
More in this series: 46+ built-in agent tools, part 2: cross-pane coordination and shared memory · The bash allowlist: safe-by-default shell execution for agents