Tools Reference

May 6, 2026 · View on GitHub

ProbeAgent provides a comprehensive set of tools that the AI can use to interact with your codebase. This document covers all available tools, their parameters, and usage patterns.


Tool Categories

CategoryToolsDescription
Search & Querysearch, query, extract, symbolsFind and retrieve code
File Operationsedit, create, listFiles, searchFilesModify and explore files
ExecutionbashRun shell commands
Analysisanalyze_all, readMediaComprehensive analysis
Agent Controldelegate, attempt_completionOrchestration and completion
SkillslistSkills, useSkillDynamic capabilities
TaskstaskMulti-step tracking

Core Search Tools

Semantic code search using Elasticsearch-style queries.

Parameters:

ParameterTypeRequiredDescription
querystringYesSearch query (supports AND, OR, NOT, wildcards)
pathstringNoDirectory to search (default: workspace root)
limitnumberNoMaximum results (default: 20)
exactbooleanNoExact match mode (default: false)
allowTestsbooleanNoInclude test files (default: false)
maxTokensnumber/nullNoMax tokens to return. Default 20000. Set to null for unlimited.

Example AI Usage:

<search>
  <query>authentication AND middleware</query>
  <path>./src</path>
  <limit>10</limit>
</search>

searchAll

Exhaustive search that auto-paginates to retrieve ALL matching results. Use when you need complete coverage for bulk analysis.

Parameters:

ParameterTypeRequiredDescription
querystringYesSearch query (supports AND, OR, NOT, wildcards)
pathstringNoDirectory to search (default: workspace root)
exactbooleanNoExact match mode (default: false)
maxTokensPerPagenumberNoTokens per page (default: 20000)
maxPagesnumberNoMaximum pages to retrieve (default: 50, safety limit)

Example DSL Usage:

// Get ALL matching results across the entire codebase
const allResults = searchAll("authentication")

// With options
const results = searchAll({
  query: "API endpoint",
  path: "./src",
  maxPages: 100
})

When to use:

  • Use search() for targeted queries where first results are sufficient
  • Use searchAll() when you need complete coverage (e.g., "find ALL usages of X")

Session-Based Pagination (DSL)

Within execute_plan DSL scripts, search uses session-based pagination:

How it works:

  • Each execute_plan invocation gets a unique session ID
  • Multiple search() calls with the same query return successive pages
  • The session is isolated — different execute_plan calls don't interfere

Manual pagination example:

// In execute_plan DSL script
let allResults = ""
let page = search("authentication")

while (page && !page.includes("All results retrieved")) {
  allResults = allResults + "\n" + page
  page = search("authentication")  // Same query = next page
}

return allResults

Benefits of manual pagination:

  • Process each page before fetching the next (memory efficient)
  • Stop early when you find what you need
  • Apply different logic per page (e.g., LLM classification)

Searching Dependencies:

The agent can search inside project dependencies using special path prefixes:

PrefixLanguageExample
go:Go modulesgo:github.com/gin-gonic/gin
js:npm packagesjs:express or js:@ai-sdk/anthropic
rust:Rust cratesrust:serde
<!-- Search in an npm package -->
<search>
  <query>createAnthropic</query>
  <path>js:@ai-sdk/anthropic</path>
</search>

<!-- Search in a Go module -->
<search>
  <query>Context AND middleware</query>
  <path>go:github.com/gin-gonic/gin</path>
</search>

Prompting the Agent:

To ask the agent to search dependencies, use natural language like:

  • "Search for how createAnthropic works in the @ai-sdk/anthropic package"
  • "Look inside the gin library to see how middleware is implemented"
  • "Find the Serialize trait definition in the serde crate"

Configuration:

const agent = new ProbeAgent({
  path: './src',
  searchDelegate: true,  // Use code-search subagent (default)
  outline: false         // Use outline-xml format
});

query

AST-based structural queries using tree-sitter patterns.

Parameters:

ParameterTypeRequiredDescription
patternstringYesAST-grep pattern
pathstringNoDirectory to search
languagestringNoProgramming language
limitnumberNoMaximum results
with_contextbooleanNoInclude owning source-block context in JSON output

Example AI Usage:

<query>
  <pattern>fn $NAME($PARAMS) { $$$BODY }</pattern>
  <language>rust</language>
  <path>./src</path>
