# curator — instructions for AI agents

curator reads source code in any language and says, for each statement,
which of five operations it performs. Use it to see what code does without
reading every line yourself.

Every example below is run by curator's test suite
(`crates/curator-cli/tests/agents_md.rs`) and its output compared byte for
byte, so what you see here is exactly what the `curator` binary of this
version prints. `curator guide` prints this file from inside the binary.

## The five operations

| `op` | The statement… | Example |
|---|---|---|
| `read` | takes a value from outside the computation (input, file, network, env) | `x = input()` |
| `change` | makes a new value from values it already has | `total = a + b` |
| `branch` | lets a value decide what runs next (if, case, assert, guard) | `if x > 0:` |
| `write` | sends a value out (print, file, network, `return`) | `print(x)` |
| `repeat` | runs something again | `for i in range(n):` |

Lines that do none of these (blank lines, braces, imports, definitions,
comments) are left out, or have `"op": null` with `--all`.

## Install

Linux or macOS (x86_64 or arm64), no other dependencies:

```text
curl -fsSL https://curator.rajvansh.dev/install.sh | sh
```

It installs `curator` into `~/.local/bin` (set `CURATOR_INSTALL_DIR` to
change that) after checking its SHA-256 against
`https://curator.rajvansh.dev/SHA256SUMS`. Other systems: build from the
source at `https://curator.rajvansh.dev/curator-src.tar.gz` with
`cargo install --path crates/curator-cli` (Rust 1.83+ and a C compiler).

This guide is for this version:

```console
$ curator --version
curator 0.1.0
```

## Read code: `curator read`

```text
curator read [PATHS]... [--name NAME] [--format jsonl|tsv] [--all]
```

- `PATHS`: files or directories; `-` means stdin. Default: `.`.
  Directories are walked in sorted order; `.git`, `target`, `node_modules`,
  `vendor`, `dist`, `build`, `__pycache__` and non-code files are skipped.
- `--name`: the file name for stdin; its extension picks the language.
- `--format`: `jsonl` (default) or `tsv`.
- `--all`: include lines that perform no operation.

Output (`jsonl`): one JSON object per line, keys always in this order:

| Key | Type | Meaning |
|---|---|---|
| `file` | string | the path as given (or `--name` for stdin) |
| `line` | integer | 1-based line number |
| `op` | string or null | `read`, `change`, `branch`, `write`, `repeat` |
| `reader` | string | `parser` (a real grammar read the file) or `sheath` (shape-based fallback) |
| `text` | string | the line, trimmed |

A file:

```console
$ curator read examples/agents/hello.py
{"file":"examples/agents/hello.py","line":5,"op":"branch","reader":"parser","text":"if not name:"}
{"file":"examples/agents/hello.py","line":6,"op":"write","reader":"parser","text":"return \"hello, world\""}
{"file":"examples/agents/hello.py","line":7,"op":"write","reader":"parser","text":"return \"hello, \" + name"}
{"file":"examples/agents/hello.py","line":10,"op":"repeat","reader":"parser","text":"for arg in sys.argv[1:]:"}
{"file":"examples/agents/hello.py","line":11,"op":"write","reader":"parser","text":"print(greet(arg))"}
```

The same as tab-separated `file:line<TAB>op<TAB>text`:

```console
$ curator read examples/agents/hello.py --format tsv
examples/agents/hello.py:5	branch	if not name:
examples/agents/hello.py:6	write	return "hello, world"
examples/agents/hello.py:7	write	return "hello, " + name
examples/agents/hello.py:10	repeat	for arg in sys.argv[1:]:
examples/agents/hello.py:11	write	print(greet(arg))
```

Code from stdin (`--name` gives it a language):

```console
$ printf 'total = price * qty\nif total > 100:\n    print("big")\n' | curator read - --name order.py
{"file":"order.py","line":1,"op":"change","reader":"parser","text":"total = price * qty"}
{"file":"order.py","line":2,"op":"branch","reader":"parser","text":"if total > 100:"}
{"file":"order.py","line":3,"op":"write","reader":"parser","text":"print(\"big\")"}
```

Every line, including those that do nothing:

```console
$ printf 'x = 1\n\n# note\n' | curator read - --name a.py --all
{"file":"a.py","line":1,"op":"change","reader":"parser","text":"x = 1"}
{"file":"a.py","line":2,"op":null,"reader":"parser","text":""}
{"file":"a.py","line":3,"op":null,"reader":"parser","text":"# note"}
```

Exit status: `0` on success; `1` if a path could not be read (the error
goes to stderr, other paths are still read); `2` for bad arguments.

```console
$ curator read does/not/exist.py; echo "exit $?"
curator: does/not/exist.py: no such file or directory
exit 1
```

## Use it as a tool: `curator mcp`

`curator mcp` is a Model Context Protocol server on stdin/stdout (one
JSON-RPC 2.0 message per line). It offers two tools:

- `curator_read`: arguments `path` (file or directory) or `code` + `name`,
  and optional `all`. Returns the same JSON Lines as `curator read`, as one
  text block.
- `curator_guide`: returns this file.

Add it to Claude Code:

```text
claude mcp add curator -- curator mcp
```

Any other MCP client: run the command `curator` with the argument `mcp`.

A full exchange:

```console
$ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"0"}}}' '{"jsonrpc":"2.0","method":"notifications/initialized"}' '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"curator_read","arguments":{"code":"print(1)\n","name":"a.py"}}}' | curator mcp
{"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{}},"protocolVersion":"2025-06-18","serverInfo":{"name":"curator","version":"0.1.0"}}}
{"id":2,"jsonrpc":"2.0","result":{"content":[{"text":"{\"file\":\"a.py\",\"line\":1,\"op\":\"write\",\"reader\":\"parser\",\"text\":\"print(1)\"}\n","type":"text"}],"isError":false}}
```

## How far to trust it

On random lines of real code it has never seen, labelled by hand before
scoring, curator is right about 9 times in 10 (see the table in
`README.md`). Treat each `op` as a strong hint, not a proof: when a
decision matters, read the `text` it points to. It knows structure from
grammars (C, C++, C#, Go, Java, JavaScript, TypeScript, Python, Ruby, Rust,
PHP, Swift, Bash) and meaning from a dictionary of common calls; other
languages are read by shape alone (`"reader": "sheath"`).

## Other commands

- `curator guide`: print this file.
- `curator translate`: submit results to a Cura registry (for Cura
  operators; see `README.md`).