Introduction
agsh (agentic shell) is a shell where you type natural language instead of commands. An LLM interprets your instructions and executes them using built-in tools like file operations, search, web access, and shell command execution.
agsh [r] > find all Rust files in this project and count the lines of code
Instead of remembering find . -name '*.rs' | xargs wc -l, you describe what you want and the agent figures out how to do it.
Features
- Natural language interface – describe what you want instead of memorizing syntax
- Built-in tools – file read/write/edit, glob search, regex content search (ripgrep), web fetch, web search, shell command execution
- Multiple LLM providers – OpenAI and Anthropic, with support for any OpenAI-compatible API
- Permission system – control what the agent can do (none/read/write), switchable mid-session
- Session management – conversations are persisted in SQLite; resume any session later
- Streaming output – responses stream to the terminal in real time, rendered as Markdown
- Interactive and one-shot modes – use it as a REPL or pipe a single prompt
How It Works
- You type a natural language instruction
- agsh sends it to the configured LLM along with tool definitions and a system prompt
- The LLM decides which tools to call (if any) and returns text and/or tool calls
- agsh executes the tool calls, feeds results back to the LLM, and repeats until the LLM is done
- The final response is rendered as Markdown in the terminal
Installation
agsh is written in Rust and builds as a single binary.
Pre-Built Binaries
Download the latest release for your platform from the GitHub Releases page.
| Platform | Archive |
|---|---|
| Linux (x86_64) | agsh-linux-amd64.tar.gz |
| macOS (Apple Silicon) | agsh-macos-arm64.tar.gz |
| Windows (x86_64) | agsh-windows-amd64.zip |
Extract the binary and place it somewhere on your $PATH:
# Linux/macOS
tar -xzf agsh-*.tar.gz
cp agsh ~/.local/bin/
Cargo Install
If you have Rust installed, you can install agsh directly from the Git repository:
cargo install --git https://github.com/k4yt3x/agsh.git
This builds the latest version from source and installs it to ~/.cargo/bin/.
Building from Source
Prerequisites
- Rust (edition 2024, requires Rust 1.85+)
- A C compiler (for the bundled SQLite)
Build
git clone https://github.com/k4yt3x/agsh.git
cd agsh
cargo build --release
The binary will be at target/release/agsh. Copy it somewhere on your $PATH:
cp target/release/agsh ~/.local/bin/
Verify
agsh --version
agsh --help
Quick Start
1. Create a Config File
Create ~/.config/agsh/config.toml with your provider settings:
OpenAI:
[provider]
name = "openai"
base_url = "https://openrouter.ai/api/v1"
api_key = "sk-or-v1-..."
model = "anthropic/claude-opus-4.6"
Anthropic:
[provider]
name = "anthropic"
model = "claude-opus-4.6"
api_key = "sk-ant-..."
See Configuration for all options including custom endpoints.
You can also use environment variables (
OPENAI_API_KEY,AGSH_PROVIDER, etc.) or CLI flags (--provider,-m) as overrides. See Environment Variables and CLI Options.
2. Start the Shell
agsh
You will see a prompt:
agsh [r] >
The [r] indicates read permission mode (the default). The agent can read files and search, but cannot write files or run commands.
3. Ask It Something
agsh [r] > what files are in the current directory?
The agent will use the find_files tool to list files and describe them.
4. Enable Write Mode
Press Shift+Tab to cycle the permission to write mode:
agsh [w] >
Now the agent can execute commands and modify files:
agsh [w] > create a file called hello.txt with the text "hello world"
5. One-Shot Mode
For quick tasks without entering the interactive shell:
agsh -p "what is my current working directory?"
The process exits after the agent responds.
6. Continue a Previous Session
To pick up where you left off, continue the last session:
agsh -c
Or resume a specific session by its UUID:
agsh -s 550e8400-e29b-41d4-a716-446655440000
See Sessions for more details.
Configuration Overview
The recommended way to configure agsh is with a config file at ~/.config/agsh/config.toml:
[provider]
name = "openai"
model = "gpt-4o"
api_key = "sk-..."
This is all you need to get started. See Config File for the full reference.
Required Settings
agsh requires three settings to function. If any are missing, it prints an error with setup instructions:
| Setting | Config Key | Env Var | CLI Flag |
|---|---|---|---|
| Provider | provider.name | AGSH_PROVIDER | --provider |
| Model | provider.model | AGSH_MODEL | -m, --model |
| API Key | provider.api_key | OPENAI_API_KEY or ANTHROPIC_API_KEY | – |
Override Layers
Configuration is layered. Higher-priority layers override lower ones:
- CLI flags – per-invocation overrides (
--provider,--model,--base-url,-p) - Environment variables – useful for CI, containers, or temporary overrides (
AGSH_PROVIDER, etc.) - Config file – persistent settings in
~/.config/agsh/config.toml - Built-in defaults – permission defaults to
read, streaming defaults to on
For example, --model gpt-4o-mini on the command line overrides both AGSH_MODEL and provider.model in the config file.
API Key Resolution
The API key environment variable depends on the configured provider:
- Provider
openai: readsOPENAI_API_KEY - Provider
anthropic: readsANTHROPIC_API_KEY
If the environment variable is not set, it falls back to provider.api_key in the config file.
Config File
agsh looks for a TOML configuration file at:
~/.config/agsh/config.toml
More precisely, it uses the XDG config directory ($XDG_CONFIG_HOME/agsh/config.toml), which defaults to ~/.config/agsh/config.toml on Linux.
The config file is optional. If it does not exist, agsh silently skips it.
Format
[provider]
name = "openai"
model = "gpt-4o"
api_key = "sk-..."
base_url = "https://api.openai.com/v1"
All fields under [provider] are optional individually – you can set some in the config file and override others with environment variables or CLI flags.
Fields
provider.name
The LLM provider to use.
| Value | Description |
|---|---|
openai | OpenAI Chat Completions API (also works with OpenAI-compatible APIs) |
anthropic | Anthropic Messages API |
provider.model
The model identifier to send to the provider. Examples:
gpt-4o,gpt-4o-mini(OpenAI)claude-sonnet-4-20250514,claude-haiku-4-5-20251001(Anthropic)- Any model supported by an OpenAI-compatible endpoint
provider.api_key
The API key for authentication. It is recommended to use environment variables (OPENAI_API_KEY or ANTHROPIC_API_KEY) instead of storing the key in the config file.
provider.base_url
Custom API base URL. Useful for:
- Self-hosted models via Ollama (
http://localhost:11434/v1) - OpenRouter (
https://openrouter.ai/api/v1) - Other OpenAI-compatible API providers
If not set, defaults to:
https://api.openai.com/v1for theopenaiproviderhttps://api.anthropic.comfor theanthropicprovider
Examples
OpenAI
[provider]
name = "openai"
model = "gpt-4o"
# API key via env: export OPENAI_API_KEY=sk-...
Anthropic
[provider]
name = "anthropic"
model = "claude-sonnet-4-20250514"
# API key via env: export ANTHROPIC_API_KEY=sk-ant-...
Ollama (local)
[provider]
name = "openai"
model = "llama3"
api_key = "unused"
base_url = "http://localhost:11434/v1"
OpenRouter
[provider]
name = "openai"
model = "anthropic/claude-sonnet-4-20250514"
base_url = "https://openrouter.ai/api/v1"
# API key via env: export OPENAI_API_KEY=sk-or-...
[web]
Settings for web-related tools (fetch_url, web_search).
web.user_agent
Custom User-Agent string for HTTP requests. Some search engines may block requests with non-browser User-Agent strings.
Default: Mozilla/5.0 (compatible; agsh/0.1)
[web]
user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
Environment Variables
The config file is the recommended way to configure agsh. Environment variables are useful as overrides – for example, in CI pipelines, containers, or when you want to temporarily switch providers without editing your config.
Environment variables override config file values but are overridden by CLI flags.
agsh-Specific Variables
| Variable | Description | Example |
|---|---|---|
AGSH_PROVIDER | LLM provider name | openai, anthropic |
AGSH_MODEL | Model identifier | gpt-4o, claude-sonnet-4-20250514 |
AGSH_PERMISSION | Default permission mode | none, read, write |
Provider API Keys
| Variable | Used When |
|---|---|
OPENAI_API_KEY | Provider is openai |
ANTHROPIC_API_KEY | Provider is anthropic |
Provider Base URL
| Variable | Description |
|---|---|
OPENAI_BASE_URL | Custom base URL for the OpenAI-compatible endpoint |
Logging
agsh uses the tracing framework. The log level can be controlled with:
| Variable | Description | Example |
|---|---|---|
RUST_LOG | Standard Rust log filter | agsh=debug, agsh=trace |
If RUST_LOG is not set, the verbosity flag (-v, -vv, -vvv) controls the level:
| Flag | Level |
|---|---|
| (none) | warn |
-v | info |
-vv | debug |
-vvv | trace |
Logs are written to stderr so they do not interfere with agent output.
CLI Options
agsh [OPTIONS]
Options
-p, --prompt <PROMPT>
Run a one-shot prompt and exit. The agent processes the prompt, prints its response, and the process terminates.
agsh -p "list all files larger than 1MB in the current directory"
-s, --session <UUID>
Resume an existing session by its UUID. The session’s message history is loaded and the conversation continues.
agsh -s 550e8400-e29b-41d4-a716-446655440000
Errors if the session does not exist or is locked by another agsh instance.
-c, --continue
Resume the most recently updated session. Equivalent to -s with the last session’s UUID.
agsh -c
--permission <MODE>
Set the initial permission mode. Accepts none (or n), read (or r), write (or w). Case-insensitive.
agsh --permission write
agsh --permission w
Default: read.
--provider <NAME>
Set the LLM provider. Overrides AGSH_PROVIDER and the config file.
agsh --provider anthropic
Supported values: openai, anthropic.
-m, --model <MODEL>
Set the model name. Overrides AGSH_MODEL and the config file.
agsh -m gpt-4o-mini
--base-url <URL>
Set a custom API base URL. Overrides OPENAI_BASE_URL and the config file.
agsh --base-url http://localhost:11434/v1
--no-stream
Disable streaming mode. The agent waits for the complete response before displaying it. By default, responses are streamed token-by-token.
agsh --no-stream
-v, --verbose
Increase log verbosity. Can be repeated up to three times.
agsh -v # info
agsh -vv # debug
agsh -vvv # trace
--help
Print help information.
--version
Print version information.
Interactive Mode
Start agsh without the -p flag to enter interactive mode:
agsh
You get a prompt:
agsh [r] >
Type your instruction and press Enter to submit. The agent processes your request and prints its response (streamed in real time as Markdown). When it finishes, you get another prompt.
Keybindings
agsh uses Emacs-style keybindings (provided by reedline).
Input
| Key | Action |
|---|---|
| Enter | Submit the current prompt |
| Alt+Enter | Insert a newline (for multi-line input) |
| Shift+Tab | Cycle the permission mode (none → read → write → none) |
Navigation
| Key | Action |
|---|---|
| Ctrl+A | Move cursor to start of line |
| Ctrl+E | Move cursor to end of line |
| Ctrl+F | Move cursor forward one character |
| Ctrl+B | Move cursor backward one character |
| Alt+F | Move cursor forward one word |
| Alt+B | Move cursor backward one word |
Editing
| Key | Action |
|---|---|
| Ctrl+D | Delete character under cursor / exit on empty line |
| Ctrl+H, Backspace | Delete character before cursor |
| Ctrl+K | Kill text from cursor to end of line |
| Ctrl+U | Kill text from start of line to cursor |
| Ctrl+W | Kill word before cursor |
| Ctrl+Y | Yank (paste) killed text |
Control
| Key | Action |
|---|---|
| Ctrl+C | Interrupt the running agent; clear the line if idle |
| Ctrl+D | Exit the shell (when the line is empty) |
| Ctrl+R | Reverse incremental search through history |
| Ctrl+L | Clear the screen |
Prompt Format
agsh [indicator] >
The indicator shows the current permission mode:
| Mode | Indicator | Color |
|---|---|---|
| None | [n] | Green |
| Read | [r] | Yellow |
| Write | [w] | Red |
The color provides a visual cue about the agent’s current capabilities. Red means the agent can modify your system.
Multi-Line Input
Press Alt+Enter to insert a newline instead of submitting. The prompt changes to show continuation:
agsh [r] > write a python script that
... prints hello world
... and saves it to hello.py
Press Enter on the last line to submit the entire multi-line input.
Shell Escape
Prefix any input with ! to execute it directly as a shell command, bypassing the LLM entirely:
agsh [r] > !pwd
/home/user/projects
agsh [r] > !ls -la
total 32
drwxr-xr-x 5 user user 4096 Mar 4 10:00 .
...
agsh [r] > !ping 1.1.1.1 -c 2
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
...
The command runs with inherited stdin/stdout/stderr, so it behaves exactly like a regular shell. This is useful for quick checks without waiting for the LLM.
Exiting
You can exit agsh in any of these ways:
- Type
exitorquit - Press Ctrl+D on an empty line
Interrupting the Agent
Press Ctrl+C while the agent is running to interrupt it. This cancels the current LLM request and kills any running shell commands that were spawned by the agent.
One-Shot Mode
One-shot mode runs a single prompt and exits, similar to bash -c:
agsh -p "your prompt here"
The agent processes the prompt (including any tool calls), prints its response, and the process terminates. The session UUID is printed to stderr on exit.
Examples
# Simple question
agsh -p "what is my current working directory?"
# File operations (requires write permission)
agsh --permission write -p "create a file called notes.txt with today's date"
# Search
agsh -p "find all TODO comments in this project"
# Web search
agsh -p "search the web for the latest Rust release"
Combining with Other Flags
All configuration flags work in one-shot mode:
# Use a specific provider and model
agsh --provider anthropic -m claude-sonnet-4-20250514 -p "explain this codebase"
# With write permission
agsh --permission write -p "run 'cargo test' and summarize the results"
# Disable streaming
agsh --no-stream -p "read README.md and summarize it"
Session Behavior
One-shot mode creates a new session for each invocation. The session UUID is printed to stderr when the run completes:
Session: 550e8400-e29b-41d4-a716-446655440000
You can resume this session later in interactive mode:
agsh -s 550e8400-e29b-41d4-a716-446655440000
Permissions
agsh uses a three-level permission system to control what tools the agent can use. This gives you control over the agent’s capabilities and prevents accidental modifications.
Permission Levels
| Level | Indicator | Allowed Tools |
|---|---|---|
| None | [n] (green) | No tools. The agent can only respond with text. |
| Read | [r] (yellow) | Read-only tools: read_file, find_files, search_contents, fetch_url, web_search |
| Write | [w] (red) | All tools, including: write_file, edit_file, execute_command |
Each level includes all tools from the levels below it. Write mode includes all read tools.
Default Permission
The default permission is read. You can change it with:
- CLI flag:
agsh -p write - Environment variable:
export AGSH_PERMISSION=write
Changing Permissions at Runtime
Press Shift+Tab to cycle through permission levels:
none → read → write → none → ...
The prompt indicator updates immediately to reflect the new level. The agent is informed of the current permission level in its system prompt, so it knows which tools are available.
How Permissions Work
When the agent attempts to use a tool, agsh checks whether the current permission level allows it:
- If allowed, the tool executes normally.
- If denied, agsh returns an error message to the agent explaining that the tool requires a higher permission level.
The agent is also instructed (via the system prompt) to inform you if it cannot perform a requested action due to permission restrictions and to suggest pressing Shift+Tab to change the level.
Examples
Read Mode (Default)
agsh [r] > read the contents of main.rs
The agent uses read_file and shows the contents. If you ask it to modify a file:
agsh [r] > add a comment to the top of main.rs
The agent will explain that it cannot write files in read mode and suggest switching to write mode.
Write Mode
agsh [w] > run cargo test and show me the output
The agent uses execute_command to run the tests and shows the results.
Sessions
Sessions persist your conversation history so you can resume later. Each session is identified by a UUID and stored in a SQLite database.
How Sessions Work
- A session is not created when agsh starts. It is created lazily when you send the first message.
- When a session is created, its UUID is printed to stderr.
- When you exit agsh (Ctrl+D), the session UUID is printed again so you can note it for later.
- Sessions include the full message history: your inputs, the agent’s responses, and tool call results.
Resuming a Session
By UUID
agsh -s 550e8400-e29b-41d4-a716-446655440000
The agent loads the previous conversation history and continues from where you left off.
Continue Last Session
agsh -c
This resumes the most recently updated session.
Session Locking
Only one agsh instance can be attached to a session at a time. This prevents race conditions from concurrent writes.
- If you try to resume a session that is locked by a running agsh process, you will get an error.
- If the locking process has exited (crashed or was killed), agsh detects this and allows you to take over the lock.
Storage Location
Sessions are stored in a SQLite database at:
~/.local/share/agsh/sessions.db
This follows the XDG Base Directory Specification ($XDG_DATA_HOME/agsh/sessions.db).
Database Schema
The database has two tables:
sessions – one row per session:
| Column | Type | Description |
|---|---|---|
id | TEXT (UUID) | Primary key |
created_at | TEXT (RFC 3339) | When the session was created |
updated_at | TEXT (RFC 3339) | When the session was last updated |
locked_by | TEXT (PID) | PID of the process holding the lock, or NULL |
metadata | TEXT | Reserved for future use |
messages – one row per message in a session:
| Column | Type | Description |
|---|---|---|
id | INTEGER | Auto-incrementing primary key |
session_id | TEXT (UUID) | Foreign key to sessions.id |
role | TEXT | user, assistant, or tool_results |
content | TEXT | Message content (plain text or JSON) |
created_at | TEXT (RFC 3339) | When the message was saved |
Managing Sessions
Session management is done directly through the SQLite database. For example, to list all sessions:
sqlite3 ~/.local/share/agsh/sessions.db \
"SELECT id, created_at, updated_at FROM sessions ORDER BY updated_at DESC;"
To delete a session and its messages:
sqlite3 ~/.local/share/agsh/sessions.db \
"DELETE FROM messages WHERE session_id = '550e8400-...';
DELETE FROM sessions WHERE id = '550e8400-...';"
Providers Overview
Providers are the LLM inference backends that agsh uses to process your instructions. agsh ships with two built-in providers:
| Provider | API | Streaming | Tool Calling |
|---|---|---|---|
| OpenAI | Chat Completions | SSE | Function calling |
| Anthropic | Messages API | SSE (named events) | Content blocks |
Selecting a Provider
Set the provider via any configuration layer:
# CLI flag
agsh --provider openai
# Environment variable
export AGSH_PROVIDER=anthropic
# Config file (~/.config/agsh/config.toml)
[provider]
name = "openai"
OpenAI-Compatible APIs
The openai provider works with any API that implements the OpenAI Chat Completions format. This includes:
- OpenAI (default endpoint)
- Ollama (
http://localhost:11434/v1) - OpenRouter (
https://openrouter.ai/api/v1) - vLLM, LiteLLM, and other OpenAI-compatible servers
Set the --base-url flag or OPENAI_BASE_URL environment variable to point to the alternative endpoint.
Streaming vs Non-Streaming
By default, agsh uses streaming mode: tokens appear in the terminal as they are generated. Use --no-stream to wait for the complete response before displaying it.
Streaming is recommended for interactive use. Non-streaming may be useful for scripting or when the provider does not support SSE.
OpenAI Provider
The OpenAI provider uses the Chat Completions API. It also works with any OpenAI-compatible API endpoint.
Configuration
| Setting | Value |
|---|---|
| Provider name | openai |
| Default base URL | https://api.openai.com/v1 |
| API key env var | OPENAI_API_KEY |
| Auth method | Bearer token (Authorization: Bearer <key>) |
Minimal Setup
export AGSH_PROVIDER=openai
export AGSH_MODEL=gpt-4o
export OPENAI_API_KEY=sk-...
agsh
Config File
[provider]
name = "openai"
model = "gpt-4o"
Supported Models
Any model available through the OpenAI Chat Completions API (or compatible endpoint) that supports tool calling:
gpt-4o,gpt-4o-minigpt-4-turboo1,o3-mini- Third-party models via compatible APIs
Custom Base URL
To use an OpenAI-compatible endpoint, set the base URL:
# Ollama
agsh --provider openai --model llama3 --base-url http://localhost:11434/v1
# OpenRouter
agsh --provider openai --model anthropic/claude-sonnet-4-20250514 --base-url https://openrouter.ai/api/v1
Or in the config file:
[provider]
name = "openai"
model = "llama3"
api_key = "unused"
base_url = "http://localhost:11434/v1"
API Details
Endpoint: POST {base_url}/chat/completions
Tool format: Tools are sent as function definitions:
{
"type": "function",
"function": {
"name": "read_file",
"description": "Read the contents of a file at the given path.",
"parameters": { "type": "object", "properties": { ... } }
}
}
Tool results: Sent back as messages with role: "tool" and the corresponding tool_call_id.
Streaming: Uses Server-Sent Events (SSE) with data: {...} lines. The stream ends with data: [DONE].
Anthropic Provider
The Anthropic provider uses the Messages API.
Configuration
| Setting | Value |
|---|---|
| Provider name | anthropic |
| Default base URL | https://api.anthropic.com |
| API key env var | ANTHROPIC_API_KEY |
| Auth method | x-api-key header |
| API version | 2023-06-01 |
| Max tokens | 8192 |
Minimal Setup
export AGSH_PROVIDER=anthropic
export AGSH_MODEL=claude-sonnet-4-20250514
export ANTHROPIC_API_KEY=sk-ant-...
agsh
Config File
[provider]
name = "anthropic"
model = "claude-sonnet-4-20250514"
Supported Models
Any model available through the Anthropic Messages API:
claude-opus-4-20250514claude-sonnet-4-20250514claude-haiku-4-5-20251001
Custom Base URL
To use an Anthropic-compatible proxy or gateway:
agsh --provider anthropic --model claude-sonnet-4-20250514 --base-url https://my-proxy.example.com
API Details
Endpoint: POST {base_url}/v1/messages
Headers:
x-api-key: <api_key>anthropic-version: 2023-06-01content-type: application/json
System prompt: Sent as a top-level system field in the request body (not as a message).
Tool format: Tools are defined with input_schema instead of parameters:
{
"name": "read_file",
"description": "Read the contents of a file at the given path.",
"input_schema": { "type": "object", "properties": { ... } }
}
Tool use and results: Expressed as content blocks within messages:
- Tool use:
{"type": "tool_use", "id": "...", "name": "...", "input": {...}} - Tool result:
{"type": "tool_result", "tool_use_id": "...", "content": "..."}
Streaming: Uses Server-Sent Events with named event types:
| Event | Description |
|---|---|
message_start | Message initialization |
content_block_start | Begin a text or tool_use block |
content_block_delta | Incremental text (text_delta) or tool input (input_json_delta) |
content_block_stop | End of a content block |
message_delta | Final metadata including stop_reason |
message_stop | Stream complete |
ping | Keep-alive |
Tools Overview
Tools are the actions that the agent can perform on your behalf. The LLM decides which tools to call based on your instructions.
Available Tools
| Tool | Permission | Description |
|---|---|---|
read_file | Read | Read file contents |
edit_file | Write | Make string replacements in a file |
write_file | Write | Create or overwrite a file |
find_files | Read | Find files by glob pattern |
search_contents | Read | Search file contents with regex |
fetch_url | Read | Fetch a web page as markdown |
web_search | Read | Search the web |
execute_command | Write | Run a shell command |
Permission Requirements
Tools are grouped by the minimum permission level required:
Read permission (available in read and write modes):
read_file,find_files,search_contents,fetch_url,web_search
Write permission (only available in write mode):
edit_file,write_file,execute_command
In none mode, no tools are available. The agent can only respond with text.
How Tool Calls Work
- The agent receives your instruction and decides which tools to call
- For each tool call, agsh checks the current permission level
- If permitted, the tool executes and its output is fed back to the agent
- The agent may make additional tool calls or respond with text
- This loop continues until the agent has no more tool calls to make
Tool calls and their results are displayed in the terminal so you can see what the agent is doing.
File Operations
read_file
Read the contents of a file at a given path.
Permission: Read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
path | string | yes | The file path to read |
offset | integer | no | Line number to start reading from (0-based) |
limit | integer | no | Maximum number of lines to read |
Examples
Read an entire file:
agsh [r] > show me the contents of src/main.rs
Read lines 10-20:
agsh [r] > show me lines 10 through 20 of src/main.rs
The agent will call read_file with offset: 10 and limit: 10.
edit_file
Make a string replacement in a file. Replaces the first occurrence of old_string with new_string.
Permission: Write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
path | string | yes | The file path to edit |
old_string | string | yes | The exact string to find and replace |
new_string | string | yes | The replacement string |
Behavior
- Reads the file, performs the replacement, and writes it back.
- Only the first occurrence of
old_stringis replaced. - If
old_stringis not found, the tool returns an error message (without modifying the file).
Examples
agsh [w] > change the function name "foo" to "bar" in src/lib.rs
agsh [w] > fix the typo "recieve" to "receive" in README.md
write_file
Create or overwrite a file with the given content.
Permission: Write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
path | string | yes | The file path to write |
content | string | yes | The content to write to the file |
Behavior
- Creates parent directories if they do not exist.
- Overwrites the file if it already exists.
Examples
agsh [w] > create a new file called hello.py that prints "hello world"
agsh [w] > write a .gitignore file for a Rust project
Search Tools
find_files
Find files matching a glob pattern.
Permission: Read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
pattern | string | yes | Glob pattern to match files against |
path | string | no | Directory to search in (defaults to current directory) |
Glob Patterns
| Pattern | Matches |
|---|---|
*.rs | All .rs files in the current directory |
**/*.rs | All .rs files recursively |
src/*.txt | All .txt files in src/ |
test_* | All files starting with test_ |
Examples
agsh [r] > find all Rust source files in this project
agsh [r] > find all configuration files (*.toml, *.yaml, *.json) in this repo
search_contents
Search file contents using a regex pattern. Powered by the ripgrep library.
Permission: Read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
pattern | string | yes | Regex pattern to search for |
path | string | no | File or directory to search in (defaults to current directory) |
glob | string | no | Glob pattern to filter which files are searched (e.g., *.rs) |
Behavior
- Searches recursively through directories.
- Skips hidden files (starting with
.) and common non-text directories (target,node_modules). - Results are limited to 100 matches to avoid overwhelming the LLM context.
- Each result includes the file path, line number, and matching line.
Examples
agsh [r] > search for all TODO comments in this project
agsh [r] > find all uses of "unwrap()" in Rust files
The agent will call search_contents with pattern: "unwrap\\(\\)" and glob: "*.rs".
agsh [r] > search for the string "API_KEY" in all .env files
Web Tools
fetch_url
Fetch a web page and return its content as markdown text.
Permission: Read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
url | string | yes | The URL to fetch |
Behavior
- Fetches the page via HTTP GET.
- Converts HTML to Markdown using
fast_html2md. - Truncates the output to 50,000 characters if the page is very large.
- HTTP timeout: 30 seconds.
- Returns the HTTP status code as an error if the request fails (e.g., 404, 500).
Examples
agsh [r] > fetch the Rust homepage and summarize what's new
agsh [r] > read the documentation at https://docs.rs/tokio/latest/tokio/
web_search
Search the web and return results. Supports multiple search engines.
Permission: Read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
query | string | yes | The search query |
engine | string | no | Search engine to use (default: duckduckgo) |
Search Engines
| Value | Engine |
|---|---|
duckduckgo | DuckDuckGo (default) |
google | Google Search |
bing | Bing Search |
Behavior
- Returns up to 10 results per search.
- Each result includes the title, URL, and a snippet (when available).
- Uses HTML scraping (no API keys required for any search engine).
- HTTP timeout: 15 seconds.
Examples
agsh [r] > search the web for "rust async tutorial"
agsh [r] > search google for the latest news about WebAssembly
agsh [r] > use bing to search for "tokio vs async-std comparison"
Shell Tool
execute_command
Execute a shell command and return its output.
Permission: Write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
command | string | yes | The shell command to execute |
timeout_ms | integer | no | Timeout in milliseconds (default: 30000) |
Behavior
- Executes the command via
sh -c "<command>"on Unix orpowershell -Command "<command>"on Windows. - Captures both stdout and stderr.
- Returns the exit code along with the output.
- Default timeout is 30 seconds. If the command exceeds the timeout, it is killed.
- Supports cancellation: pressing Ctrl+C while a command is running kills the child process.
Output Format
The tool returns output in this format:
Exit code: 0
stdout:
<stdout content>
stderr:
<stderr content>
Examples
agsh [w] > run the test suite
The agent will call execute_command with command: "cargo test".
agsh [w] > show disk usage of the current directory
agsh [w] > check which ports are listening on this machine
agsh [w] > compile the project in release mode
Timeout
For long-running commands, the agent can specify a custom timeout:
agsh [w] > run the full integration test suite (it might take a while)
The agent may call execute_command with a higher timeout_ms value.
Safety
The agent is instructed (via the system prompt) to explain what it intends to do before running potentially destructive commands. However, the permission system is the primary safety mechanism: write-permission tools are only available when you explicitly enable write mode.