</query>

Use with_context when the exact AST match needs its enclosing function, method, class, attached comments, or call context for downstream analysis:

<query>
  <pattern>fetch($$$ARGS)</pattern>
  <language>typescript</language>
  <path>./src</path>
  <with_context>true</with_context>
</query>

Common Patterns:

  • Functions: fn $NAME() { $$$BODY }
  • Classes: class $NAME { $$$BODY }
  • Interfaces: interface $NAME { $$$BODY }
  • Variables: let $NAME = $VALUE

extract

Extract code blocks from files by location or symbol.

Parameters:

ParameterTypeRequiredDescription
filestringYesFile path with line or symbol (e.g., src/auth.ts:42 or src/auth.ts#login)
contextnumberNoContext lines before/after

Example AI Usage:

<extract>
  <file>src/auth/login.ts:42</file>
  <context>5</context>
</extract>

symbols

List all symbols (functions, classes, structs, constants, etc.) in a file. Returns a hierarchical tree with line numbers — like a table of contents for code files.

Parameters:

ParameterTypeRequiredDescription
filestringYesPath to the file to list symbols from

Example AI Usage:

<symbols>
  <file>src/auth/login.ts</file>
</symbols>

Response format (JSON):

{
  "file": "src/auth/login.ts",
  "symbols": [
    { "name": "loginUser", "kind": "function", "line": 5, "end_line": 25, "signature": "async function loginUser(email: string, password: string)" },
    { "name": "AuthService", "kind": "class", "line": 27, "end_line": 80, "signature": "class AuthService", "children": [
      { "name": "constructor", "kind": "method", "line": 28, "end_line": 35, "signature": "constructor()" },
      { "name": "validate", "kind": "method", "line": 37, "end_line": 50, "signature": "validate(token: string): boolean" }
    ]}
  ]
}

File Operation Tools

edit

Edit files using text replacement, AST-aware symbol operations, or line-targeted editing. Supports four modes: text-based find/replace with fuzzy matching, AST-aware symbol replacement, symbol insertion, and line-targeted editing with optional hash-based integrity verification.

Enabled By: allowEdit: true

Four Editing Modes:

ModeParametersWhen to Use
Text editold_string + new_stringSmall, precise changes: fix a condition, rename a variable, update a value
Symbol replacesymbol + new_stringReplace an entire function, class, or method by name (no exact text matching needed)
Symbol insertsymbol + new_string + positionInsert new code before or after an existing symbol
Line-targeted editstart_line + new_stringEdit specific lines from extract/search output; ideal for changes inside large functions

Parameters:

ParameterTypeRequiredDescription
file_pathstringYesPath to the file to edit (absolute or relative to cwd)
new_stringstringYesReplacement text or new code content
old_stringstringNoText to find and replace. Copy verbatim from the file.
replace_allbooleanNoReplace all occurrences (default: false, text mode only)
symbolstringNoCode symbol name for AST-aware editing (e.g. "myFunction", "MyClass.myMethod")
positionstringNo"before" or "after" — insert near the symbol or line instead of replacing it
start_linestringNoLine reference for line-targeted editing (e.g. "42" or "42:ab" with hash)
end_linestringNoEnd of line range, inclusive (e.g. "55" or "55:cd"). Defaults to start_line.

Mode Selection Rules (Priority Order):

  • If symbol is provided → AST-aware mode (symbol replace or symbol insert depending on position)
  • If start_line is provided (without symbol) → line-targeted mode
  • If old_string is provided (without symbol or start_line) → text-based mode
  • If none are provided → error with guidance

Text Mode — Find and Replace

Provide old_string with text copied verbatim from the file and new_string with the replacement.

<edit>
<file_path>src/main.js</file_path>
<old_string>return false;</old_string>
<new_string>return true;</new_string>
</edit>

Fuzzy Matching: If exact matching fails, the tool automatically tries progressively relaxed matching:

  1. Exact match — verbatim string comparison
  2. Line-trimmed — strips leading/trailing whitespace from each line
  3. Whitespace-normalized — collapses all runs of whitespace to single spaces
  4. Indent-flexible — matches code structure regardless of base indentation level

Replace all occurrences:

<edit>
<file_path>config.json</file_path>
<old_string>"debug": false</old_string>
<new_string>"debug": true</new_string>
<replace_all>true</replace_all>
</edit>

Symbol Replace Mode — Rewrite by Name

Provide symbol with the name of a function, class, or method and new_string with the complete new implementation. No need to quote the old code.

<edit>
<file_path>src/utils.js</file_path>
<symbol>calculateTotal</symbol>
<new_string>function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}</new_string>
</edit>

