Furrow Forms

bootstrap_site · one call provisions a site's whole form backend

The only form backend your agent runs autonomously.

From no account to verified webhooks — registration, provisioning, snippets, spam, email — over MCP and REST. One workspace runs every site you ship. Everyone else still needs a human in the loop.

paste this into your agent

Fetch furrowforms.com/ai and set up forms for this site.
agent · claude-code
[ mcp ]

Set up forms for the Acme Astro site. Domain acmeroofing.com, these Turnstile keys, webhook to our CRM. Contact form and quote form.

⚙ bootstrap_site · client ✓ project ✓ forms (contact, quote) ✓

✎ edit src/pages/contact.astro

+ <form action="https://api.furrowforms.com/s/fp_k7m2" method="POST">
+   <div class="cf-turnstile" data-sitekey="0x4AAA…"></div>

⚙ test_webhook ·200 OK · signature verified

Done — both forms live, webhook verified.

How it works

You paste one prompt. Your agent does the rest.

01[ /api/register ]

It opens the account and configures the site

Your agent registers over the API — you read it one 6-digit code from your email — then sets security once on the project: Turnstile keys, allowed domains, notify emails, webhook, rate limits, file uploads.

02[ bootstrap_site ]

It spins up every form you asked for

Contact, quote, careers, newsletter — one idempotent bootstrap_site call. Each form gets a POST URL and inherits the site’s configuration automatically. Overrides only where you said so.

03[ test_webhook ]

It ships the snippet and proves it works

Generated frontend code for HTML, Astro, or Next.js — honeypot and Turnstile included — pasted into your repo. Then a signed test delivery: 200 OK, signature verified, before it says “done.”

[ or ] prefer hands-on? The dashboard does all three with clicks — same API underneath. Open the dashboard →

Settings inheritance

Configure the website, not every form

Other form backends make you repeat configuration on every single form. In Furrow, security and routing live on the project — one website — and every form under it inherits automatically. Overrides exist, but they're opt-in.

  • [ 01 ]Rotate Turnstile keys once — every form on the site uses the new ones immediately.
  • [ 02 ]Change the notification list on the project — all forms pick it up. No sweep, no drift.
  • [ 03 ]Agencies: one client, many websites, zero repeated setup across the roster.
acme — hierarchy
[ cascade ]
client/acme-roofing

project/acmeroofing.com

  • turnstile keys
  • allowed domains
  • notify emails
  • webhook + secret
  • rate limits
  • honeypot
  • uploads + inbox
form/contactinherits all
form/quoteinherits all
form/careersinherits alloverride: notify → hr@acme.com

Agent control plane

Every product surface, operable over MCP and REST

MCP and REST share the exact same domain logic — there is no drift between what agents and humans can do. The dashboard is a thin viewer over the same API. 26 tools cover the entire product, every create is idempotent by slug, and built-in MCP resources let agents self-orient.

level 1 — the baseline

Readable by agents

An llms.txt tells agents what the product is. Most form backends stop here.

level 2 — most of the field

Specifiable by agents

An agent assembles a setup link — then hands off to a human to click, sign in, and paste an endpoint back.

level 3 — Furrow Forms

Operable by agents

An agent registers the account, creates the client, configures the site, spins up every form, pulls the snippet, and verifies the webhook. Zero clicks — starting from no account.

[ you are here ]
mcp · bootstrap_site
[ idempotent ]
{
  "client": { "name": "Acme Roofing" },
  "project": {
    "domain": "acmeroofing.com",
    "turnstile": { "site_key": "0x4AAA…", "secret": "•••" },
    "notify": ["leads@acmeroofing.com"],
    "webhook": { "url": "https://crm.example.com/hooks/furrow" }
  },
  "forms": [
    { "slug": "contact", "fields": ["name", "email", "message"] },
    { "slug": "quote",   "fields": ["name", "email", "sqft", "zip"] }
  ]
}

