---
title: "The CLIs"
url: https://services.dev/docs/cli
---
# The CLIs

URL: https://services.dev/docs/cli

> Two command lines, rendered from one contract. services.dev is yours, to write, check, serve and test a brand. npx <brand> is your buyers', their agents' and your members'.

Your brand has two command lines, for two different people.

- **`services.dev` is yours.** It writes a Service, checks it, serves it on localhost, and drives every branch with magic values and test clocks.
- **`npx <brand>` is your buyers'.** It's published under your own package name, in your brand's words, and never names services.dev. Your buyers, their agents and the members of your Pool run it. Each deploy publishes it.

Both render one column of the [contract](https://services.dev/docs/surfaces/contract.md). Every command a buyer runs is a row of the [operations registry](https://services.dev/docs/reference/operations.md), the same row that gives the API its route, MCP its tool and the SDK method its name, so a command can never do something the other surfaces can't.

## The smallest form

In an empty folder, one command writes a Service and serves it. The banner prints the CLI's line beside every other surface's:

```txt
$ mkdir lingua && cd lingua
$ npx services.dev
  wrote   package.json · services/translation.ts · services/translation.md · AGENTS.md
lingua · AI delivers every job.
  site    http://localhost:8787/translation
  api     POST http://localhost:8787/jobs {"service":"translation"}
  key     sk_test_7Hq2 · a call with no key uses it, on localhost only
  mcp     http://localhost:8787/mcp · stdio: npx services.dev mcp
  cli     npx services.dev translation k=v …
  sdk     connect({ origin: 'http://localhost:8787' }).translation.order(input)
  docs    http://localhost:8787/llms.txt
  buyers  http://localhost:8787/portal
  you     http://localhost:8787/console
  AI and money are simulated until you wire them. $0.42 a call is an example.
```

[Your first paid job](https://services.dev/docs.md) runs it to an accepted job.

## Every command

`help` groups every command by who runs it: you, a buyer or their agent, the person at the line, and you again, testing in the sandbox.

```txt
magic values: none

$ npx services.dev help
services.dev

You
  npx services.dev                  write a Service if this folder has none, then serve it
  init [name]                       write services/<id>.ts, its brief and AGENTS.md
  dev [--port 8787] [--members N --market tight|normal|flush]  serve every Service on localhost; an agent orders a first job
  check [--json]                    what each Service sells and leaves you, and anything to fix
  sdk [--out sdk]                   write the brand's typed client: index.js, index.d.ts and package.json
  diff <before> <after>             what a change does on the API, CLI, MCP, SDK, Site, Docs and App
  verify [--url <url>] [--surface http|mcp|all] [--suite <file|url>]  run a brand's conformance suite against it, or any suite@1 document: pass, fail, skipped
  mcp [--url <url>]                 serve this folder's MCP server on stdio, or relay to a running brand's
  tasks offer <task> <member>       name the member a Task goes to
  clocks assign <clock> <member>    assign the member who answers for a clock
  members login <member>            mint a member's own session on localhost
  asks get <ask>                    read an ask
  jobs export <job>                 one job's evidence bundle
  jobs ledger <job>                 one job, as the owner reads it

A buyer, or their agent
  <service> k=v …                   order a job: --max <usd>, --key <key>, --approved, --policy k=v, --metadata k=v, --test-clock <tc_>
  jobs get <job>                    read a job
  jobs wait <job>                   wait up to 50 seconds for a job to finish
  jobs list                         the buyer's jobs, newest first
  jobs accept <job>                 accept a delivered job
  jobs send-back <job> <note>       send a job back with a note, and the AI redoes it
  jobs cancel <job>                 cancel a job before delivery
  jobs end <job> <end>              end a job at one of its ends, as that end's by allows
  jobs again <job>                  order an ended job again
  jobs set-policy <job> k=v …       set a job's policy values within their bounds
  jobs signal <job> <signal>        raise one of the Service's inbound signals
  clocks list                       the clocks your jobs and their subjects run
  clocks get <clock>                read a clock
  clocks ack <clock>                acknowledge a clock you answer for
  clocks satisfy <clock>            close a clock you answer for, on evidence on the record
  clocks choose <clock> <option>    choose one of a clock's lapse options at its date
  subscriptions list                your subscriptions
  subscriptions get <subscription>  read a subscription
  subscriptions cancel <subscription>  cancel a subscription
  asks reissue <ask>                reissue an open ask's link, to hand to its party again
  jobs files put <job> <path>       put a file in a job's documents plane under its own sha256
  jobs files get <job> <sha256>     read a file a job holds, by its sha256

A person: at your line, or a member in their own session
  jobs approve <job>                approve, sign or do a job waiting on a person
  members add <pool> <email> k=v …  join a Pool, email first and resumable
  me availability <availability>    set your availability
  me ledger                         read your conflicts ledger
  me ledger add <name> k=v …        add a party to your conflicts ledger
  tasks list                        your feed
  tasks get <task>                  read a Task's teaser
  tasks sheet <task>                read a Task's sheet
  tasks pass <task> <reason>        pass on a Task
  tasks claim <task>                claim a Task
  tasks clear <task>                clear a held Task
  tasks packet <task>               read a cleared Task's packet
  tasks release <task>              give a held Task back before it is done

Testing, in the sandbox
  test-clocks create <frozen_at>    make a test clock frozen at a time
  test-clocks advance <clock> <to>  move a test clock to a time, or by a span
  events list                       the brand's events after a seq
  listen [--forward-to <url>]       the brand's events
  watches create <url>              watch events at a URL
  watches list                      the watches this key holds, with their deliveries
  watches delete <watch>            stop a watch
  watches replay <watch>            deliver to a watch again every event it covers after a seq
  events send <type>                send an event in

v2's short names
  order <service> k=v …             order a job: --max <usd>, --key <key>, --approved, --policy k=v, --metadata k=v
  get <job>                         jobs get
  wait <job>                        jobs wait, until it stops working
  accept <job>                      jobs accept
  send-back <job> <note>            jobs send-back
  cancel <job>                      jobs cancel
  approve <job>                     jobs approve
  tick <span> [--test-clock <tc_>] [--market <m>]  test-clocks advance: move dev's own clock, or --test-clock that one, such as 7d; --market checks dev's simulated market
  trigger <type>                    events send: fire a synthetic event, or raise a signal

  --json         print the answer as the API sent it; every failure prints the one error shape (or SERVICES_DEV_JSON=1)
  --ai <usd>     what one simulated AI call costs (0.42, an example figure)
  --no-try       dev skips the first job
  SERVICES_DEV_KEY  the key each call sends as Authorization: Bearer; on localhost, none uses the test key
  SERVICES_DEV_SESSION  a member's own session, from members login: the member commands act in it
  --attest <statement>  tasks clear: each statement on the sheet, word for word, once each
  --affirm <item>       jobs approve and tasks attest: each checklist item the person affirms

Exit codes
  0 ok · 1 check failed · 2 usage · 3 invalid request · 4 authentication · 5 blocked: a person must act · 6 conflict or guard · 10 retry: api error, rate limited, nothing running

npx services.dev help --json lists every command with its operation; npx services.dev <command> --help shows one.
```

Seven commands read the folder: `init`, `dev`, `check`, `sdk`, `diff`, `verify` and `mcp`. Every other command is generated from the operations registry: add a row and its command appears, with no CLI code to write. A Service is ordered by its own id, so `translation` is a command the moment the file exists.

## Every command is a row

A command's own help prints the row it runs, as every other surface renders it:

```txt
$ npx services.dev jobs send-back --help
npx services.dev jobs send-back <job> <note>
  send a job back with a note, and the AI redoes it
  row     job.send_back · POST /jobs/:id/send_back · send_back_job · jobs.sendBack()
  note    What to fix.
  key     Any string you choose: the same key replays the first answer and never acts twice. The Idempotency-Key header does the same.
  exit    0 ok · 2 usage · 3 invalid request · 4 authentication · 5 blocked · 6 conflict · 10 retry
```

Every command that acts is safe to retry: it is idempotent by nature, like `jobs accept`, or it takes a `key`, like this one. The join is checked, not hoped for: `check` fails [`surface_drift`](https://services.dev/docs/reference/check/surface_drift.md) when a command has no row, or a live row has no command. [In CI](https://services.dev/docs/cli/ci.md) shows it failing on a Service named like a command.

## One job, four surfaces

On localhost, your brand's CLI is `services.dev` itself. A buyer's command runs against `dev` exactly as your buyers' will, and gets the job every other surface returns:

**CLI**

```txt
$ npx services.dev translation document=https://example.com/lease.pdf to=fr-CA --max 49 --key lease
job_7Hq2 · working · $49.00 held
job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged
  record  draft · ai | review · ai · pass
  ledger  +$49.00 · AI $0.84 · you $48.16
  next    npx services.dev accept job_7Hq2
```

**API**

```txt
$ curl -X POST http://localhost:8787/jobs -H 'content-type: application/json' -d '{"service":"translation","document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","max_usd":49,"key":"lease"}'
← 202 · job_7Hq2 · working · $49.00 held
  next    get_job {"id":"job_7Hq2"}
```

**MCP**

```txt
→ tools/call order_translation {"document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","max_usd":49,"key":"lease"}
← job_7Hq2 · working · $49.00 held
  next    get_job {"id":"job_7Hq2"}
```

**SDK**

```txt
await lingua.translation.order({"document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","max_usd":49,"key":"lease"})
← job_7Hq2 · working · $49.00 held
  next    get_job {"id":"job_7Hq2"}
```

The capture fails unless all four return the same body, request ids aside. The CLI also waits for delivery and prints the record and the ledger, because on localhost you're the owner. Set a key and it reads the job as that key does, with the buyer's view only: [Install and log in](https://services.dev/docs/cli/install.md) shows both.

## Your brand's CLI

`npx <brand>`

Each deploy publishes `npx <brand>` under your package name, beside your generated SDK. It renders the same column in your brand's own words, from `Brand.words` ([the contract](https://services.dev/docs/surfaces/contract.md)), and adds `login` for buyers. The members of your Pool get their own commands under a member's session, for the acts the delivery portal offers: attest, send back, decline and release. No key and no agent can run those. Its pages live in your brand's docs, one per command, so your buyers never land on services.dev.

## Built for agents

Every command takes `--json`, or reads `SERVICES_DEV_JSON=1` from an agent's environment. It prints the answer as the API sent it, and every failure as the one error shape: `type`, `category`, `code`, `reason`, `next` and `doc_url`. The exit code is the failure's category, so an agent or a CI job branches without reading the words. [Build with your coding agent](https://services.dev/docs/start/agents.md) puts it to work.

## Next

- [Install and log in](https://services.dev/docs/cli/install.md): npx, a global install, and the key each call sends.
- [In CI](https://services.dev/docs/cli/ci.md): `check --json`, exit codes, magic values and test clocks.
- [Listening locally](https://services.dev/docs/cli/listen.md): `listen --forward-to` and `trigger`.

---

- Up: [Your first paid job](https://services.dev/docs.md)
- Previous: [Your conformance suite](https://services.dev/docs/api/verify.md)
- Next: [Install and log in](https://services.dev/docs/cli/install.md)
