# The command line

> Every API operation from a terminal, an agent's fields as types, test events on your own machine, and MCP over standard input.

One file, and it needs only Node.js 22 or later:

```sh
curl -O https://developers.aigently.ai/aigently.mjs
export AIGENTLY_API_KEY=ag_test_...
node aigently.mjs conversations list --limit 5
```

## Any API operation

Every operation in the [reference](/reference) is a command: its resource, its method, its ids in
order, and its fields as flags — the field's name with dashes.

```sh
node aigently.mjs agents retrieve 8a1f3c2e-…
node aigently.mjs conversations retrieve 5f0c9a52-… --include transcript
node aigently.mjs calls create --agent-id 8a1f3c2e-… --to-number +966501234567 \
  --variables '{"first_name": "Sara"}'
node aigently.mjs conversations list --agent-id 8a1f3c2e-… --all > conversations.jsonl
```

- **Lists take commas** (`--include transcript,cost`), or a JSON array when an item has a comma in
  it (`--turns '["Hi, are you open on Sunday?"]'`). **Objects take JSON**, and a file takes its
  path (`--file ./faq.pdf`). `null` sends null, which is how a number is detached from its agent.
- `--json '{…}'`, or `--json @body.json`, sends a whole body; flags add to it.
- **`--all` walks every page of a list**, printing one JSON object a line.
- **A request that takes an `Idempotency-Key` gets one**, unless you pass your own with
  `--idempotency-key`.
- The answer is printed as JSON. A refusal prints its `code`, `detail` and request id, and exits 1.

`node aigently.mjs operations` lists every command.

## An agent's fields as types

```sh
node aigently.mjs types --agent 8a1f3c2e-… > agent.ts
node aigently.mjs types --agent 8a1f3c2e-… --lang python > agent_fields.py
```

It writes the agent's [three lists of fields](/guides/variables) — what a conversation can start
with, what it collects, and what its analysis writes — as TypeScript interfaces or Python
`TypedDict`s, required fields marked. Write them again when the agent's fields change: the
`agent.updated` event says when. A field named like a Python keyword, such as `from`, is written
in the `TypedDict("…", {…})` form, which takes any name.

## Evaluations in a build step: `evaluate`

```sh
node aigently.mjs evaluate 8a1f3c2e-…
```

It rehearses the agent's saved conversations, waits for the verdict, prints every conversation's
outcome, and exits `0` when all passed, `1` when one failed, and `3` when none failed but some could
not be checked. `--json` prints the whole run instead, and `--timeout` says how many seconds to wait
(25 minutes unless you say). See [Evaluations in your pipeline](/guides/evaluations).

## A call, followed live: `follow`

```sh
node aigently.mjs follow 5f0c9a52-…
```

It prints what is said on a call as it is said — `Caller:` and `Agent:` lines — and stops when the
call ends. `--json` prints each line as the API sends it. See [Live calls](/guides/live-calls).

## Test events on your machine: `listen`

The platform cannot reach `localhost`. `listen` keeps a connection open to the API with a **test
key** and passes on everything a test webhook receiver would be sent — and, if you ask, the context
lookups of test calls — to a server on your machine.

```sh
node aigently.mjs listen --forward-to localhost:3000/hooks
```

- **Events.** Each test event is POSTed to `--forward-to` with the headers a webhook carries,
  signed with the session's own secret, which it prints when the connection is ready. Check them
  exactly as you would a receiver's ([how](/guides/webhooks#check-the-signature)). What your server
  answers is only printed.
- **Lookups.** With `--forward-lookups-to`, a test call's context lookup is POSTed there, and your
  server's status and body go back to the call as its answer — so a [test inbound
  call](/guides/inbound-calls#in-test-mode) reaches your own code. An open session is asked before
  the agent's test address or its sample answer.
- **Only what the key reaches.** A key limited to some projects or agents hears only about those,
  and is asked only their test calls' lookups.
- **Only what the key may read.** Listening needs `conversations:read`, and a
  `conversation.transcript` event also needs `transcripts:read`. Every key preset has both.
- **Test keys only.** A live key is refused when it connects: real conversations go to receivers
  whose addresses have been checked, never to a laptop.
- **A few at a time.** A key may keep 3 sessions open, and an organization 10.
- **It stops when the key does.** Revoke the key, let it expire, or rotate it without an overlap,
  and the session ends within half a minute.
- **Stop it and its session is gone**, with everything it was holding: the next test call's events
  go only to your test receivers.

## An AI assistant: `mcp`

`node aigently.mjs mcp` carries an assistant's [MCP](/guides/mcp) messages from standard input to
the API's MCP server, and the answers back — for an assistant that runs its tools as a local
program.

## Options

| Option | What it does |
|---|---|
| `--api-key <key>` | Your key. Or set `AIGENTLY_API_KEY`. |
| `--api <url>` | The API's address, for a company running its own copy. Or set `AIGENTLY_BASE_URL`. Default `https://api.aigently.ai`. |
| `--all` | For a list: every page, one JSON object a line. |
| `--idempotency-key <key>` | Your own id for a request that takes one. |
| `--forward-to <url>` | `listen`: where to POST each test event, like `localhost:3000/hooks`. |
| `--forward-lookups-to <url>` | `listen`: where to POST each test call's lookup. |
| `--help` | The options. |

Your key travels in a header, never in an address, where a proxy would log it.
