quickforms runs a streamable HTTP MCP server at https://YOUR-QUICKFORMS-HOST/mcp. It uses the same team API keys as the REST API, with the same API key abilities and team roles: read-only tools need the read ability, and anything that changes data needs write and an admin or owner role.
Claude Code
claude mcp add --transport http quickforms https://YOUR-QUICKFORMS-HOST/mcp \
--header "Authorization: Bearer YOUR_API_KEY"Other clients
Most clients that support remote MCP servers accept a config like this. Check your client’s docs for the exact file and key names.
{
"mcpServers": {
"quickforms": {
"type": "http",
"url": "https://YOUR-QUICKFORMS-HOST/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Tools
The server is called quickforms (version 1.0.0) and has 19 tools.
| Tool | Arguments | What it does |
|---|---|---|
list-forms |
None | List the forms in your team, newest first, with endpoint URL, mode and submission count. |
get-form |
form_id |
Get one form: schema, settings, endpoint URL, embed snippets and sandbox key. The webhook secret is returned by create-form and rotate-webhook-secret only. |
list-form-templates |
None | List the ready-made templates with their key, name, summary, category and field labels. |
generate-form |
prompt, save |
Design a form with the AI form builder from a plain-English prompt. Returns a draft (fields, description, smart rules, success message, autoresponder) to review and pass to create-form, or creates the form straight away with save: true. |
create-form |
template, name, description, mode, schema, draft, turnstile_secret, stripe_secret, webhook_url, settings |
Create a form from a name, schema and optional description, mode, webhook URL and settings. Pass template with a key from list-form-templates to start from a template: its fields and settings are used, anything else you pass overrides them, and name and schema become optional. Pass draft: true to create it unpublished. |
update-form |
form_id, name, description, mode, is_active, schema, draft, turnstile_secret, stripe_secret, webhook_url, settings |
Update a form, including its description. Only the keys you pass change. Passing schema replaces the whole field list. Pass draft: true to keep the changes as a draft instead of making them live. |
publish-form |
form_id, discard |
Publish a form: make its saved draft live, or put a never-published form live. Pass discard: true to throw the draft away instead and keep the live version as it is. |
rotate-webhook-secret |
form_id |
Replace a form’s webhook signing secret and return the form with the new one. The old secret stops working straight away. |
rotate-sandbox-key |
form_id |
Replace a form’s sandbox key and return the form with the new one. The old key stops working straight away. |
send-test-submission |
form_id, data |
Send a sandbox test submission. Validated and stored, every email and webhook simulated. Runs against the form’s draft, if it has one. |
create-form-links |
form_id, links |
Create personal links to a form’s hosted page, 1 to 500 at once, each with optional label, email, prefill, metadata, max_submissions (default 1, null for unlimited) and expires_at. |
list-form-links |
form_id, status, email, revoke_link_id |
List up to 200 of a form’s newest personal links with their status, filtered by status or email. Pass revoke_link_id to revoke that link instead. |
list-submissions |
form_id, sandbox, spam, link_id, confirmation, failed_rules, search, since, until, fields, page, per_page |
List submissions with sandbox, spam, failed_rules, confirmation (pending, confirmed or expired), link_id, search, since/until and exact field filters, paginated. |
get-submission |
submission_id |
Get one submission with every delivery and attempt. Sandbox deliveries include the payload that would have been sent. |
confirm-submission |
submission_id, action |
Double opt-in: action is confirm or resend. confirm confirms a pending submission and releases its held emails and webhooks. resend sends a new confirmation email with a fresh link, and also revives an expired submission. |
review-submission |
submission_id, spam |
Mark a submission as spam or not spam. Marking a flagged submission as not spam releases its held emails and webhooks. Marking a delivered one as spam only labels it. |
redeliver |
delivery_id |
Queue a fresh attempt for a live email or webhook delivery. Sandbox deliveries, and ones whose payload has been cleared by retention, can’t be redelivered. |
list-partial-submissions |
form_id, status, sandbox, days |
The completion funnel for a form and its 50 most recent partial submissions. Filter by status (in_progress, abandoned or completed). |
manage-destination |
action, form_id, destination_id, type, name, enabled, config, mapping, conditions, data |
List, create, update, delete and preview a form’s destinations, or list the destination types. |
get-form-analytics |
form_id, days |
Anonymous analytics for a form: views, visitors, starts, live submissions, conversion rate, a daily series and the top UTM sources, campaigns, referrer domains and ad click IDs. |
Drafts
Pass draft: true to create-form or update-form to keep changes unpublished. Live submissions keep using the published version, while send-test-submission runs against the draft. When the draft is right, call publish-form, or publish-form with discard: true to throw it away. See drafts and publishing.
Settings
settings on create-form and update-form accepts every key in the REST API’s form settings table, including routing rules, reply-to, Altcha, geo filters, disposable email blocking, payments and partial submissions.
Hosted forms
create-form and update-form accept settings.hosted (enabled, layout, appearance, accent, font, radius, background, title, intro, submit_label, logo_url, favicon_url, show_branding) to change the hosted form page. Only the keys you pass change. get-form returns the settings and the page’s URL.
Personal links
create-form-links takes form_id and a links list. It returns each link with its url, ready to send. list-form-links shows which links are open, completed, expired or revoked, and revokes one with revoke_link_id. create-form and update-form accept settings.require_link to only accept submissions through links. Submissions made through a link have link_id and the link’s details in meta.link. Pass link_id to list-submissions to see a link’s submissions. See personal links.
Spam
Submissions get two separate checks from the spam filter: the base spam check sets spam: true, and breaking the form’s smart rules sets failed_rules: true. Either one holds the deliveries. Pass spam or failed_rules (true or false) to list-submissions to filter by either check, and use review-submission to release a false positive. Marking a submission as not spam clears both flags. create-form and update-form accept description and settings.spam (enabled, threshold, rules).
Webhook events
create-form and update-form accept settings.webhook.events, a list of the webhook events to send: submission.created, submission.held, submission.deleted, submission.confirmation_expired and payment.needs_attention. The default is submission.created only.
Double opt-in
create-form and update-form accept settings.confirmation (enabled, email_field, subject, body, button_label, expires_hours, on_expiry, redirect_url, confirmed_message). On those forms a submission only sends a confirmation email until the person clicks its link, and submissions have confirmation_status (null, pending, confirmed or expired) and confirmed_at. Pass confirmation to list-submissions to filter by status, and use confirm-submission to confirm on the person’s behalf or resend the email. See double opt-in.
Spam protection
create-form and update-form accept settings.honeypot_field and settings.honeypot_fields, a list of up to 5 extra honeypots with realistic names such as website or fax. Passing honeypot_fields replaces the whole list, and a honeypot named like one of the form’s fields is rejected.
get-form returns settings.turnstile (enabled, site_key) and turnstile_secret_set, but never the Turnstile secret key. Set the secret key with turnstile_secret on create-form or update-form. It is write-only.
Creating forms
generate-form is limited to 30 generated forms an hour per user by default (QUICKFORMS_FORM_BUILDER_PER_HOUR). Past that it returns an error saying to try again later. It needs the AI form builder to be configured on the server (see configuration). See creating forms for the template list and examples.
Payments
create-form and update-form accept stripe_secret, your Stripe secret key (sk_ or a restricted rk_ key). It is write-only: get-form returns stripe_secret_set instead. Switch payments on with settings.payment (enabled, publishable_key, currency, amount in the smallest currency unit, or amount_field plus prices, and description). See payments.
Partial submissions
With settings.partials on (enabled, abandon_after_minutes, retention_days), the embed and hosted page save progress while people fill the form in. list-partial-submissions returns a funnel (started, completed, abandoned, in_progress, completion_rate and drop_off, the fields where people stop) over the last days (1 to 365, default 30), and data, the 50 most recently active partial submissions. Pass sandbox: true for sandbox ones. See partial submissions.
Destinations
manage-destination takes an action:
| Action | Needs | What it does |
|---|---|---|
types |
Nothing | The destination types with their config fields and mapping targets. |
list |
form_id |
The form’s destinations, oldest first. |
create |
form_id, type, name, config |
Add a destination. Optional enabled, mapping and conditions. |
update |
destination_id |
Change name, enabled, config, mapping or conditions. Only the keys you pass change. |
delete |
destination_id |
Delete the destination. |
preview |
destination_id |
A dry run showing exactly what would be sent, with secrets redacted. Pass data with sample field values. Without it, it uses the latest submission, or made-up values when there are none. Nothing is sent. |
Secrets in config are write-only and come back masked. mapping maps each target key to a template with {{field}} placeholders, plus {{_form_name}}, {{_submission_id}}, {{_submitted_at}} and {{_summary}}. conditions is a list of {field, operator, value}, all of which must match, with operator one of equals, not_equals, contains, is_set or is_empty. Deliveries are retried and logged like webhooks, and simulated in sandbox. See destinations.
Analytics
get-form-analytics takes form_id and days (1 to 365, default 30). It returns views, visitors, starts, submissions, conversion_rate, a daily series, and the top sources, campaigns, referrers and click_ids behind live submissions. The same data as GET /api/v1/forms/{form}/analytics. See analytics and tracking.