Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

  1. You type a natural language instruction
  2. agsh sends it to the configured LLM along with tool definitions and a system prompt
  3. The LLM decides which tools to call (if any) and returns text and/or tool calls
  4. agsh executes the tool calls, feeds results back to the LLM, and repeats until the LLM is done
  5. 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.

PlatformArchive
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:

SettingConfig KeyEnv VarCLI Flag
Providerprovider.nameAGSH_PROVIDER--provider
Modelprovider.modelAGSH_MODEL-m, --model
API Keyprovider.api_keyOPENAI_API_KEY or ANTHROPIC_API_KEY

Override Layers

Configuration is layered. Higher-priority layers override lower ones:

  1. CLI flags – per-invocation overrides (--provider, --model, --base-url, -p)
  2. Environment variables – useful for CI, containers, or temporary overrides (AGSH_PROVIDER, etc.)
  3. Config file – persistent settings in ~/.config/agsh/config.toml
  4. 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: reads OPENAI_API_KEY
  • Provider anthropic: reads ANTHROPIC_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.

ValueDescription
openaiOpenAI Chat Completions API (also works with OpenAI-compatible APIs)
anthropicAnthropic 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/v1 for the openai provider
  • https://api.anthropic.com for the anthropic provider

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

VariableDescriptionExample
AGSH_PROVIDERLLM provider nameopenai, anthropic
AGSH_MODELModel identifiergpt-4o, claude-sonnet-4-20250514
AGSH_PERMISSIONDefault permission modenone, read, write

Provider API Keys

VariableUsed When
OPENAI_API_KEYProvider is openai
ANTHROPIC_API_KEYProvider is anthropic

Provider Base URL

VariableDescription
OPENAI_BASE_URLCustom base URL for the OpenAI-compatible endpoint

Logging

agsh uses the tracing framework. The log level can be controlled with:

VariableDescriptionExample
RUST_LOGStandard Rust log filteragsh=debug, agsh=trace

If RUST_LOG is not set, the verbosity flag (-v, -vv, -vvv) controls the level:

FlagLevel
(none)warn
-vinfo
-vvdebug
-vvvtrace

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

KeyAction
EnterSubmit the current prompt
Alt+EnterInsert a newline (for multi-line input)
Shift+TabCycle the permission mode (none → read → write → none)
KeyAction
Ctrl+AMove cursor to start of line
Ctrl+EMove cursor to end of line
Ctrl+FMove cursor forward one character
Ctrl+BMove cursor backward one character
Alt+FMove cursor forward one word
Alt+BMove cursor backward one word

Editing

KeyAction
Ctrl+DDelete character under cursor / exit on empty line
Ctrl+H, BackspaceDelete character before cursor
Ctrl+KKill text from cursor to end of line
Ctrl+UKill text from start of line to cursor
Ctrl+WKill word before cursor
Ctrl+YYank (paste) killed text

Control

KeyAction
Ctrl+CInterrupt the running agent; clear the line if idle
Ctrl+DExit the shell (when the line is empty)
Ctrl+RReverse incremental search through history
Ctrl+LClear the screen

Prompt Format

agsh [indicator] >

The indicator shows the current permission mode:

ModeIndicatorColor
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 exit or quit
  • 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

LevelIndicatorAllowed 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:

ColumnTypeDescription
idTEXT (UUID)Primary key
created_atTEXT (RFC 3339)When the session was created
updated_atTEXT (RFC 3339)When the session was last updated
locked_byTEXT (PID)PID of the process holding the lock, or NULL
metadataTEXTReserved for future use

messages – one row per message in a session:

ColumnTypeDescription
idINTEGERAuto-incrementing primary key
session_idTEXT (UUID)Foreign key to sessions.id
roleTEXTuser, assistant, or tool_results
contentTEXTMessage content (plain text or JSON)
created_atTEXT (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:

ProviderAPIStreamingTool Calling
OpenAIChat CompletionsSSEFunction calling
AnthropicMessages APISSE (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

SettingValue
Provider nameopenai
Default base URLhttps://api.openai.com/v1
API key env varOPENAI_API_KEY
Auth methodBearer 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-mini
  • gpt-4-turbo
  • o1, 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

SettingValue
Provider nameanthropic
Default base URLhttps://api.anthropic.com
API key env varANTHROPIC_API_KEY
Auth methodx-api-key header
API version2023-06-01
Max tokens8192

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-20250514
  • claude-sonnet-4-20250514
  • claude-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-01
  • content-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:

EventDescription
message_startMessage initialization
content_block_startBegin a text or tool_use block
content_block_deltaIncremental text (text_delta) or tool input (input_json_delta)
content_block_stopEnd of a content block
message_deltaFinal metadata including stop_reason
message_stopStream complete
pingKeep-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

ToolPermissionDescription
read_fileReadRead file contents
edit_fileWriteMake string replacements in a file
write_fileWriteCreate or overwrite a file
find_filesReadFind files by glob pattern
search_contentsReadSearch file contents with regex
fetch_urlReadFetch a web page as markdown
web_searchReadSearch the web
execute_commandWriteRun 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

  1. The agent receives your instruction and decides which tools to call
  2. For each tool call, agsh checks the current permission level
  3. If permitted, the tool executes and its output is fed back to the agent
  4. The agent may make additional tool calls or respond with text
  5. 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

NameTypeRequiredDescription
pathstringyesThe file path to read
offsetintegernoLine number to start reading from (0-based)
limitintegernoMaximum 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

NameTypeRequiredDescription
pathstringyesThe file path to edit
old_stringstringyesThe exact string to find and replace
new_stringstringyesThe replacement string

Behavior

  • Reads the file, performs the replacement, and writes it back.
  • Only the first occurrence of old_string is replaced.
  • If old_string is 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

NameTypeRequiredDescription
pathstringyesThe file path to write
contentstringyesThe 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

NameTypeRequiredDescription
patternstringyesGlob pattern to match files against
pathstringnoDirectory to search in (defaults to current directory)

Glob Patterns

PatternMatches
*.rsAll .rs files in the current directory
**/*.rsAll .rs files recursively
src/*.txtAll .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

NameTypeRequiredDescription
patternstringyesRegex pattern to search for
pathstringnoFile or directory to search in (defaults to current directory)
globstringnoGlob 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

NameTypeRequiredDescription
urlstringyesThe 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/

Search the web and return results. Supports multiple search engines.

Permission: Read

Parameters

NameTypeRequiredDescription
querystringyesThe search query
enginestringnoSearch engine to use (default: duckduckgo)

Search Engines

ValueEngine
duckduckgoDuckDuckGo (default)
googleGoogle Search
bingBing 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

NameTypeRequiredDescription
commandstringyesThe shell command to execute
timeout_msintegernoTimeout in milliseconds (default: 30000)

Behavior

  • Executes the command via sh -c "<command>" on Unix or powershell -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.