Skip to main content

Tool reference

AILANG World serves 8 tools. Each one is a pure AILANG transition that plans exactly one brokered effect, runs it inside your episode's worktree, and commits one World log entry. The MCP tool name and the A2A skill id are both the tool id below.

Rules that apply to every tool:

  • Arguments are strict. A key outside the schema is refused by the plan, never ignored. The refusal commits a log entry with zero effects.
  • Paths are relative to the worktree root: non-empty, no .. segment, no leading -. AILANG's policy layer refuses anything that resolves outside the worktree (absolute paths, symlinks leading out), keeps .git/ read-only, and keeps the operator's deny list read-only.
  • One call costs 1 from the session's budget for the tool's effect. Budgets count calls, not time or tokens.
  • Every result carries world: {effects:[{id, status, record}], plan}. See Results and errors.
ToolEffect (grant needed)ArgumentsFinish phase
ailang-readWorkspace.Read (scope worktree)pathno
ailang-writeWorkspace.Write (scope worktree)path, contentno
ailang-editWorkspace.Write (scope worktree)path, old_text, new_textno
ailang-checkAilang.Check (scope worktree)pathyes
ailang-runAilang.Run (scope worktree)path, args_json?, stdin?, argv?, caps?no
builtins-searchAilang.Discover (scope worktree)query?, module?yes
examples-searchAilang.Discover (scope worktree)queryno
ailang-cliAilang.CLI (scope worktree)op, path?, module?, query?, package?, flags?no

Six grants cover the eight tools: ailang-write and ailang-edit share Workspace.Write, and the two searches share Ailang.Discover. Two more, Ailang.RunEnv and Ailang.RunNet, let ailang-run take the Env or Net capability when the operator enables it. tools/list shows only the tools whose effect your session holds a grant for. A grant with budget 0 still lists the tool, but every call is denied:budget.

ailang-read​

Read (sandboxed). Effect Workspace.Read, scope worktree, cost 1 per call. Handler: policy-tool read. Module: packages/se-tools/se_tools/read.ail.

Description served in tools/list:

Read a file inside this episode's worktree (policy-tool `read`). The path is relative to the worktree root, non-empty, with no `..` segment and no leading `-`; anything that resolves outside the worktree (absolute, `..`, or a symlink leading out) is refused by AILANG's policy layer, and `.git/` plus the operator's deny list stay read-only. Unknown argument keys are refused, never ignored. Returns {ok, content} or {ok:false, refused}. Costs one Workspace.Read call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
pathstringyesFile path, relative to the worktree root

additionalProperties is false: any other key is refused.

Result​

ok, content, tool (the tool binary ref), policy_digest, world.

Output schema properties: content, ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"
missing required argument "path"
argument "path" must be a string

From the handler or AILANG's policy layer (the effect ran with status ok; the output says ok: false):

read /etc/hosts: path "/etc/hosts" escapes sandbox "<worktree>"
read nope.ail: openat nope.ail: no such file or directory

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-read","arguments":{"path":"hello.ail"}}}

ailang-write​

Write (sandboxed). Effect Workspace.Write, scope worktree, cost 1 per call. Handler: policy-tool write. Module: packages/se-tools/se_tools/write.ail.

Description served in tools/list:

Create or overwrite a file inside this episode's worktree (policy-tool `write`). The path is relative to the worktree root, non-empty, with no `..` segment and no leading `-`; anything that resolves outside the worktree (absolute, `..`, or a symlink leading out) is refused by AILANG's policy layer, and `.git/` plus the operator's deny list stay read-only. Unknown argument keys are refused, never ignored. Returns {ok} or {ok:false, refused}. Costs one Workspace.Write call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
pathstringyesFile path, relative to the worktree root
contentstringyesThe complete new file content

additionalProperties is false: any other key is refused.

Result​

ok, tool, policy_digest, world.

Output schema properties: ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"
missing required argument "content"
unknown argument "old_text"; ailang-write admits only: path, content

From the handler or AILANG's policy layer (the effect ran with status ok; the output says ok: false):

write .git/config: .git/ is read-only to the lane's tools
write .ailang/x.ail: matches fs_deny_write ".ailang/**" — read-only under this policy

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-write","arguments":{"path":"notes/todo.txt","content":"first line\n"}}}

ailang-edit​

Edit (sandboxed). Effect Workspace.Write, scope worktree, cost 1 per call. Handler: policy-tool edit. Module: packages/se-tools/se_tools/edit.ail.

Description served in tools/list:

