---
title: "Build with your coding agent"
url: https://services.dev/docs/start/agents
---
# Build with your coding agent

URL: https://services.dev/docs/start/agents

> The agent in your editor writes Services the way you would. AGENTS.md tells it the loop, check --json tells it what to fix, and every failure names the fix.

Your coding agent writes a Service and gets it ready to sell on its own, in one loop: change a file, run `check --json`, do what each failure's `next` says, and stop at `✓ ready to sell`.

## Connect it first

These docs are an MCP server at `https://services.dev/mcp`. Add it once:

**Claude Code**

```bash
claude mcp add --transport http services-docs https://services.dev/mcp
```

**Cursor**

```json title=".cursor/mcp.json"
{ "mcpServers": { "services-docs": { "url": "https://services.dev/mcp" } } }
```

**VS Code**

```json title=".vscode/mcp.json"
{ "servers": { "services-docs": { "type": "http", "url": "https://services.dev/mcp" } } }
```

Its tools are `search_docs`, `read_doc`, `explain_code` for any code, `get_operation` for any call and `get_key` for any key of `Service({...})`. An agent with no MCP client starts at [llms.txt](https://services.dev/llms.txt), which lists every page and bundle.

## The instructions it reads

`npx services.dev` writes AGENTS.md beside your Services, so the agent in your editor knows the loop from the first prompt:

```md
# Agent instructions

Each file in services/ is one Service you sell, and its .md file is the AI's brief.

- After every change, run `npx services.dev check --json` and fix each failure from its `doc_url`.
- One Service imports another with its .ts extension: `import translation from './translation.ts'`.
- Try a job: `npx services.dev dev` has an agent order one. Order more with `npx services.dev <service> field=value … --max <price>`.
- As the buyer: `npx services.dev accept <job>`, or `npx services.dev send-back <job> "<note>"` and the AI redoes it.
- Only if a Service has a `human` line: `npx services.dev approve <job>` approves, signs or does a job waiting on a person.
- An MCP client launches the brand with `npx services.dev mcp` (stdio), or connects to `http://localhost:8787/mcp` while dev runs.
- Drive the CLI with `--json`: every failure prints `{ type, code, reason, next, doc_url }`, and the exit code is its type's (`npx services.dev help`).
```

## The loop

Say your agent mistyped one step's name while it wired a registry filing into Translation. It runs `check --json`, as AGENTS.md says:

```txt
$ npx services.dev check --json
```

```json title="the failures"
{
  "services": [
    {
      "path": "services/translation.ts",
      "ok": false,
      "failures": [
        {
          "code": "step_unreachable",
          "reason": "A step no edge reaches never runs.",
          "next": "Fix its after, or route there with next. file names corect, which isn't a step; correct is routed, and no step has a next, a rejection or a fallback that can send the job there.",
          "doc_url": "https://services.dev/docs/reference/check/step_unreachable"
        },
        {
          "code": "release_unproven",
          "reason": "price.release names no step that runs.",
          "next": "Name a step that runs. price.release is 'file', and file never runs.",
          "doc_url": "https://services.dev/docs/reference/check/release_unproven"
        }
      ]
    }
  ]
}
```

The same answer carries every Service's ledger, margin, apps and MCP budget beside its failures:

```json title="the whole answer"
{
  "ai": {
    "cents_per_call": 42,
    "simulated": true
  },
  "mcp": {
    "tools": 13,
    "tokens": 4508,
    "sandbox": 9,
    "budget": 8000
  },
  "services": [
    {
      "path": "services/translation.ts",
      "lines": 21,
      "steps": "glossary · buyer · answer → translate · ai → harden · ai · adversarial · 2 lenses · then a person signs → file · the registry → correct · buyer · upload · routed → hand_off · buyer · answer · routed",
      "ok": false,
      "price": "$89 per job, within 48 hours, charged on file's receipt.",
      "who": "A sworn translator signs before the file step. The buyer answers at glossary.",
      "agent": {
        "tool": "order_translation",
        "words": 29,
        "job": "job_7Hq2",
        "status": "waiting",
        "on": "party",
        "charged": null,
        "person": true,
        "why": ""
      },
      "ledger": "+$89.00 · AI $1.26 (example) · sworn translator $30.00 · you $57.74",
      "approved_ledger": null,
      "outcome": null,
      "margin": {
        "floor": {
          "cents": 4120,
          "pct": 46
        },
        "own": 4120,
        "stop": 4780,
        "nested": []
      },
      "apps": [
        "customer portal",
        "delivery portal",
        "owner console"
      ],
      "failures": [
        {
          "code": "step_unreachable",
          "reason": "A step no edge reaches never runs.",
          "next": "Fix its after, or route there with next. file names corect, which isn't a step; correct is routed, and no step has a next, a rejection or a fallback that can send the job there.",
          "doc_url": "https://services.dev/docs/reference/check/step_unreachable"
        },
        {
          "code": "release_unproven",
          "reason": "price.release names no step that runs.",
          "next": "Name a step that runs. price.release is 'file', and file never runs.",
          "doc_url": "https://services.dev/docs/reference/check/release_unproven"
        }
      ]
    }
  ]
}
```

One typo failed two gates, and the first `next` names the typo. Every failure carries the same four fields:

| Field | What it is | What the agent does with it |
|---|---|---|
| `code` | an id, such as `step_unreachable` | branches on it, never on the words |
| `reason` | one sentence on what's wrong | quotes it when it reports back to you |
| `next` | the fix, in words at build time, or the exact call at run time | does it |
| `doc_url` | the gate's own page, such as [step_unreachable](https://services.dev/docs/reference/check/step_unreachable.md) | reads the failing file and its fix there |

`check` exits 1 until every Service is ready to sell, so [a CI step](https://services.dev/docs/cli/ci.md) can gate on it too.

The agent makes the one-line fix:

```diff
diff --git a/services/translation.ts b/services/translation.ts
index 3ef4330..36584f8 100644
--- a/services/translation.ts
+++ b/services/translation.ts
@@ -16,7 +16,7 @@ export default Service({
       submit: 'https://registry.example.test/filings',
       to: 'the registry',
       receipt: 'filing',
-      rejected: { missing_certificate: 'corect', '*': 'translate' },
+      rejected: { missing_certificate: 'correct', '*': 'translate' },
       perfect: '2d',
       fallback: 'hand_off',
     },
```

It checks again, and both gates pass: the second failure was the first one's echo.

```txt
$ npx services.dev check
services/translation.ts · 21 lines · $89 per job, within 48 hours, charged on file's receipt.
  who     A sworn translator signs before the file step. The buyer answers at glossary.
  steps   glossary · buyer · answer → translate · ai → harden · ai · adversarial · 2 lenses · then a person signs → file · the registry → correct · buyer · upload · routed → hand_off · buyer · answer · routed
  agent   order_translation · 29 of 30 words · job_7Hq2 waits on party
  ledger  +$89.00 · AI $1.26 (example) · sworn translator $30.00 · you $57.74
  margin  at least $41.20 a job (46%) · a job that stops costs you at most $47.80
  apps    customer portal · delivery portal · owner console

mcp     13 buyer tools · 4,508 of 8,000 tokens · 9 more with ?toolset=sandbox
✓ ready to sell · 1 Service · it keeps at least 46% of every job
```

## The same shape at run time

A running brand refuses in the same shape, so the agent that builds and the agent that buys follow one rule: send `next`. An order missing a field comes back as `next`, with the field to fill:

```json
{
  "type": "BLOCKED",
  "category": "invalid_request",
  "code": "input_invalid",
  "reason": "Missing to.",
  "param": "to",
  "next": {
    "do": "order",
    "service": "translation",
    "arguments": {
      "document": {
        "url": "https://example.com/lease.pdf",
        "name": "lease.pdf"
      },
      "max_usd": 49,
      "key": "lease",
      "to": null,
      "service": "translation"
    },
    "fill": [
      "to"
    ],
    "tool": "order_job",
    "http": "POST http://localhost:8787/jobs {\"service\":\"translation\"}"
  },
  "doc_url": "http://localhost:8787/docs/errors/input_invalid",
  "request_id": "req_m8cwgn",
  "simulated": true
}
```

An agent driving the CLI branches on the exit code, the failure's type:

```txt
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
```

Exit 5: hand the person the link in `next`. Exit 10: send the same call with the same `--key`, which never acts twice. Every shape is in [Answers](https://services.dev/docs/api/answers.md), and every code in [Errors](https://services.dev/docs/reference/errors.md).

## Start from your shape

Say the work, the price, where a person belongs, and the reference Service it resembles:

- "Write a Service like lingua: AI translates a document, $49 on delivery."
- "Write a Service like api.lawyer: AI drafts a provisional patent application, a registered patent agent signs before it's filed with the USPTO, the nonprovisional deadline lives on the patent, and it charges on the filing receipt."
- "Write a Service like apis.tax: a yearly Tax Plan that orders the return every February 1 and an estimate each quarter, with 12 questions and 2 notice responses included."
- "Write a Service like api.forsale: AI works a deal to close, a closer from our Pool takes deals of $50,000 and up, and it charges 5% of the closed value, proven by the payment."

## Next

**[Take the first real job](https://services.dev/docs/start/live.md)**: connect Stripe, deploy live, and get paid.

---

- Up: [Your first paid job](https://services.dev/docs.md)
- Previous: [All four, in one filing](https://services.dev/docs/grow/together.md)
- Next: [Take the first real job](https://services.dev/docs/start/live.md)
