Agent tools
All tools available to the Cantrip agent, grouped by category. These tools are used by both the main conversation loop and background subagents.
You do not call these tools directly. The agent selects and uses them autonomously based on the current task. This reference is for understanding what the agent can do.
File operations
| Tool | Description |
|---|---|
read_file |
Read a file's contents |
write_file |
Create or overwrite a file |
edit_file |
Replace a specific string in a file |
multi_edit |
Apply multiple edits to one or more files atomically |
list_directory |
List files and directories |
grep |
Search file contents with regex |
glob |
Find files matching a glob pattern |
Code intelligence
Read-only structured navigation over the active charm. All three tools share a single in-memory index that reuses the repo-map's parser; the index persists to .cantrip-codeintel.json and refreshes automatically when source files change. The agent reaches for these tools when a question is exact-symbol-shaped (MyCharm._on_install, RepoMap.render_for_prompt); broad text searches still fall through to grep.
| Tool | Description |
|---|---|
code_symbols |
Search workspace symbols by name with deterministic match policy (exact qualified > exact > prefix > fuzzy) |
code_definition |
Resolve a symbol to its defining file/line plus a bounded snippet, with ambiguity surfaced as multiple candidates |
code_references |
List every recorded callsite for a symbol with file:line locations and an honest truncation count |
The same surface is also reachable from the chat:
/symbols <query>,/definition <symbol>,/references <symbol>— slash commands with the same output shape as the tool calls.@symbol <query>,@definition <symbol>,@references <symbol>—@-mention providers that expand inline in a user message.
Worked example — finding everywhere a method is called:
code_references symbol="IngressHandler.refresh"src/charm.py:42 refresh tests/unit/test_charm.py:78 refresh2 references to
IngressHandler.refreshacross 2 files
Coverage starts deliberately narrow: Python source plus charm metadata YAML (charmcraft.yaml, metadata.yaml, config.yaml, actions.yaml). Rust, Go, shell, and Terraform stay literal-text territory.
Charm development
| Tool | Description |
|---|---|
charmcraft_init |
Scaffold a new charm project |
charmcraft_pack |
Pack a charm into a .charm file |
quick_pack |
Fast packing without charmcraft's full lifecycle (no LXD) |
charm_validate |
Validate charm metadata and structure |
charmcraft_fetch_libs |
Fetch charm libraries from Charmhub |
analyse_framework |
Detect application framework and suggest charm path |
charm_audit |
Comprehensive charm quality audit |
charmlint |
Run 35+ deterministic lint rules |
harness_inventory |
Survey tests/ for remaining ops.testing.Harness usages, with a per-file harness/scenario/mixed breakdown |
scenario_coverage |
Audit observer-to-test coverage and flag missing can_connect=False / relation-broken event-shape tests |
inspect_env_keys |
Sweep an application source tree for environment-variable references (os.getenv, process.env.X, System.getenv, Spring ${...}, .env rows) and return a deduplicated key list plus per-file usage map; per-framework env contracts ported from canonical/skills |
operational_readiness |
Evaluate against Canonical's Operational Readiness Metrics |
Juju operations
| Tool | Description |
|---|---|
juju_status |
Get current model status |
juju_deploy |
Deploy a charm |
bundle_deploy |
Deploy an existing Juju bundle.yaml (with optional overlays). Legacy consumption only; prefer juju_deploy + juju_relate for new deployments |
juju_refresh |
Refresh a deployed charm to a new revision |
juju_relate |
Create a relation between applications |
juju_config |
Set application configuration |
juju_get_app_config |
Read current application configuration |
juju_run_action |
Run a charm action |
juju_ssh |
SSH into a unit |
juju_wait |
Wait for a unit to reach a target status |
juju_dispatch |
Dispatch a custom event to a unit |
juju_add_model |
Create a new Juju model |
juju_destroy_model |
Destroy a Juju model |
juju_offer |
Create a cross-model relation offer |
juju_consume |
Consume a cross-model relation offer |
juju_list_offers |
List available cross-model offers |
juju_list_secrets |
List Juju secrets |
juju_show_secret |
Show secret contents |
juju_read_relation_data |
Read relation data bags |
charm_sync |
Sync charm source to a deployed unit |
Testing
| Tool | Description |
|---|---|
run_charm_tests |
Run unit or integration tests |
generate_tests |
Generate test scaffolding |
test_report |
Generate a test results report |
hook_benchmark |
Benchmark hook execution times |
fuzz_test |
Fuzz test charm event handlers |
chaos_test |
Run chaos testing scenarios |
scaling_test |
Test scaling behaviour |
upgrade_test |
Test charm upgrade paths |
generate_load_test |
Generate load test scripts |
Acceptance testing
| Tool | Description |
|---|---|
action_exerciser |
Exercise every charm action with valid inputs |
relation_smoke |
Smoke-test all relation endpoints |
workload_endpoint |
Verify workload endpoints respond |
config_variation |
Test config option variations |
config_under_load |
Test config changes under load |
acceptance_report |
Generate an acceptance test summary |
Observability
| Tool | Description |
|---|---|
juju_debug_log |
Read Juju debug log |
juju_stream_logs |
Stream Juju logs in real time |
tempo_query |
Query distributed traces from Tempo |
loki_query |
Query logs from Loki |
grafana_screenshot |
Render a Grafana panel or dashboard as a PNG (via /render); saves the image to ~/.cache/cantrip/screenshots/ and returns a caption plus the file path |
tempo_waterfall |
Render a Tempo trace as a waterfall PNG — one bar per span along a time axis, slowest spans highlighted; vision-capable providers see the image alongside the caption |
juju_status_render |
Render the current juju status as a coloured tree PNG — apps grouped with their units, status glyphs per node, relations listed below; saves to ~/.cache/cantrip/screenshots/ and attaches the image for vision-capable providers |
Git and GitHub
| Tool | Description |
|---|---|
git_clone |
Clone a repository |
git_init |
Initialise a new git repository |
git_status |
Show working tree status |
git_diff |
Show file diffs |
git_log |
Show commit history |
git_add |
Stage files for commit |
git_commit |
Create a commit |
git_push |
Push commits to remote |
gh_repo_create |
Create a GitHub repository |
gh_repo_bootstrap |
Apply default repo settings (branch protection, issue templates, CI workflow stub) |
gh_pr_create |
Create a pull request |
gh_issue_list |
List GitHub issues |
pr_review |
Review a pull request |
pr_review_reply |
Reply to PR review comments |
Web and search
| Tool | Description |
|---|---|
web_search |
Search the web |
web_fetch |
Fetch and extract content from a URL |
charmhub_search |
Search Charmhub for charms |
charmhub_info |
Get detailed info about a Charmhub charm |
registry_search |
Search Docker registries for images |
registry_image_info |
Get image metadata from a registry |
Publishing
| Tool | Description |
|---|---|
charmcraft_upload |
Upload a charm to Charmhub |
charmcraft_release |
Release a charm revision to a channel |
generate_readme |
Generate a README for the charm |
generate_icon |
Generate a charm icon |
generate_docs |
Generate charm documentation; bridges root TUTORIAL.md / DEMO.md / architecture.md into the Diátaxis tree when present, and populates tutorial / how-to from demo/ and ACCEPTANCE.md artefacts when acceptance tests have run |
generate_diagram |
Generate architecture or integration diagrams |
extract_design_decisions |
Refresh docs/explanation/architecture.md with a chronological design-decision log mined from the session transcript; preserves charm-author intro |
extract_troubleshooting |
Mine error→fix pairs from the session transcript and write docs/how-to/troubleshooting.md grouped by category (relation / hook / secret / image / network / storage / observability / general); preserves charm-author intro |
generate_terraform |
Generate Terraform module for the charm |
validate_terraform |
Validate a generated Terraform module |
Rockcraft and OCI
| Tool | Description |
|---|---|
rockcraft_init |
Scaffold a rockcraft project |
rockcraft_pack |
Pack a rock (OCI image) |
check_rock_contract |
Validate a repo against the rockcraft framework contract for a 12-factor framework (Flask, Django, FastAPI, Express, Spring Boot, Go) — blocking issues, advisory warnings, supported base: values |
skopeo_registry_push |
Push an OCI image to a registry |
Environment
| Tool | Description |
|---|---|
concierge_prepare |
Prepare the development environment (Juju, LXD, MicroK8s) |
concierge_status |
Check environment readiness |
preflight_targets |
Snapshot kubectl context, Juju controllers, rockcraft / charmcraft / skopeo presence and snap channel, plus the experimental-extension env vars expected by the chosen framework — runs before kicking off a 12-factor build |
list_inference_snaps |
List available local inference snaps |
run_command |
Run a shell command |
wait_for |
Block until a typed condition is true (file appears, port opens, command exits zero, juju app reaches active/idle) |
wait_for — typed waits
Use wait_for instead of scripting until …; do sleep loops or hanging a turn on a long-timeout subprocess. Predicates are tagged so the schema is enumerable; command_exits_zero runs argv directly (no shell pipeline) and is gated by the same destructive-shape policy as run_command.
| Predicate | Required arguments | Poll cadence |
|---|---|---|
file_exists |
path |
0.5s |
file_absent |
path |
0.5s |
process_exited |
pid |
0.5s |
port_open |
port (optional host, default 127.0.0.1) |
0.5s |
command_exits_zero |
command (argv list; base must be one of charmcraft, juju, make, pytest, test) |
5s |
juju_app_active_idle |
app (optional model) |
delegates to juju wait-for --timeout |
Every call requires timeout_seconds (capped at 1800). Successful calls return a one-line caption like juju app prom reached active/idle after 47.2s; timeouts return success=false with timed_out=true in the result data.
Worked example — wait for charmcraft pack to finish a long build, then for the app to settle:
wait_for(
predicate="command_exits_zero",
command=["charmcraft", "pack"],
timeout_seconds=900,
)
wait_for(
predicate="juju_app_active_idle",
app="my-charm",
timeout_seconds=600,
)
For waits that must span turns (the autonomous loop should stop while you wait), use /pause and /resume instead — wait_for blocks the current tool call only.
Memory
Durable learning tools. The agent calls these when the auto-writer
needs to persist a lesson, or when the user drives a
/memory, /remember, or
/forget slash command. See the
memory how-to for workflow.
| Tool | Description |
|---|---|
memory_list |
Summaries-only listing across charm + global scopes, filterable by kind/tag/status |
memory_read |
Load one memory’s full body by title; charm-scope shadows global-scope when titles collide |
memory_search |
Case-insensitive substring search across titles and bodies |
memory_write |
Create or overwrite a memory (kind, scope, body, tags, citations) |
memory_update |
Partial update by title; any omitted field is left unchanged |
memory_revalidate |
Re-check citation SHAs and quarantine entries whose source has drifted |
memory_sweep |
Archive entries untouched for 60+ days (soft-expiry TTL) |
memory_purge_check |
Surface archived entries older than 180 days as deletion candidates |
memory_forget |
Permanently delete a memory |
MCP-sourced tools
When servers are declared in cantrip.mcp.yaml,
Cantrip registers each of their tools with the qualified name
mcp__<server>__<tool>. The agent calls
them exactly like a built-in tool; the MCP client handles the
wire protocol, OAuth, elicitation, and reconnects. The per-server
allowed_tools list in the YAML is the authoritative
gate on which names surface.
Since the set varies per deployment, they aren’t listed
here — run /mcp tools <server> in the
chat to see what a connected server exposes. See the
MCP how-to for configuration.
Internal
These tools manage the agent's own state. They are not typically visible to the user but are important for how the agent operates.
| Tool | Description |
|---|---|
plan_tasks |
Decompose an intent into a task plan using the LLM |
manage_tasks |
Inspect, cancel, or reprioritise tasks in the work queue |
oracle_consult |
Route one focused question to a stronger reasoning model and return the answer without committing the main session to it; bounded by a per-turn call cap and a per-session USD cap (see multi-model patterns) |
load_skill |
Load a specialised skill prompt for the current task |
workspace_info |
Read a cantrip.workspace.yaml manifest (charms, cross-charm relations, shared config) from the current tree or any ancestor directory |
virtual_file_read |
Read a compressed virtual file from context |
virtual_file_search |
Search across virtual files |
showboat |
Generate a Showboat demo from the charm |
rodney |
Scaffold a Rodney demo |