Your own Service
Add the work you sell to your brand, brief the AI that does it, check it until it's ready, and sell it on every surface.
In the same folder, init adds a second Service to your brand:
$ npx services.dev init "Store Listing"
wrote services/store-listing.ts · services/store-listing.md
kept package.json · AGENTS.md
next npx services.dev devFill in what comes in, what goes out and the price. Here is Store Listing, finished:
import { Service } from 'services.dev'
export default Service({
name: 'Store Listing',
description: 'Your app store listing, written for each language you sell in.',
input: { app: 'text: what the app does, such as a budgeting app for couples', languages: 'language[]: such as fr, de, ja', tone: ['plain', 'playful'] },
output: { listing: 'file' },
price: 29,
})languages is a list, and tone is a list of choices. The such as in each field is what an agent sends when it tries the Service.
The brief is your know-how, and the AI reads it on every job. init writes the questions. Answer them the way you'd brief someone new:
# Store Listing
The AI reads this brief on every job. Write it the way you'd brief someone new.
## How the work is done
- Read what the app does, then write a title, a subtitle, keywords and a description in each language.
- Write each language fresh, the way a native speaker would, never word for word from English.
- Count every field against the store's limit before you call the job done.
## What good looks like
- A title a buyer would type into the store's search, in their own language.
- The tone the buyer chose, in every language.
## Never
- Never claim a feature the app doesn't have.
- Never name a competitor.Say your first description ran long:
$ npx services.dev check
services/store-listing.ts · 5 lines · $29 per job, within 48 hours, charged on delivery.
who AI delivers every job.
steps draft · ai → review · ai · adversarial
agent order_store_listing · 45 of 30 words · bought job_7Hq2 · $29.00 · no person
ledger +$29.00 · AI $0.84 (example) · you $28.16
margin at least $23.20 a job (80%) · a job that stops costs you at most $5.80
apps customer portal · owner console
✗ The tool description is over 30 words, so agents skim past it. Shorten description: the tool description is 45 words.
https://services.dev/docs/reference/check/description_too_longEach failure says why, what to do next, and where it's explained. Shorten it, and run check again:
$ npx services.dev check
services/store-listing.ts · 5 lines · $29 per job, within 48 hours, charged on delivery.
who AI delivers every job.
steps draft · ai → review · ai · adversarial
mcp 14 buyer tools · 5,133 of 8,000 tokens · 9 more with ?toolset=sandbox
agent order_store_listing · 24 of 30 words · bought job_7Hq2 · $29.00 · no person
ledger +$29.00 · AI $0.84 (example) · you $28.16
margin at least $23.20 a job (80%) · a job that stops costs you at most $5.80
apps customer portal · owner console
services/translation.ts · 4 lines · $49 per job, within 48 hours, charged on delivery.
who AI delivers every job.
steps draft · ai → review · ai · adversarial
agent order_translation · 24 of 30 words · bought job_7Hq2 · $49.00 · no person
ledger +$49.00 · AI $0.84 (example) · you $48.16
margin at least $39.20 a job (80%) · a job that stops costs you at most $9.80
apps customer portal · owner console
mcp 14 buyer tools · 5,105 of 8,000 tokens · 9 more with ?toolset=sandbox
✓ ready to sell · 2 Services · AI delivers both alone · each keeps at least 80% of every jobEvery check has an agent buy a job, so you know agents can before a buyer tries.
Stop dev, and start it again with npx services.dev dev --no-try, so no agent orders first. Then order Store Listing and wait for it, on whichever surface you like:
$ npx services.dev store-listing "app=a budgeting app for couples" languages=fr,de tone=plain --max 29 --key listing
job_7Hq2 · working · $29.00 held
job_7Hq2 · delivered · listing.txt · $29.00 charged
record draft · ai | review · ai · pass
ledger +$29.00 · AI $0.84 · you $28.16
next npx services.dev accept job_7Hq2$ curl -X POST http://localhost:8787/jobs -H 'content-type: application/json' -d '{"service":"store-listing","app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"}'
← 202 · job_7Hq2 · working · $29.00 held
next get_job {"id":"job_7Hq2"}
$ curl http://localhost:8787/jobs/job_7Hq2?wait=50
← 200 · job_7Hq2 · delivered · listing.txt · $29.00 charged
next accept_job {"id":"job_7Hq2"}→ tools/call order_store_listing {"app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"}
← job_7Hq2 · working · $29.00 held
next get_job {"id":"job_7Hq2"}
→ resources/read job://job_7Hq2?wait=50
← job_7Hq2 · delivered · listing.txt · $29.00 charged
next accept_job {"id":"job_7Hq2"}await lingua.storeListing.order({"app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"})
← job_7Hq2 · working · $29.00 held
next get_job {"id":"job_7Hq2"}
await lingua.jobs.wait("job_7Hq2")
← job_7Hq2 · delivered · listing.txt · $29.00 charged
next accept_job {"id":"job_7Hq2"}You never wrote a route, a command, a tool or an SDK call. Each one comes from the Service: one file, every surface.
- Make it harder to get wrong: harden it, the first of the Grow steps.
- Have your own model do the work: AI steps and briefs.
- Let the agent in your editor run this loop for you: build with your coding agent.