Early Access
The workflow builder that lives in Claude Code.
Describe the automation. Your coding agent writes a clean, typed TypeScript job, tests it against real events, and deploys it serverless.
Install
npx terse-cli@latest installCreate
/terse-create describe your workflowWorks with
Built for coding agents to do their best work
How Terse works in Claude Code: create and improve workflows
claude
Claude Code v2.1.42
Fable 5 · Anthropic API
~/projects/deal-desk
/terse-create When someone signs up in WorkOS, sync them to Attio — create the company if it's new, add the person, and get the deal into our Sales pipeline.
One question before I research: if the company already exists, should a signup still move its deal along? I'd recommend yes, with a note on the deal.
Yes — and note who signed up.
Interview done. Scanning your workspace and researching the docs.
Read src/terse.generated.ts — WorkOS and Attio are connected; Triggers.workos.onUserCreated covers this.
Research done — here's the workflow drawn out:
┌─────────────────────────────────┐
│ WorkOS user signs up │
└────────────────┬────────────────┘
▼
┌─────────────────────────────────┐
│ Upsert the person in Attio │
└────────────────┬────────────────┘
│ match by email domain
▼
┌─────────────────────────────────┐
│ Upsert the company │
└────────────────┬────────────────┘
▼
┌─────────────────────────────────┐
│ agent: file the deal in Sales │
│ create if new, pick the stage, │
│ note who signed up │
└─────────────────────────────────┘Does this match what you have in mind?
Match — build it.
Building in milestones: trigger wiring, then the Attio writes, the deal agent last.
Wrote src/jobs/workos-attio-sync.ts (28 lines)
Now a pinned real signup through the full job — I expect a person, a company, and a deal in Sales.
⏵ terse test run workos-attio-sync --id 4f21
The test ran as expected: person upserted, company created, deal filed with a note.
The workflow is ready locally. Deploy it to production with terse deploy?
Deploy.
⏵ terse deploy — synced. Triggers active at deal-desk-workos-attio-sync.terse.run.
src/jobs/workos-attio-sync.ts
import { createJob, generateText } from "terse-sdk"// generated types for your workspace ↓import { Triggers, Skills, AttioList, toolbox } from "./terse.generated" createJob({ name: "workos-attio-sync", triggers: [Triggers.workos.onUserCreated()], onTrigger: async (event) => { const user = event.data const domain = user.email.split("@")[1] // deterministic tool calls ↓ const company = await toolbox.attio.upsertCompany({ domain }) await toolbox.attio.upsertPerson({ email: user.email, name: `${user.firstName} ${user.lastName}`, companyId: company.id, }) // agentic reasoning, ACL'd skills ↓ await generateText({ prompt: `Add ${company.name} to the Sales pipeline: create the deal if it's new, pick the right stage, leave a short note.`, skills: [Skills.attio({ list: AttioList.Sales })], }) },})claude
Claude Code v2.1.42
Fable 5 · Anthropic API
~/projects/deal-desk
/terse-improve Attio is filling up with companies called gmail.com and outlook.com.
Pulling recent runs to see where those come from.
Read 50 runs from workos-attio-sync. 19 created a company from a personal email domain.
Personal signups shouldn't create companies. I'll skip the company for free-mail domains and file those people under Self-serve instead.
Modified workos-attio-sync.ts (+10 −0)
Replaying the 19 runs.
19/19 now route to Self-serve. The junk companies are still in Attio, though.
Cleaning those up, then shipping.
Deleted 19 companies. Deployed in 2.1s.
src/jobs/workos-attio-sync.ts+10−0
import { createJob, generateText } from "terse-sdk"import { Triggers, Skills, AttioList, toolbox } from "./terse.generated"const FREE_MAIL = new Set(["gmail.com", "outlook.com", "yahoo.com"])createJob({name: "workos-attio-sync",triggers: [Triggers.workos.onUserCreated()],onTrigger: async (event) => {const user = event.dataconst domain = user.email.split("@")[1]// personal signups → Self-serve, no company recordif (FREE_MAIL.has(domain)) {return toolbox.attio.addToList({list: AttioList.SelfServe,email: user.email,})}const company = await toolbox.attio.upsertCompany({ domain })await toolbox.attio.upsertPerson({email: user.email,name: `${user.firstName} ${user.lastName}`,companyId: company.id,})await generateText({prompt: `Add ${company.name} to the Sales pipeline: create thedeal if it's new, pick the right stage, leave a short note.`,skills: [Skills.attio({ list: AttioList.Sales })],})},})
Why Terse
Equipped to build production workflows.
What your agent gets out of the box with each approach.
| Capability | Agent + raw MCPs | Low-codeZapier · n8n | Agent + Cloudflare Worker | Agent + Terse |
|---|---|---|---|---|
| Type-safe workspace context engineToken-efficient | Not included | Not included | Not included | Included |
| Skills that teach your agent to build correctly | Not included | Not included | Not included | Included |
| Connect tools via OAuth or API keys | Not included | Included | Not included | Included |
| Durable workflows | Not included | Included | Not included | Included |
| Full trace and replay of every executionEasily available to the agent | Not included | Not included | Not included | Included |
| Learns from previous runs | Not included | Not included | Not included | Included |
Integrations
Trigger from your stack, act on your stack.
OAuth or API key, connected once. GitHub, Slack, cron, and webhooks kick workflows off; typed clients for the rest let your agent read and write without hand-rolled requests.
GitHub
Slack
Linear
NotionAttio
Gmail
Snowflake
PostHog
Datadog
LaunchDarkly
ApolloWorkOS
HeyReachResend
Google Search ConsoleMeta Ads
Higgsfield
Don’t see your tool? The skill can wire up a custom integration on the spot, though a native one is faster and more reliable. Tell us on Slack and we’ll add it.
Ready?
Your first workflow in 60 seconds.
Install the skill, describe the workflow, and your coding agent writes, tests, and deploys it.
Install
npx terse-cli@latest installCreate
/terse-create describe your workflow