26 tools · a sample

  • bootstrap_site
  • create_client
  • create_project
  • update_project
  • create_form
  • update_form
  • get_snippet
  • list_submissions
  • test_webhook
  • archive_form
  • +16 more

Streamable HTTP at /mcp or local stdio, authenticated with a bearer token your agent can mint itself — cold-start registration lives at /api/register. Retries never duplicate; creates are idempotent by slug.

MCP server docs →

Spam stack

Four layers deep. On by default.

[ zero config required ]

01[ _gotcha ]

Honeypot

A hidden field bots can’t resist. Trips are silently dropped — no fake "clean" submission is ever stored.

02[ project-level ]

Cloudflare Turnstile

Privacy-friendly challenge, on by default. Keys live on the project — rotate once, every form follows.

03[ origin check ]

Domain allowlist

Submissions are only accepted from origins you list per project. Everything else bounces.

04[ 429 ]

Rate limiting

Per-IP, per-form. 10 requests per 60 seconds by default, configurable when you need it.

Delivery

Every submission lands twice: inbox and webhook

Email that reads like a human wrote it

Notifications go to the project's list — forms can override. Subjects and intros take template tokens with fallbacks, and your field contract keeps every email human-readable.

notification template
subject: New lead from {{project.name}} — {{name | "someone"}}
intro:   Submission #{{count}} on {{form.name}}
fields:  your form's fields, human-readable
meta:    page URL · origin · UTM · submission ID

Recipients are set per project — change the list once, every form follows.

Webhooks you can actually trust

Every delivery is HMAC-SHA256 signed with timestamp, event, and delivery-ID headers — verify authenticity, reject replays. Automatic retries with backoff, up to 8 attempts over ~24 hours, with a full delivery log per project.

delivery headers
[ verified ]
X-Furrow-Signature: sha256=9f2b41…
X-Furrow-Timestamp: 1755712803
X-Furrow-Event:     submission.created
X-Furrow-Delivery:  dlv_2mq8…

One call to test_webhook verifies the wiring before you go live.

File uploads follow the same rule. Enable them once per site and visitors attach files on the form; you — or your agent — open them in a private per-site inbox. The email and the webhook link to that inbox, never to a public download URL.

Your form, your markup

No form builder. Your form lives in your codebase.

Classic HTML POSTs redirect to your thank-you page; fetch calls get JSON back. Snippets are generated from your form's field contract — honeypot and Turnstile included — for HTML, Astro, and Next.js.

<form action="https://api.furrowforms.com/s/fp_k7m2" method="POST">
  <input type="text" name="_gotcha" style="display:none" tabindex="-1" />
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <div class="cf-turnstile" data-sitekey="0x4AAA…"></div>
  <button>Send</button>
</form>

Built responsibly

Boring security, done properly

[ typescript end to end ]

IPs never stored raw

Only HMAC hashes — rate limiting works without keeping visitor IPs.

Secrets encrypted at rest

Turnstile and webhook secrets under AES-256-GCM; API responses never leak them.

Tokens shown once

API tokens are stored as hashes. Mint, copy, done — nothing to exfiltrate later.

No open redirects

Thank-you redirect targets are validated against your allowed domains.

Pricing

Two prices. No ladder.

Full pricing →

[ free ]

$0forever

The whole product — full MCP + REST, signed webhooks, the cascade. 100 submissions a month.

[ pro ]

$199per year, per workspace

10,000 submissions a month. Unlimited clients, projects, and forms. Nothing gated.

Expansion packs

[ +5,000 subs/mo each ]

Outgrow 10,000 submissions? Stack packs on Pro — no tier jumps, no overage math.

$99per year, per pack

No feature gates, no per-form fees, no "contact sales."

[ POST /s/fp_xxxx ]

Point a form at a URL.
Or point your agent at us.

Other form backends make you configure every form. Furrow configures the website — and your agent can do it for you.

paste this into your agent

Fetch furrowforms.com/ai and set up forms for this site.

Setup for agents →