# Build with a coding agent

URL: /code/build-with-a-coding-agent · Id: `page:code/build-with-a-coding-agent`

> Point a coding agent at a Startup project with its briefing file, two MCP servers, a scoped test key and the Change loop.

`npm create startups` writes `AGENTS.md` and `.mcp.json`, so a coding [Agent](/business/nouns/agent) works the [Startup](/business/nouns/startup) from its first prompt. The agent edits files, calls [Verbs](/business/nouns/verb) and ships through [Changes](/business/nouns/change), never around them.

## Prerequisites
- A project from `npm create startups`. The examples use `leaseline.app`, which tracks lease renewals for small property managers at $29 a month.
- A coding agent that reads `AGENTS.md` and connects to MCP servers over streamable HTTP.

## Steps
1. Read the `AGENTS.md` the project ships. It is the agent's whole briefing, and you edit it freely:

   ```md title="AGENTS.md"
   # Leaseline

   This repository defines Leaseline. Its files compile into the running business.

   ## Before you write
   - Connect both MCP servers in .mcp.json.
   - Fetch /$.d.ts from the leaseline server: the types of $, cut to your key.
   - Read the convention for a file before you change it: https://startupbuilder.dev/code/file-conventions

   ## While you work
   - Keep npx startup-builder dev running. Each save previews as a Change.
   - Print a Verb's input with npx startup-builder schema <Noun.verb> before you call it.
   - Rehearse every write with --try, or mode "try" in the do tool.

   ## Never
   - Never edit generated/ or .sb/. Name secrets in env.ts; never write a value.
   - Never call Stripe or any outside API directly. Call the Verb.
   - Never use --env live. Shipping is Change.review, then the founder's Version.deploy.
   ```

2. Check `.mcp.json`. It connects two servers: the Startup itself on [api.sb](/code/platform/api-sb), and these docs:

   ```json title=".mcp.json"
   {
     "mcpServers": {
       "leaseline": { "url": "https://api.sb/mcp?ns=leaseline.app" },
       "startupbuilder-docs": { "url": "https://startupbuilder.dev/mcp" }
     }
   }
   ```

   The first acts on the business through `search`, `fetch` and `do` ([MCP](/code/mcp)). The second reads documentation and needs no key ([docs for agents](/start/docs-for-agents)).

3. Give the agent its own test key, scoped to the Verbs it needs and expiring on its own:

   ```bash
   npx startup-builder keys create --name coding-agent --scope leaseline.app --verbs Offer.publish,Change.review --expire-in 30d
   ```

   Set it as `STARTUP_BUILDER_API_KEY` in the agent's shell. A test key never touches live data or real money ([keys](/code/api/guides/keys)).

4. Start the dev server in a second terminal, so every edit compiles and previews:

   ```bash
   npx startup-builder dev
   ```

5. Ask for a change in plain words, such as "add a 60-day notice field to leases". The agent edits `nouns/Lease.mdx`, the dev server recompiles, and a broken convention fails with the file and line.

6. When the preview is right, have the agent review the Change. Every test and [Evaluator](/business/nouns/evaluator) runs on the preview:

**Ask**

   ```text
   Review my change.
   ```

**API**

   ```bash
   curl -X POST https://api.sb/leaseline.app/changes/change_1/review \
     -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
   ```

**SDK**

   ```ts
   import { $ } from 'startup-builder'

   const change = await $.Change.review({ change: 'change_1' })
   ```

**CLI**

   ```bash
   npx startup-builder do Change.review --json '{"change":"change_1"}'
   ```

**MCP**

   ```json
   {
     "name": "do",
     "arguments": { "code": "return await $.Change.review({ change: 'change_1' })" }
   }
   ```

7. Merge and deploy the Change. [Ship my changes](/code/ship-my-changes) shows the calls; `Version.deploy` asks the founder first, so the agent never ships to customers alone.

## Result
The agent edits files, checks each call against the types before it runs, and ships only reviewed Changes. A write over the key's [Limit](/business/nouns/limit) waits `pending` for an [Approval](/business/nouns/approval) instead of failing.

An agent offers only what these docs document. The founder's words map to guides in [/asks.json](/asks.json); anything not documented, the agent does not offer.

## Next steps
- [Every file convention](/code/file-conventions): what the agent writes, file by file.
- [MCP](/code/mcp): `search`, `fetch` and `do` on a Startup.
- [Run the CLI in CI](/code/cli/guides/ci): the same checks on every pull request.