The tool uses tree-sitter AST parsing to find the symbol by name, then replaces the entire definition with your new_string. Supported across 16 languages: JavaScript, TypeScript, Python, Rust, Go, Java, C, C++, Ruby, PHP, Swift, Kotlin, Scala, C#, Lua, Zig.

Auto-indentation: The tool detects the original symbol's indentation level and reindents your new_string to match.

Symbol naming: Use the name as it appears in source — functions: "calculateTotal", classes: "UserService", methods: "MyClass.myMethod" (dot notation).

Symbol Insert Mode — Add Code Near a Symbol

Provide symbol, new_string, and position ("before" or "after") to insert code near an existing symbol.

<edit>
<file_path>src/utils.js</file_path>
<symbol>calculateTotal</symbol>
<position>after</position>
<new_string>function calculateTax(total, rate) {
  return total * rate;
}</new_string>
</edit>

Line-Targeted Mode — Edit by Line Number

Use line numbers from extract or search output to make precise edits. Ideal for editing inside large functions without rewriting the entire symbol.

<edit>
<file_path>src/main.js</file_path>
<start_line>42</start_line>
<end_line>55</end_line>
<new_string>  // simplified implementation
  return processItems(order.items);</new_string>
</edit>

When allowEdit is enabled, hashLines is on by default — line references include content hashes for integrity verification (e.g. "42:ab"). If the hash doesn't match, the error provides updated references. Disable with hashLines: false or --no-hash-lines.

Heuristic auto-corrections handle common LLM mistakes: stripping accidental line-number prefixes, removing echoed boundary lines, and restoring indentation.

Error Handling — Self-Healing Messages:

All error messages include specific recovery instructions. When an edit fails, the error tells the AI exactly how to fix the call and retry. For example:

  • String not found: Suggests reading current file content, trying symbol mode, verifying path
  • Symbol not found: Suggests using search/extract to find the correct name, offers text mode fallback
  • Multiple occurrences: Suggests replace_all=true or adding more context
  • Hash mismatch: Provides the updated line:hash reference for retrying

Configuration:

const agent = new ProbeAgent({
  path: './src',
  allowEdit: true,
  allowedFolders: ['./src', './tests']  // restrict to specific directories
});

Extract→Edit Workflow (Large Functions):

For editing inside large functions, combine extract (to get line numbers) with edit (to make precise changes):

<!-- Step 1: Extract the function to see its line numbers -->
<extract>
<targets>src/order.js#processOrder</targets>
</extract>

<!-- Output shows:
  142:ab | function processOrder(order) {
  143:cd |   const items = order.items;
  ...
  189:ef |   return total;
  190:12 | }
-->

<!-- Step 2: Edit specific lines within the function -->
<edit>
<file_path>src/order.js</file_path>
<start_line>143:cd</start_line>
<end_line>145</end_line>
<new_string>  const items = order.items.filter(i => i.active);
  const validated = validateItems(items);</new_string>
</edit>

With allowEdit, hashLines is on by default — the extract output includes content hashes (e.g. 143:cd) for integrity verification in the edit call. If the file changed since extraction, the error provides updated references.

File State Tracking (Multi-Edit Safety):

When allowEdit: true, the agent automatically tracks which files have been read via search/extract. Before any edit, the tracker verifies that:

  1. The file was previously read (blocks blind edits)
  2. The file hasn't been modified since it was last read (detects stale content)

After each successful write, the tracker is updated so chained edits to the same file work correctly. If a check fails, the error message guides the LLM to re-read the file with extract before retrying.

Standalone SDK Usage:

import { editTool } from '@probelabs/probe';

const edit = editTool({
  allowedFolders: ['/path/to/project'],
  cwd: '/path/to/project'
});

// Text edit
await edit.execute({
  file_path: 'src/main.js',
  old_string: 'return false;',
  new_string: 'return true;'
});

