This guide walks you through building an AI agent that can use shell commands, MCP tools, and multi-step reasoning. By the end you'll have a working agent that can explore code, run commands, and answer questions.
- Node.js 18+
- An AI provider API key (Google, Anthropic, or OpenAI)
The simplest agent is an AI step with bash access:
version: "1.0"
ai_provider: google
steps:
agent:
type: ai
prompt: "Find all TODO comments in the codebase and summarize them."
enable_bash: trueWith enable_bash: true, the AI can run shell commands to explore the filesystem, run grep, read files, etc.
Run it: npx visor
Define tools the AI can call. Tools are shell commands with typed inputs:
version: "1.0"
ai_provider: google
# Define reusable tools at the top level
tools:
count-lines:
description: "Count lines in a file"
exec: "wc -l {{ args.file }}"
args:
file:
type: string
description: "Path to the file"
list-files:
description: "List files matching a pattern"
exec: "find . -name '{{ args.pattern }}' -type f"
args:
pattern:
type: string
description: "Glob pattern"
steps:
agent:
type: ai
prompt: "Analyze the project structure. Which files are the largest?"
ai_custom_tools: [count-lines, list-files]Use system_prompt inside the ai: block (not at step level):
steps:
agent:
type: ai
prompt: "{{ conversation.current.text }}" # available in --tui and --message modes
ai_custom_tools: [count-lines, list-files]
ai:
system_prompt: |
You are a senior software engineer. You can use tools to explore
the codebase. Always verify your assumptions by reading actual code.
Be concise and cite file paths.
max_iterations: 20 # allow up to 20 tool callsChain multiple agent steps for complex tasks:
version: "1.0"
ai_provider: anthropic
ai_model: claude-sonnet-4-20250514
steps:
# Step 1: Gather context
explore:
type: ai
prompt: "Explore the project and identify the main modules and their responsibilities."
enable_bash: true
ai:
system_prompt: "You are a code archaeologist. Map the codebase structure."
# Step 2: Analyze with context from step 1
analyze:
type: ai
prompt: |
Based on this codebase map:
{{ outputs["explore"] | json }}
Identify the top 3 areas that need refactoring and explain why.
depends_on: [explore]
ai:
system_prompt: "You are a software architect focused on code quality."
# Step 3: Generate a report
report:
type: ai
prompt: |
Create a markdown report from this analysis:
{{ outputs["analyze"] | json }}
depends_on: [analyze]Connect external MCP servers for specialized capabilities:
steps:
agent:
type: ai
prompt: "Check the repository for security issues using Semgrep."
ai_mcp_servers:
semgrep:
command: npx
args: ["-y", "@semgrep/mcp@latest"]
ai:
system_prompt: "You are a security analyst. Use Semgrep to scan the code."Or use the MCP provider directly for non-AI tool calls:
steps:
scan:
type: mcp
transport: stdio
command: npx
command_args: ["-y", "@semgrep/mcp@latest"]
method: scan
methodArgs:
path: "."The same config works as a conversational Slack bot:
SLACK_BOT_TOKEN=xoxb-... SLACK_APP_TOKEN=xapp-... npx visor --slack --config agent.yamlOr interactively in the terminal:
npx visor --tui --config agent.yamlversion: "1.0"
# ── Global defaults ─────────────────────────────────
ai_provider: google # default for all AI steps
ai_model: gemini-2.5-flash # default model
# ── Tools (top level) ───────────────────────────────
tools:
my-tool:
description: "..."
exec: "..."
args: { ... }
# ── Steps ────────────────────────────────────────────
steps:
my-step:
type: ai
prompt: "..."
# AI config goes in the ai: block
ai:
system_prompt: "..." # NOT at step level
provider: anthropic # override global
model: claude-sonnet-4-20250514 # override global
max_iterations: 20
# OR use shorthand at step level (same effect)
ai_system_prompt: "..."
ai_provider: anthropic
ai_model: claude-sonnet-4-20250514
# Tool access
enable_bash: true # allow shell commands
ai_custom_tools: [tool-name] # reference top-level tools
ai_mcp_servers: # connect MCP servers
server-name:
command: "..."
args: [...]
utcp-tools: # or UTCP tools
type: utcp
manual: https://tools.example.com/utcp- ai-custom-tools-simple.yaml — AI with custom tools
- ai-with-bash.yaml — AI with bash access
- claude-code-config.yaml — Claude Code with MCP tools
- mcp-provider-example.yaml — Direct MCP tool calls
- utcp-provider-example.yaml — UTCP tools (standalone and with AI)
| Mistake | Fix |
|---|---|
system_prompt at step level |
Put inside ai: block, or use ai_system_prompt |
Top-level ai: block |
Use ai_provider/ai_model at top level |
model: or provider: at step level |
Use ai_model/ai_provider or put inside ai: |
Run npx visor validate to catch config errors.
- AI Configuration — providers, retry, fallback
- AI Custom Tools — tool definition reference
- MCP Provider — MCP transport options
- Failure Routing — retry and auto-remediation
- Session Reuse — multi-turn conversations