Replace old_text with new_text in a file inside this episode's worktree (policy-tool `edit`); old_text must occur exactly once (include enough context). The path is relative to the worktree root, non-empty, with no `..` segment and no leading `-`; anything that resolves outside the worktree (absolute, `..`, or a symlink leading out) is refused by AILANG's policy layer, and `.git/` plus the operator's deny list stay read-only. Unknown argument keys are refused, never ignored. Returns {ok} or {ok:false, refused}. Costs one Workspace.Write call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
pathstringyesFile path, relative to the worktree root
old_textstringyesExact text to replace (must occur exactly once)
new_textstringyesReplacement text

additionalProperties is false: any other key is refused.

Result​

ok, tool, policy_digest, world.

Output schema properties: ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"
missing required argument "new_text"
unknown argument "old"; ailang-edit admits only: path, old_text, new_text

From the handler or AILANG's policy layer (the effect ran with status ok; the output says ok: false):

edit hello.ail: old_text occurs 8 times; include more context so it is unique
edit hello.ail: old_text not found — the file may have changed; read it again

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-edit","arguments":{"path":"hello.ail","old_text":"println(\"hello from ailang-run\")","new_text":"println(\"hello from pi\")"}}}

ailang-check​

AILANG Check. Effect Ailang.Check, scope worktree, cost 1 per call. Handler: policy-tool ai_check. Module: packages/se-tools/se_tools/check.ail.

Description served in tools/list:

Type-check and Z3-verify an AILANG file inside this episode's worktree (policy-tool `ai_check`) and return STRUCTURED diagnostics: {ok:true, passed, error_count, errors:[{code, message, file}]} (line and column stay inside message), or {ok:false, status, refused}. The path is relative to the worktree root, non-empty, with no `..` segment and no leading `-`; anything that resolves outside the worktree (absolute, `..`, or a symlink leading out) is refused by AILANG's policy layer, and `.git/` plus the operator's deny list stay read-only. Unknown argument keys are refused, never ignored. Costs one Ailang.Check call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
pathstringyesPath to the .ail file, relative to the worktree root

additionalProperties is false: any other key is refused.

Result​

ok, passed, error_count, errors, world (the finish output; no tool or policy_digest).

The finish phase parses ai_check's JSON report into ok: true, passed, error_count and errors (each code, message, file; line and column stay inside message). ok: true means the check ran; passed is the verdict. When no report is produced the result is ok: false with status and refused (for example the Ailang.Check effect ended denied).

Output schema properties: passed, error_count, errors, status, ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"
unknown argument "limit"; ailang-check admits only: path

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-check","arguments":{"path":"hello.ail"}}}

ailang-run​

AILANG Run (policy-gated). Effect Ailang.Run, Ailang.RunEnv, Ailang.RunNet, scope worktree, cost 1 per call. Handler: ailang run --policy <policy> [--args-json J] -- <path> [-- <argv...>] with stdin piped in (cwd = the worktree root). The policy is the episode's base policy for an IO/FS run, otherwise a per-cap-set variant World renders and AILANG's policy-tool summary verifies before its first use. Module: packages/se-tools/se_tools/run.ail.

Description served in tools/list:

Execute an AILANG program inside this episode's worktree under the operator's policy: `ailang run --policy <policy> [--args-json J] -- <path> [-- <argv...>]`, from the worktree root, with `stdin` piped in. `caps` is the run's EXACT capability set, like the grader's `--caps` (default IO and FS): distinct names from Declassify, Env, FS, IO, Net, never Env with Net; each beyond IO and FS must also be enabled by the operator (`serve --run-allow-caps`), or the call is refused. An Env run is the effect Ailang.RunEnv and a Net run Ailang.RunNet, each needing its own session grant; any other run, Declassify included, is Ailang.Run. Net reaches only the loopback host:port pairs the operator named (`serve --run-net-allow`); every other host, port and redirect is refused. `argv` (at most 32 strings, each at most 1024 bytes, no NUL) always follows an inner `--`, so it never reaches the run's flag parser; `stdin` is text of at most 65536 bytes (absent = empty). The program's declared effect row must be a subset of the rendered policy's allowed_caps; an unrequested FS is admitted at budget 0, so it fails at first use; the run is bounded by the policy's timeout (8 s). Returns {admitted, exit_code, decision, limit, stdout, stderr, policy}; policy is {digest, security_mode, caps, net_allow} of the variant that ran. Denied programs never execute; read `decision.missing_from_policy` and narrow the program's effects or widen `caps`. A refused inner effect can still exit 0, so read stdout and stderr, not only exit_code. The program's inner effects are governed by the AILANG policy layer, not brokered one by one. The path is relative to the worktree root, non-empty, with no `..` segment and no leading `-`; anything that resolves outside the worktree (absolute, `..`, or a symlink leading out) is refused by AILANG's policy layer, and `.git/` plus the operator's deny list stay read-only. Unknown argument keys are refused, never ignored. Costs one call of its effect from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
pathstringyesPath to the .ail file, relative to the worktree root
args_jsonstringnoJSON arguments for the entrypoint (passed as --args-json)
stdinstringnoThe program's whole standard input, at most 65536 UTF-8 bytes (absent = empty)
argvarray of stringnoProgram arguments (getArgs), passed after an inner --; at most 32, each at most 1024 bytes, no NUL
capsarray of Declassify / Env / FS / IO / NetnoThe run's exact capability set (default IO, FS); never Env with Net