// Symbol replace
await edit.execute({
  file_path: 'src/utils.js',
  symbol: 'calculateTotal',
  new_string: `function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}`
});

// Symbol insert
await edit.execute({
  file_path: 'src/utils.js',
  symbol: 'calculateTotal',
  position: 'after',
  new_string: `function calculateTax(total, rate) {
  return total * rate;
}`
});

// Line-targeted edit (replace a range)
await edit.execute({
  file_path: 'src/order.js',
  start_line: '143',
  end_line: '145',
  new_string: '  const items = order.items.filter(i => i.active);'
});

// Line-targeted edit with hash verification
await edit.execute({
  file_path: 'src/order.js',
  start_line: '143:cd',
  new_string: '  const items = order.items.filter(i => i.active);'
});

// Insert after a line
await edit.execute({
  file_path: 'src/order.js',
  start_line: '142',
  position: 'after',
  new_string: '  console.log("Processing order:", order.id);'
});

create

Create new files with specified content. Parent directories are created automatically.

Enabled By: allowEdit: true

Parameters:

ParameterTypeRequiredDescription
file_pathstringYesPath where the file should be created
contentstringYesContent to write to the file
overwritebooleanNoWhether to overwrite if file exists (default: false)

Example AI Usage:

<create>
<file_path>src/utils/helpers.ts</file_path>
<content>export function formatDate(date: Date): string {
  return date.toISOString();
}</content>
</create>

Overwrite an existing file:

<create>
<file_path>src/config.json</file_path>
<content>{"debug": true, "verbose": false}</content>
<overwrite>true</overwrite>
</create>

listFiles

List files and directories.

Parameters:

ParameterTypeRequiredDescription
directorystringNoDirectory to list (default: workspace root)
maxDepthnumberNoMaximum directory depth

Example AI Usage:

<listFiles>
  <directory>./src/components</directory>
  <maxDepth>2</maxDepth>
</listFiles>

searchFiles

Search for files by name pattern.

Parameters:

ParameterTypeRequiredDescription
patternstringYesFile name pattern (glob)
directorystringNoSearch directory
limitnumberNoMaximum results

Example AI Usage:

<searchFiles>
  <pattern>*.test.ts</pattern>
  <directory>./src</directory>
  <limit>20</limit>
</searchFiles>

Execution Tool

bash

Execute shell commands.

Enabled By: enableBash: true

Parameters:

ParameterTypeRequiredDescription
commandstringYesCommand to execute
cwdstringNoWorking directory
timeoutnumberNoTimeout in ms (default: 30000)

Example AI Usage:

<bash>
  <command>npm test -- --coverage</command>
  <cwd>./</cwd>
  <timeout>60000</timeout>
</bash>

Configuration:

const agent = new ProbeAgent({
  path: './src',
  enableBash: true,
  bashConfig: {
    allow: ['git:push'],                // Override default deny for git push
    deny: ['git:push:--force'],         // But always block force push
    disableDefaultAllow: false,
    disableDefaultDeny: false,
    debug: false
  }
});

Permission Priority (highest to lowest):

  1. Custom deny (bashConfig.deny) — always blocks, cannot be overridden
  2. Custom allow (bashConfig.allow) — overrides default deny patterns
  3. Default deny — built-in list of dangerous commands
  4. Allow list — built-in + custom allow patterns for safe commands

This means --bash-allow "git:push" overrides the default deny for git push without disabling any other default protections. See the Security Guide for detailed examples.

Default Allowed Commands:

  • ls, cat, head, tail, find, grep (file exploration)
  • git:status, git:log, git:diff, git:show, git:branch (git read-only)
  • gh:issue:list, gh:pr:view, gh:search:*, gh:api (GitHub CLI reads)
  • npm:list, pip:list (package info)

Default Denied Commands:

  • rm:-rf, sudo, chmod:777 (destructive/privilege escalation)
  • git:push, git:reset, git:commit, git:merge (git write operations)
  • gh:issue:create, gh:pr:merge, gh:repo:delete (GitHub CLI writes)
  • npm:install, pip:install (package installation)

Analysis Tools

analyze_all

Comprehensive codebase analysis.

Parameters:

