Skip to content

Latest commit

 

History

History
148 lines (119 loc) · 4.78 KB

File metadata and controls

148 lines (119 loc) · 4.78 KB

Tool Patterns & Chaining Reference

CLI Tool Mapping

Sandbox tools mirror Copilot CLI built-in tools:

Copilot CLI Sandbox call_tool() Host implementation
view call_tool('view', path=..., view_range=...) Path.read_text(), line slicing
create call_tool('create', path=..., file_text=...) Path.write_text() (fails if exists)
edit call_tool('edit', path=..., old_str=..., new_str=...) String replace (exactly 1 match)
glob call_tool('glob', pattern=..., paths=...) Path.glob()
grep / rg call_tool('grep', pattern=..., paths=..., glob=...) rg subprocess (requires ripgrep)
bash call_tool('bash', command=..., timeout=...) subprocess.run(shell=True)
sql call_tool('sql', query=..., db_path=...) sqlite3 module
web_fetch call_tool('web_fetch', url=..., method=...) curl subprocess
github-mcp-server-* call_tool('github_api', endpoint=..., method=..., body=...) gh api subprocess

Always available (no dependencies)

tool description
view Read file contents or list directory
create Create a new file (fails if exists)
edit Surgical string replacement in a file
glob Find files by glob pattern
bash Run shell commands (high risk)
sql Execute SQLite queries

Conditionally available

tool requires description
grep rg (ripgrep) Search file contents
web_fetch curl Fetch URLs
github_api gh CLI GitHub REST API

Return types (critical — wrong assumptions cause retries)

  • call_tool('glob', ...)list[str] e.g. ["src/app.py", "src/utils.py"]
  • call_tool('view', ...)str (full file content)
  • call_tool('bash', ...)dict with stdout, stderr, returncode
  • call_tool('mcp_call', ...)str
  • call_tool('web_fetch', ...)str (HTML auto-stripped to text, capped at 20K)
  • Brace expansion works: call_tool('glob', pattern='src/{db,services}/**/*.py')

Chaining Patterns

Sequential: search -> read -> analyze

for f in call_tool('glob', pattern='**/*.py', paths='src'):
    content = call_tool('view', path=f)
    lines = content.splitlines()
    todos = [l for l in lines if 'TODO' in l]
    if todos:
        print(f"{f}: {len(todos)} TODOs")
        for t in todos:
            print(f"  {t.strip()}")

Nested composition

# Read config found by glob
config = call_tool('view',
    path=call_tool('glob', pattern='**/config.json')[0])

Fan-out / fan-in (multi-repo)

import json as _json
repos = ['repo-a', 'repo-b', 'repo-c']
all_issues = []
for repo in repos:
    raw = call_tool('github_api', endpoint=f'/repos/myorg/{repo}/issues')
    all_issues.extend(_json.loads(raw))
print(f"Total open issues: {len(all_issues)}")

Data pipeline with SQL

import json as _json

# Create and populate a table from API data
call_tool('sql', query='CREATE TABLE IF NOT EXISTS issues (id INT, title TEXT, state TEXT)')

raw = call_tool('github_api', endpoint='/repos/owner/repo/issues?per_page=50')
issues = _json.loads(raw)
for issue in issues:
    call_tool('sql', query=f"INSERT INTO issues VALUES ({issue['number']}, '{issue['title']}', '{issue['state']}')")

# Query the data
open_count = call_tool('sql', query='SELECT COUNT(*) as cnt FROM issues WHERE state="open"')
print(f"Open issues: {open_count[0]['cnt']}")

Search and edit

# Find and fix a pattern across files
hits = call_tool('grep', pattern='http://', paths='src', glob='*.py')
for line in hits.strip().splitlines():
    filepath = line.split(':')[0]
    content = call_tool('view', path=filepath)
    if 'http://' in content and 'https://' not in content:
        call_tool('edit', path=filepath,
                  old_str='http://', new_str='https://')
        print(f"Fixed: {filepath}")

Error-tolerant batch processing

import json as _json
files = call_tool('glob', pattern='*.json', paths='config')
for f in files:
    try:
        raw = call_tool('view', path=f)
        data = _json.loads(raw)
        print(f"{f}: OK ({len(data)} keys)")
    except Exception as e:
        print(f"{f}: ERROR - {e}")

Custom Tool Definitions

Add to the manifest JSON:

{
  "name": "count_lines",
  "description": "Count lines in a file",
  "parameters": {"path": {"type": "string", "required": true}},
  "implementation": {"type": "shell", "command_template": "wc -l < {path}"}
}
{
  "name": "calculate",
  "description": "Evaluate a math expression",
  "parameters": {"expression": {"type": "string", "required": true}},
  "implementation": {"type": "python", "code": "result = eval(expression, {'__builtins__': {}}, {'abs': abs, 'min': min, 'max': max, 'round': round})"}
}