additionalProperties is false: any other key is refused.

Result​

admitted, exit_code, decision, limit, stdout, stderr, policy, world. policy is {digest, security_mode, caps, net_allow} of the policy the run executed under. See Results and errors for the four outcome shapes.

Which effect a call spends follows caps: with Env it is Ailang.RunEnv, with Net it is Ailang.RunNet, otherwise Ailang.Run (a Declassify run included). Each needs its own grant, and each capability beyond IO and FS must also be enabled by the operator (serve --run-allow-caps), or the handler refuses the call before anything runs (the effect is recorded failed). A Net run reaches only the loopback host:port pairs the operator named with --run-net-allow. See Tool confinement.

Output schema properties: admitted, exit_code, decision, limit, stdout, stderr, ok, refused, world, policy (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"
argument "args_json" must be a string holding JSON
argument "args_json" must be a string
argument "stdin" is 65537 bytes; the limit is 65536
argument "argv" has 33 items; the limit is 32
an argv item is 1025 bytes; the limit is 1024
an argv item contains a NUL byte
unknown capability "Process"; caps admits only: Declassify, Env, FS, IO, Net
capability "IO" is listed twice
caps names both Env and Net; one run takes at most one of them
unknown argument "env"; ailang-run admits only: path, args_json, stdin, argv, caps

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-run","arguments":{"path":"benchmark/solution.ail","caps":["IO"],"stdin":"1\n2\n3\n4\n5\n"}}}

Search AILANG builtins. Effect Ailang.Discover, scope worktree, cost 1 per call. Handler: policy-tool builtins_list (text form, no flags). Module: packages/se-tools/se_tools/builtins_search.ail.

Description served in tools/list:

Search the REAL builtin inventory compiled into the tool binary (policy-tool `builtins_list`, text form). Pass query (case-insensitive substring over name/module/effect; at most 10 matches) and/or module (e.g. 'std/fs'); omit both for the full list. Use this instead of guessing builtin names. Returns {count, matches}, each match {name, module, effect}. Degraded: no signature or description is returned or searched (policy-tool caps a CLI op's stdout at 64 KiB and the JSON inventory exceeds it); use ailang-cli `builtins_show` or examples-search for usage. A truncated or unparseable inventory is refused, never an empty result. Unknown argument keys are refused, never ignored. Costs one Ailang.Discover call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
querystringnoSubstring to look for
modulestringnoModule filter, e.g. std/fs

additionalProperties is false: any other key is refused.

Result​

count, matches (each name, module, effect), world.

The finish phase parses the Total: N builtins header and one name [effect] module line per builtin, then keeps entries where module contains the module argument and query is a substring of name, module or effect (both case-insensitive). With a query, at most 10 matches are returned; count is the number returned, not the inventory total. A truncated or unparseable inventory is ok: false with status and refused, never an empty list. Matches carry no signature or description: use ailang-cli op builtins_show for those.

Output schema properties: count, matches, status, ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

unknown argument "limit"; builtins-search admits only: query, module
argument "query" must be a string

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"builtins-search","arguments":{"query":"println"}}}

Search AILANG examples. Effect Ailang.Discover, scope worktree, cost 1 per call. Handler: policy-tool examples_search over the corpus named by serve --examples-dir. Module: packages/se-tools/se_tools/examples_search.ail.

Description served in tools/list:

Search the AILANG examples corpus this daemon serves (policy-tool `examples_search`; the operator's --examples-dir) for `query`, then read a hit with ailang-cli op examples_show. The op admits no flags, so there is no limit argument. Use this before writing a construct you are unsure of. Returns {ok, argv, exit_code, stdout, stderr}, or {ok:false, refused} when no corpus is configured. Unknown argument keys are refused, never ignored. Costs one Ailang.Discover call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
querystringyesText to search the examples for

additionalProperties is false: any other key is refused.

Result​

ok, argv, exit_code, stdout, stderr, tool, policy_digest, world. Read a hit with ailang-cli op examples_show.

Output schema properties: stdout, ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

missing required argument "query"
unknown argument "limit"; examples-search admits only: query

From the handler or AILANG's policy layer (the effect ran with status ok; the output says ok: false):

no examples corpus configured: start ailang-worldd serve with --examples-dir DIR (an AILANG examples corpus: manifest.json plus runnable/; `ailang examples download` makes one at ~/.ailang/examples)

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"examples-search","arguments":{"query":"fold"}}}

ailang-cli​

AILANG CLI (policy-allowlisted). Effect Ailang.CLI, scope worktree, cost 1 per call. Handler: policy-tool, op from the binary's cli list. Module: packages/se-tools/se_tools/cli.ail.

Description served in tools/list:

Run an allowlisted ailang operation as a typed policy-tool request. ops: agent_prompt, ai_check, axioms, builtins_list, builtins_show, check, devtools_prompt, docs_search, examples_list, examples_search, examples_show, examples_tags, fmt, iface, pkg_docs, policy_check, prompt, test, tree, version. Field by op: check/ai_check/fmt/tree/policy_check: {path}; iface/pkg_docs: {module}; docs_search/examples_search: {query}; examples_show/builtins_show: {module: <name>}; test: {path?, package?}; flags: {"json": "", "limit": "5"} only where the op admits them (boolean flags take ""). fmt's write flag is refused: ailang-cli never writes (fmt returns the formatted text; save it with ailang-write). NOT read/write/edit (their own tools) and NOT run (ailang-run). Paths and package directories follow the worktree path rule. Unknown argument keys are refused, never ignored. Returns {ok, argv, exit_code, stdout, stderr} or {ok:false, refused}. Costs one Ailang.CLI call from the session's budget. Every call commits one World log entry; the result carries `world` (the effect plan and the brokered effect's record ref).

Arguments​

NameTypeRequiredDescription
opstringyesThe operation, e.g. "check", "iface", "docs_search", "test"
pathstringnoIn-worktree file path (check, ai_check, fmt, tree, policy_check, test)
modulestringnoModule path or name (iface: "std/fs"; examples_show/builtins_show: a name)
querystringnoSearch text (docs_search, examples_search)
packagestringnoPackage directory for test (in-worktree)
flagsobject of stringnoAdmitted flags by name; boolean flags take "" (e.g. {"json": ""})

additionalProperties is false: any other key is refused.

Admitted ops and their flags (v0.52.1 tool binary). Pass flags as {"name": "value"}; boolean flags take "".

opFieldsAdmitted flags
agent_promptnonenone
ai_checkpath--timeout
axiomsnonenone
builtins_listnone--by-effect --by-module --json --module --query --verbose
builtins_showmodule (a name)none
checkpath--json --quiet --strict-syntax
devtools_promptnonenone
docs_searchquery--json --limit
examples_listnone--status --tags
examples_searchquerynone
examples_showmodule (a name)none
examples_tagsnonenone
fmtpath--check (--write is refused)
ifacemodule--compact
pkg_docsmodulenone
policy_checkpathnone
promptnonenone
testpath, package (both optional)--allow-skips --json --no-color --package
treepathnone
versionnonenone

Result​

ok, argv, exit_code, stdout, stderr, tool, policy_digest, world.

Output schema properties: argv, exit_code, stdout, stderr, ok, refused, world (required: world).

Refusals you will see​

From the plan (zero effects, world.effects is [], still committed):

op "read" is not an ailang-cli op; reads, writes and edits have their own tools, and run is ailang-run
op "fmt" flag "write" writes the worktree; ailang-cli never writes (fmt without it returns the formatted text; write it with ailang-write)
argument "flags" must be an object of string values
missing required argument "op"
path "<p>" refused: it must be relative and non-empty, with no ".." segment and no leading "-"

From the handler or AILANG's policy layer (the effect ran with status ok; the output says ok: false):

op check does not admit flag --zz (admitted: --json --quiet --strict-syntax)

Example call​

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ailang-cli","arguments":{"op":"iface","module":"std/io","flags":{"compact":""}}}}

This page is generated by website/scripts/gen-tool-reference.mjs from packages/se-tools/transitions.json (refusal texts transcribed from packages/se-tools/se_tools/*.ail). Do not edit it by hand: change the sources and run node website/scripts/gen-tool-reference.mjs from the repo root.