ParameterTypeRequiredDescription
pathstringNoDirectory to analyze
depthstringNoAnalysis depth: 'shallow', 'normal', 'deep'

Example AI Usage:

<analyze_all>
  <path>./src</path>
  <depth>normal</depth>
</analyze_all>

readMedia

Load and analyze media files (images and PDF documents). The readImage tool name is supported as a backward-compatible alias.

Parameters:

ParameterTypeRequiredDescription
pathstringYesPath to media file (image or PDF)

Supported Formats:

  • Images: .png, .jpg, .jpeg, .webp, .bmp, .svg
  • Documents: .pdf

Provider Notes:

  • PDF support is native across Claude (32MB limit), OpenAI (50MB), and Gemini (50MB)
  • SVG is not supported by Google Gemini
  • Documents are sent via the Vercel AI SDK file content part

Example AI Usage:

<readMedia>
  <path>./docs/architecture-diagram.png</path>
</readMedia>
<readMedia>
  <path>./reports/analysis.pdf</path>
</readMedia>

Agent Control Tools

delegate

Delegate tasks to specialized subagents.

Enabled By: enableDelegate: true

Parameters:

ParameterTypeRequiredDescription
taskstringYesSelf-contained task description
subagentstringNoSubagent type
contextstringNoAdditional context

Example AI Usage:

<delegate>
  <task>Research how authentication is implemented and summarize the flow</task>
</delegate>

Configuration:

const agent = new ProbeAgent({
  path: './src',
  enableDelegate: true
});

attempt_completion

Signal task completion.

Parameters:

ParameterTypeRequiredDescription
resultstringYesSummary of completed work
commandstringNoOptional command to demonstrate

Example AI Usage:

<attempt_completion>
  <result>Added input validation to the login form:
- Email format validation
- Password strength requirements
- Real-time error feedback
All tests passing.</result>
</attempt_completion>

Skills Tools

listSkills

List available agent skills.

Enabled By: allowSkills: true

Example AI Usage:

<listSkills />

useSkill

Execute a discovered skill.

Parameters:

ParameterTypeRequiredDescription
skillNamestringYesName of skill
inputanyNoSkill parameters

Example AI Usage:

<useSkill>
  <skillName>generate-tests</skillName>
  <input>{"file": "src/auth.ts"}</input>
</useSkill>

Task Management

task

Manage multi-step tasks.

Enabled By: enableTasks: true

Parameters:

ParameterTypeRequiredDescription
actionstringYes'create', 'update', 'complete', 'list'
taskIdstringConditionalRequired for update/complete
titlestringConditionalRequired for create
descriptionstringNoTask description
statusstringNoTask status
blockedBystring[]NoBlocking task IDs

Example AI Usage:

<task>
  <action>create</action>
  <title>Implement user authentication</title>
  <description>Add login/logout functionality with JWT tokens</description>
</task>

MCP Tools

When MCP is enabled, external tools are available with mcp__ prefix:

const agent = new ProbeAgent({
  enableMcp: true,
  mcpConfig: {
    mcpServers: {
      'github': {
        command: 'npx',
        args: ['-y', '@modelcontextprotocol/server-github'],
        transport: 'stdio',
        enabled: true
      }
    }
  }
});

MCP tools appear as:

  • mcp__github__create_issue
  • mcp__github__list_pulls
  • mcp__filesystem__read_file

Tool Filtering

Control which tools are available to the AI:

// All tools (default)
const agent = new ProbeAgent({
  allowedTools: ['*']
});

// Specific tools only
const agent = new ProbeAgent({
  allowedTools: ['search', 'extract', 'query']
});

// Exclude specific tools
const agent = new ProbeAgent({
  allowedTools: ['*', '!bash', '!edit']
});

// No tools (conversation only)
const agent = new ProbeAgent({
  disableTools: true
});

Tool Execution Events

Monitor tool execution:

agent.events.on('toolCall', (event) => {
  console.log(`Tool: ${event.name}`);
  console.log(`Status: ${event.status}`);
  console.log(`Parameters: ${JSON.stringify(event.params)}`);

  if (event.status === 'completed') {
    console.log(`Duration: ${event.duration}ms`);
    console.log(`Result: ${event.result}`);
  }

  if (event.status === 'failed') {
    console.log(`Error: ${event.error}`);
  }
});