com. furrowforms/ furrow-forms
by furrowforms.com · remote · local (npm) · no sign-in to list tools · v1.0.1 · published by com.furrowforms
Form backend an agent runs end to end: provision forms, snippets, spam, signed webhooks.
27 tools: 4 can delete or cancel things, 12 change things and 11 only read.
Scanned Oct 21, 2026
- Deletes or cancels4Claude Code: deny: see these tools
- Can't be undone0Claude Code: ask
- Changes things12Claude Code: ask: see these tools
- Only reads11Claude Code: allow: see these tools
1 check matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http furrow-forms https://api.furrowforms.com/mcpFindings
Matches of fixed checks, with the text they matched.
- Infobootstrap_site
The description is 2,396 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...ppet. Do not use when you only need to patch an existing form — call update_form."
Tools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
27 tools
Deletes or cancels 4Claude Code: deny
archive_clientUse to archive a client.No findings
Why it is in this group
- The name "archive_client" says "archive": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Use to archive a client. Do not use this as a hard delete. There is no unarchive tool in v1.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
archive_formUse to archive a form so public submit returns 404.No findings
Why it is in this group
- The name "archive_form" says "archive": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Use to archive a form so public submit returns 404. Do not use this as a hard delete.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
archive_projectUse to archive a website.No findings
Why it is in this group
- The name "archive_project" says "archive": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Use to archive a website. Archived projects reject public submit. Do not use this as a hard delete. There is no unarchive tool in v1.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: true
rotate_project_inboxUse when a project's private inbox URL may have leaked.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Use when a project's private inbox URL may have leaked. Issues a new inbox key; every previously shared inbox link stops working immediately. get_project returns the new files_url.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: true
- idempotentHint: false
Changes things 12Claude Code: ask
bootstrap_siteUse this to stand up a client, one website (project), and its forms in a single call.1 finding
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Findings
- Info
The description is 2,396 characters long, over the 2,000 this check looks for.
What this check looks forMatched text
description ends: "...ppet. Do not use when you only need to patch an existing form — call update_form."
Description, as the server wrote it Use this to stand up a client, one website (project), and its forms in a single call. name/slug are the client; optional project_name/project_slug default to the same. Free accounts cannot create a fourth active project — call create_upgrade_link if bootstrap_site returns plan_limit. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Idempotent on client, project, and form slugs. Site settings (domains, Turnstile, notify emails, webhook, email templates, uploads) live on the project. Email templates support {{project.name}}, {{project.slug}}, {{form.name}}, {{form.slug}}, {{count}} (1-based clean submissions on this form, including the current one), and any submission field such as {{name}} or {{email}}. Use a fallback with {{name | "New submission"}}. Missing fields render empty and never error. Do not pass HTML; Furrow renders one owned layout. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. Checkbox groups, select multiple, and other multi-value HTML fields must use a [] suffix on the name (name="services[]") or only the last checked value is stored. Put services[] on field_contract.name too. JSON/fetch should send a real array without brackets ({ "services": ["a", "b"] }) and must not use Object.fromEntries(formData) — use formData.getAll("services"). Single checkbox, select, or combobox: no brackets. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet. Do not use when you only need to patch an existing form — call update_form.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
create_clientUse to add a client (company) by slug.No findings
Why it is in this group
- The name "create_client" says "create": a word for a change.
Description, as the server wrote it Use to add a client (company) by slug. Idempotent on slug unless strict is true. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Prefer bootstrap_site when also creating a website and forms. Do not put Turnstile or webhooks on a client — those live on the project.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
create_formUse to add a form under an existing project_id.No findings
Why it is in this group
- The name "create_form" says "create": a word for a change.
Description, as the server wrote it Use to add a form under an existing project_id. Idempotent on slug unless strict is true. Overrides are nullable; omit them to inherit project notify emails, webhook, redirect, require_turnstile, and email templates. Pass email.subject / email.intro to override notification copy for this form only. Pass webhook_url_override to send this form to a different URL. Field contract labels (label) are used on notification emails. Checkbox groups, select multiple, and other multi-value HTML fields must use a [] suffix on the name (name="services[]") or only the last checked value is stored. Put services[] on field_contract.name too. JSON/fetch should send a real array without brackets ({ "services": ["a", "b"] }) and must not use Object.fromEntries(formData) — use formData.getAll("services"). Single checkbox, select, or combobox: no brackets. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
create_projectUse to add one website under an existing client_id.No findings
Why it is in this group
- The name "create_project" says "create": a word for a change.
Description, as the server wrote it Use to add one website under an existing client_id. Idempotent on slug unless strict is true. Free accounts are limited to 3 active (non-archived) projects; yearly is unlimited. If create_project returns plan_limit, call create_upgrade_link and hand the human the Stripe URL. Prefer bootstrap_site when the client does not exist yet. Optional email sets notification templates (subject, from_name, intro, footer_mode, include_meta). Free accounts cannot set footer_mode off. Set uploads_enabled on the project to accept files. Email templates support {{project.name}}, {{project.slug}}, {{form.name}}, {{form.slug}}, {{count}} (1-based clean submissions on this form, including the current one), and any submission field such as {{name}} or {{email}}. Use a fallback with {{name | "New submission"}}. Missing fields render empty and never error. Do not pass HTML; Furrow renders one owned layout. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet. Do not put Turnstile keys on a form.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
create_upgrade_linkUse when a free team is blocked on the 3-project, 100-submission, or one-workspace limit, or when a human should upgrade to yearly ($199/year) so you can keep adding projects, work…No findings
Why it is in this group
- The name "create_upgrade_link" says "create": a word for a change.
Description, as the server wrote it Use when a free team is blocked on the 3-project, 100-submission, or one-workspace limit, or when a human should upgrade to yearly ($199/year) so you can keep adding projects, workspaces, and storing new submissions. Returns a Stripe Checkout URL to hand the human. If the team is already yearly, omit product to get a Stripe Customer Portal URL, or pass product=expansion for a $99/year pack that adds 5,000 submissions/month. Do not change plan in the database — Stripe webhooks do that. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: false
test_webhookUse to POST a signed webhook.test event to the project's webhook URL.No findings
Why it is in this group
- The description's first verb is "post": a word for a change.
Description, as the server wrote it Use to POST a signed webhook.test event to the project's webhook URL. Available on free and yearly. Do not use this to inspect past deliveries — that is REST GET /api/projects/:id/webhook-deliveries. Fails if no webhook URL and secret are set.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: false
update_accountUse to rename the workspace, set branding, or configure the AI spam filter.No findings
Why it is in this group
- The name "update_account" says "update": a word for a change.
Description, as the server wrote it Use to rename the workspace, set branding, or configure the AI spam filter. Pass ai.typesafe_api_key to save this team's TypeSafe key (null clears it; the key is write-only). ai.notify_suspected_spam (default true) emails notify addresses with a Potential spam label when Jev flags a submission; no webhook is sent either way. Heuristic spam stays silent. Free accounts cannot set branding.mode or email.footer_mode to anything but furrow — those writes are ignored. Yearly may set branding.mode to furrow, off, or agency (name + optional link + optional logo; Furrow keeps the layout, no raw HTML). Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use this to change the plan — call create_upgrade_link.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
update_clientUse to rename a client.No findings
Why it is in this group
- The name "update_client" says "update": a word for a change.
Description, as the server wrote it Use to rename a client. Do not use this to change domains, Turnstile, or webhooks — call update_project.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
update_formUse to patch form overrides.No findings
Why it is in this group
- The name "update_form" says "update": a word for a change.
Description, as the server wrote it Use to patch form overrides. Pass null on an override to inherit again. Set email.subject or email.intro to override project notification copy for this form only; from_name, footer_mode, and include_meta stay on the project. Email templates support {{project.name}}, {{project.slug}}, {{form.name}}, {{form.slug}}, {{count}} (1-based clean submissions on this form, including the current one), and any submission field such as {{name}} or {{email}}. Use a fallback with {{name | "New submission"}}. Missing fields render empty and never error. Do not pass HTML; Furrow renders one owned layout. Set webhook_url_override to override the project webhook for this form. Do not use this to change Turnstile keys — those live on the project. Checkbox groups, select multiple, and other multi-value HTML fields must use a [] suffix on the name (name="services[]") or only the last checked value is stored. Put services[] on field_contract.name too. JSON/fetch should send a real array without brackets ({ "services": ["a", "b"] }) and must not use Object.fromEntries(formData) — use formData.getAll("services"). Single checkbox, select, or combobox: no brackets. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
update_projectUse to patch website settings.No findings
Why it is in this group
- The name "update_project" says "update": a word for a change.
Description, as the server wrote it Use to patch website settings. Nested email sets notification templates: email.subject, email.from_name, email.intro, email.footer_mode (furrow | minimal | off), email.include_meta. Optional branding updates the team (mode furrow | off | agency on yearly only; ignored on free except furrow). Set uploads_enabled and upload_allowed_types here — forms inherit them. Email templates support {{project.name}}, {{project.slug}}, {{form.name}}, {{form.slug}}, {{count}} (1-based clean submissions on this form, including the current one), and any submission field such as {{name}} or {{email}}. Use a fallback with {{name | "New submission"}}. Missing fields render empty and never error. Do not pass HTML; Furrow renders one owned layout. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet. Null Turnstile or webhook fields clear them. Do not use this to create forms. Updating project keys changes resolved settings on existing forms unless a form override is set.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
update_teamUse to rename a team.No findings
Why it is in this group
- The name "update_team" says "update": a word for a change.
Description, as the server wrote it Use to rename a team. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use this to create another workspace — that is dashboard-only and requires yearly. For plan, usage, retention, and branding, call get_account / update_account. Do not use this to change clients or projects.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
upsert_project_webhookUse to set or replace the project webhook URL.No findings
Why it is in this group
- The name "upsert_project_webhook" says "upsert": a word for a change.
Description, as the server wrote it Use to set or replace the project webhook URL. Available on free and yearly. A signing secret is generated once if the project has none. Forms inherit this unless webhook_url_override is set. Do not use this for a one-off delivery — call test_webhook.
Annotations the server declares
- readOnlyHint: false
- idempotentHint: true
Only reads 11Claude Code: allow
get_accountUse to read the team's plan, usage this month, limits, expansion_packs, retention_days, branding, and AI spam filter (ai.typesafe_key_set, ai.notify_suspected_spam).No findings
Why it is in this group
- The name "get_account" says "get": a word for reading.
Description, as the server wrote it Use to read the team's plan, usage this month, limits, expansion_packs, retention_days, branding, and AI spam filter (ai.typesafe_key_set, ai.notify_suspected_spam). The TypeSafe key itself is never returned. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use this to list projects — call list_projects.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
get_clientUse to inspect one client.No findings
Why it is in this group
- The name "get_client" says "get": a word for reading.
Description, as the server wrote it Use to inspect one client. Do not use to list that client's sites — call list_projects with client_id.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
get_formUse to read a form plus resolved and inherited settings, including resolved.email and resolved.uploads.No findings
Why it is in this group
- The name "get_form" says "get": a word for reading.
Description, as the server wrote it Use to read a form plus resolved and inherited settings, including resolved.email and resolved.uploads. files_url is the private inbox folder for this form under the project inbox (do not put it in a public snippet). Turnstile always inherits from the project (inherited.turnstile is true). Form webhook_url_override is nullable; null means inherit the project webhook. Forms may override email.subject and email.intro only. Do not use to generate embed code — call get_snippet.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
get_projectUse to inspect one website's settings, domains, webhook URL, email templates, upload policy, plan, usage this month, limits, retention_days, and branding.No findings
Why it is in this group
- The name "get_project" says "get": a word for reading.
Description, as the server wrote it Use to inspect one website's settings, domains, webhook URL, email templates, upload policy, plan, usage this month, limits, retention_days, and branding. Returns stored values plus resolved.email. Secrets are never returned. Plans are capacity, not a feature ladder. Free: one workspace, 100 clean submissions/month pooled on the team, 3 active (non-archived) projects, 30-day submission retention, and email.footer_mode / branding.mode stay furrow. Yearly ($199/year): extra workspaces, 10,000 submissions/month, unlimited projects, 730-day retention, branding.mode furrow | off | agency. Expansion packs are $99/year each and add 5,000 submissions/month on a yearly account. MCP, webhooks, snippets, inheritance, Turnstile, and email templates stay available on free. Spam, honeypot, and rejected posts do not count. Use create_upgrade_link to hand a human a Stripe Checkout (or Customer Portal) URL. Pass product=expansion on a yearly team to add a pack. Do not use to list forms — call list_forms.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
get_snippetUse after the form exists to get copy-paste html, astro, or next code that posts to /s/:publicKey.No findings
Why it is in this group
- The name "get_snippet" says "get": a word for reading.
Description, as the server wrote it Use after the form exists to get copy-paste html, astro, or next code that posts to /s/:publicKey. Do not invent a submit URL — this tool returns it. Snippets are single-value inputs; write checkbox groups and multi-selects yourself. Checkbox groups, select multiple, and other multi-value HTML fields must use a [] suffix on the name (name="services[]") or only the last checked value is stored. Put services[] on field_contract.name too. JSON/fetch should send a real array without brackets ({ "services": ["a", "b"] }) and must not use Object.fromEntries(formData) — use formData.getAll("services"). Single checkbox, select, or combobox: no brackets. File inputs use multipart POST (name="resume[]" for multiple). Enable uploads on the project first. Downloads are the project inbox at files_url, with the form slug as a folder — never put that URL in a public snippet. After dropping the snippet, add visitor-facing success UI: a thank-you page plus default_redirect_url for classic HTML POST, or an on-page message when using fetch/{ok:true}. Do not leave visitors looking at JSON. See furrow://docs/submit-success.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
get_submissionUse to read one stored submission by id, including file metadata and files_url (the form inbox).No findings
Why it is in this group
- The name "get_submission" says "get": a word for reading.
Description, as the server wrote it Use to read one stored submission by id, including file metadata and files_url (the form inbox). Do not use this for live submit tests — POST to /s/:publicKey instead. Do not expect signed bucket URLs — download from the inbox.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
list_clientsUse to browse clients (companies).No findings
Why it is in this group
- The name "list_clients" says "list": a word for reading.
Description, as the server wrote it Use to browse clients (companies). Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use to list websites — call list_projects with client_id. Archived clients are hidden unless status=all or archived.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
list_formsUse to list forms.No findings
Why it is in this group
- The name "list_forms" says "list": a word for reading.
Description, as the server wrote it Use to list forms. Pass project_id for one website or client_id for one company (team is inferred). Otherwise Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use to read resolved inheritance — call get_form.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
list_projectsUse to browse websites.No findings
Why it is in this group
- The name "list_projects" says "list": a word for reading.
Description, as the server wrote it Use to browse websites. Pass client_id to list one client's sites (team is inferred). Without client_id, Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Do not use to read one project's settings — call get_project. Archived projects are hidden unless status=all or archived.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
list_submissionsUse to inspect recent posts.No findings
Why it is in this group
- The name "list_submissions" says "list": a word for reading.
Description, as the server wrote it Use to inspect recent posts. Available on free and yearly. Pass project_id or form_id to infer the team; omit both and Operator tokens (all workspaces) must pass team_id from list_teams. Team-scoped tokens may omit team_id and cannot target another workspace. Free teams prune submissions after 30 days; yearly after 730 days. Do not use to read a single submission — call get_submission.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
list_teamsUse to see workspaces this token can act on.No findings
Why it is in this group
- The name "list_teams" says "list": a word for reading.
Description, as the server wrote it Use to see workspaces this token can act on. A team-scoped frw_ token returns that team only. An operator token or an MCP OAuth login returns every team you belong to — pass team_id on list_clients, create_client, and bootstrap_site. Creating another workspace is dashboard-only after signing in and requires a yearly plan; free accounts stay on one team. Do not use this to list clients — call list_clients.
Annotations the server declares
- readOnlyHint: true
- idempotentHint: true
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 1.0.1. Values in angle brackets are yours to fill in.
claude mcp add --transport http furrow-forms https://api.furrowforms.com/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__furrow-forms__list_teams",
"mcp__furrow-forms__get_account",
"mcp__furrow-forms__list_clients",
"mcp__furrow-forms__get_client",
"mcp__furrow-forms__list_projects",
"mcp__furrow-forms__get_project",
"mcp__furrow-forms__list_forms",
"mcp__furrow-forms__get_form",
"mcp__furrow-forms__list_submissions",
"mcp__furrow-forms__get_submission",
"mcp__furrow-forms__get_snippet"
],
"ask": [
"mcp__furrow-forms__update_team",
"mcp__furrow-forms__update_account",
"mcp__furrow-forms__create_upgrade_link",
"mcp__furrow-forms__create_client",
"mcp__furrow-forms__update_client",
"mcp__furrow-forms__create_project",
"mcp__furrow-forms__update_project",
"mcp__furrow-forms__create_form",
"mcp__furrow-forms__update_form",
"mcp__furrow-forms__upsert_project_webhook",
"mcp__furrow-forms__test_webhook",
"mcp__furrow-forms__bootstrap_site"
],
"deny": [
"mcp__furrow-forms__archive_client",
"mcp__furrow-forms__rotate_project_inbox",
"mcp__furrow-forms__archive_project",
"mcp__furrow-forms__archive_form"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as furrow-forms. Review it before you use it.