PortForm

For AI agents

Build forms with your AI agent

Your AI agent can build, connect, test, and verify your form before you even sign up. Start with an anonymous sandbox — no account, no token — then hand off a claim link. Once you own the form, agents manage it over the authenticated MCP server.

Build before you sign up

The anonymous sandbox is a real, temporary form an agent can create with a single request — no account, no MCP token. It accepts up to 5 test submissions, lives 24 hours, and is then handed to you with a claim link.

1 · Create a sandbox

POST to the public sandbox endpoint. Both fields are optional.

create a sandbox
curl -X POST https://app.portform.co/api/v1/public/sandboxes \
  -H "Content-Type: application/json" \
  -d '{"label":"Contact form","destination_email":"you@example.com"}'

2 · Read the response

The 201 response provides everything the next steps need — the sandbox id, form information, access key, submit URL, status URL, claim URL, a one-time claim token, ready-to-paste snippets, test information, and ordered next steps. Nothing else has to be looked up.

3 · Send a test submission

Use the access key from the response as YOUR_ACCESS_KEY. Sandbox submissions are stored but never emailed.

send a test submission
curl -X POST https://app.portform.co/api/submit \
  -F access_key=YOUR_ACCESS_KEY \
  -F name=Ada \
  -F email=ada@example.com \
  -F message="Hello from an agent" \
  -F botcheck=

Limits: 5 test submissions per sandbox, 24-hour lifetime, up to 3 sandboxes per IP every 10 minutes. The one-time claim token appears once in the response — hand the human the claim URL, and never print or log the token anywhere else.

From idea to verified submission

The sandbox response already carries the ordered next steps for the whole flow.

1

Create

Your agent POSTs to the sandbox endpoint and gets back an access key, submit URL, status URL, and a claim URL.

2

Wire

It pastes the returned HTML snippet into the site, or POSTs the form fields to the submit URL with the access key.

3

Test

It sends up to 5 test submissions to prove the form works end to end.

4

Verify

It GETs the status URL to confirm the submissions were received.

5

Claim

It hands you the claim URL. You sign in and the sandbox becomes your permanent form — same id, same submit URL.

Continue with MCP

Once you own a form, an agent connected to PortForm’s MCP server can create and manage forms and read submissions on an ongoing basis. MCP is authenticated — it requires a workspace token and never accepts anonymous access.

A remote Streamable HTTP server, MCP protocol 2025-06-18, authenticated with a Bearer pf_… workspace token and gated by your workspace role. There is no package to install.

MCP endpoint
POST https://app.portform.co/api/v1/mcp
generic MCP config
{
  "mcpServers": {
    "portform": {
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PORTFORM_TOKEN}"
      }
    }
  }
}

Reference the token through an environment variable — never inline a real pf_ token in a file you commit. Mint a token from your MCP settings.

Eight tools

list_forms
List the forms on your workspace.
get_form
Read one form’s configuration.
create_form
Create a form; its id is the access key to submit with.
update_form
Update an existing form.
list_submissions
List submissions for a form.
get_submission
Read one submission.
test_submission
Send one real test submission to prove delivery.
diagnose
Lint form markup before it ships.

Reads and form management only. Billing, members, linked emails, and integrations are not exposed over MCP.

Connect your agent

Setup for 15 coding agents, grouped by how each one connects. Open your agent to see the exact command or config — the token is always referenced through an environment variable, never inlined.

One commandRun it once in your terminal.
Claude CodeOne commandAnthropic’s terminal agent. Adds MCP servers with one command.
Terminal
claude mcp add --transport http portform https://app.portform.co/api/v1/mcp --header "Authorization: Bearer $PORTFORM_TOKEN"
  1. 1.Run this in your project directory.
  2. 2.It is stored in Claude Code’s own config at the default local scope, not in your repository.
  3. 3.Run /mcp inside Claude Code to see portform listed.
CodexOne commandOpenAI’s CLI agent. Adds a remote server and reads the token from your environment.
Terminal
codex mcp add portform --url https://app.portform.co/api/v1/mcp --bearer-token-env-var PORTFORM_TOKEN
  1. 1.Export PORTFORM_TOKEN with the token above, then run this.
  2. 2.It writes to ~/.codex/config.toml — the token itself stays in your environment.
  3. 3.Run /mcp inside Codex to check the server is listed.
Gemini CLIOne commandGoogle’s terminal agent. Adds MCP servers with one command.
Terminal
gemini mcp add -s user -t http portform https://app.portform.co/api/v1/mcp -H "Authorization: Bearer $PORTFORM_TOKEN"
  1. 1.Run this anywhere.
  2. 2.-s user writes to ~/.gemini/settings.json. Without it Gemini CLI defaults to project scope and would put the token in .gemini/settings.json inside your repo.
  3. 3.Run /mcp inside Gemini CLI to check the connection.
VS CodeOne commandCopilot’s agent mode in VS Code. One command registers the server.
Terminal
code --add-mcp '{"name":"portform","type":"http","url":"https://app.portform.co/api/v1/mcp"}'
.vscode/mcp.json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "portform-token",
      "description": "PortForm MCP token",
      "password": true
    }
  ],
  "servers": {
    "portform": {
      "type": "http",
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${input:portform-token}"
      }
    }
  }
}

Safe to commit: ${input:portform-token} is a prompt, not a value. VS Code does not read ${env:…} in this file.

  1. 1.Run this to register the server in your user profile.
  2. 2.To share it with the repo instead, use the file below — VS Code prompts for the token once and keeps it in its own secret storage.
  3. 3.Open the Chat view in Agent mode and check portform under Tools.
Config filePaste a block into the agent’s config.
CursorConfig fileThe editor. MCP servers live in a JSON file, or install in one click.
.cursor/mcp.json
{
  "mcpServers": {
    "portform": {
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PORTFORM_TOKEN}"
      }
    }
  }
}
  1. 1.Save this as .cursor/mcp.json in your project, or ~/.cursor/mcp.json to use it everywhere.
  2. 2.Set PORTFORM_TOKEN in your shell environment to the token above, so the value never enters the file.
  3. 3.This file is inside your repository, so it references PORTFORM_TOKEN rather than carrying the token. Keep it that way.
  4. 4.Cursor Settings → MCP should now list portform.
Add to Cursor
WindsurfConfig fileThe editor from Cognition. MCP servers live in a JSON file.
~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "portform": {
      "serverUrl": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PORTFORM_TOKEN}"
      }
    }
  }
}
  1. 1.Save this as ~/.codeium/windsurf/mcp_config.json, or paste it into Cascade’s MCP panel.
  2. 2.Set PORTFORM_TOKEN in your shell environment to the token above, so the value never enters the file.
  3. 3.Refresh the server list in Cascade.
ClineConfig fileThe VS Code extension and CLI. Remote servers go in its MCP settings JSON.
~/.cline/mcp.json
{
  "mcpServers": {
    "portform": {
      "type": "streamableHttp",
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_PORTFORM_TOKEN"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}
  1. 1.Save this as ~/.cline/mcp.json, or open Cline → MCP Servers → Configure and paste it there.
  2. 2.Both live outside your repository. Cline does not document environment interpolation in headers, so the value goes in the file.
  3. 3.The server list should show portform as connected.
Roo CodeConfig fileThe VS Code extension. Remote servers go in its global MCP settings.
Roo Code → MCP Servers → Edit Global MCP
{
  "mcpServers": {
    "portform": {
      "type": "streamable-http",
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_PORTFORM_TOKEN"
      }
    }
  }
}
  1. 1.Open Roo Code → MCP Servers → Edit Global MCP and paste this into mcp_settings.json.
  2. 2.Use the global file, not .roo/mcp.json — that one is in your repository, and header interpolation is not documented.
  3. 3.The type must be streamable-http with the hyphen; http does not work.
opencodeConfig fileThe open-source terminal agent. Remote servers go in its JSON config.
~/.config/opencode/opencode.json
{
  "mcp": {
    "portform": {
      "type": "remote",
      "url": "https://app.portform.co/api/v1/mcp",
      "enabled": true,
      "headers": {
        "Authorization": "Bearer {env:PORTFORM_TOKEN}"
      }
    }
  }
}
  1. 1.Merge this into ~/.config/opencode/opencode.json.
  2. 2.Set PORTFORM_TOKEN in your shell environment to the token above, so the value never enters the file.
  3. 3.opencode’s syntax is {env:PORTFORM_TOKEN} with no leading $ — the other clients’ form does not work here.
AntigravityConfig fileGoogle’s agent-first IDE. Takes a JSON MCP config.
~/.gemini/config/mcp_config.json
{
  "mcpServers": {
    "portform": {
      "serverUrl": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ${env:PORTFORM_TOKEN}"
      }
    }
  }
}
  1. 1.Save this as ~/.gemini/config/mcp_config.json so it applies to every workspace.
  2. 2.Set PORTFORM_TOKEN in your shell environment to the token above, so the value never enters the file.
  3. 3.Run /mcp in Antigravity to reload and check the connection.
Set up in the agentAdded in the agent’s own settings.
DevinSet up in DevinRuns in the cloud. MCP servers are added in Devin’s settings.
Devin → Settings → Connections → MCP servers
Name:        portform
Transport:   HTTP
Server URL:  https://app.portform.co/api/v1/mcp
Auth:        Auth Header
Header:      Authorization
Value:       Bearer YOUR_PORTFORM_TOKEN
  1. 1.In Devin, open Settings → Connections → MCP servers and choose “Add a custom MCP”.
  2. 2.Pick the HTTP transport and “Auth Header” authentication, then enter the values above.
  3. 3.This needs the Manage MCP Servers permission in your Devin organisation.

Needs the Manage MCP Servers permission in your Devin organisation.

v0Set up in v0Vercel’s web generator. Takes custom MCP servers with a bearer token.
v0 → + → MCPs → Custom MCP server
Name:            portform
Server URL:      https://app.portform.co/api/v1/mcp
Authentication:  Bearer Token
Token:           YOUR_PORTFORM_TOKEN
  1. 1.In v0, open the + menu → MCPs → “Add a custom MCP server”.
  2. 2.Enter the URL above and choose Bearer Token authentication.
  3. 3.v0 calls the tools while it generates. The app it builds for you does not get MCP access of its own — this connects v0, not your project.

v0 uses the tools while it generates. The app it produces does not get MCP access of its own.

Replit AgentSet up in ReplitRuns in the cloud. Custom MCP servers are added with a header of your choosing.
Replit → Integrations → MCP servers
Name:        portform
Server URL:  https://app.portform.co/api/v1/mcp
Auth:        Custom header
Header:      Authorization
Value:       Bearer YOUR_PORTFORM_TOKEN
  1. 1.Open the Integrations pane in Replit and add a custom MCP server.
  2. 2.Choose custom-header authentication rather than OAuth, then enter Authorization and the value above.
  3. 3.Replit discovers the tools once the server is saved.
Copilot coding agentSet up in GitHubGitHub’s cloud agent. MCP servers are configured per repository.
GitHub → Settings → Copilot → MCP servers
{
  "mcpServers": {
    "portform": {
      "type": "http",
      "url": "https://app.portform.co/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer $COPILOT_MCP_PORTFORM_TOKEN"
      },
      "tools": [
        "*"
      ]
    }
  }
}
  1. 1.Add the token as an Actions secret named COPILOT_MCP_PORTFORM_TOKEN. Only names starting with COPILOT_MCP_ reach the agent.
  2. 2.Then paste this into Settings → Copilot → MCP servers → MCP configuration, and save.
  3. 3.Both steps need repository admin access.

Needs repository admin access, and the token has to be stored as a COPILOT_MCP_ secret.

Prompt onlyNo way to present a PortForm token yet.
BoltPrompt onlyThe web builder. Its connectors take OAuth, not a bearer token.

Bolt’s custom MCP settings only offer an OAuth client id and secret — there is no field for an Authorization header, so it cannot present a PortForm token. Copy the prompt instead.

Hand your agent a form to build.

Start with the anonymous sandbox, or sign up and connect MCP for ongoing management.

We use optional analytics cookies to understand how the site is used. Necessary cookies for signing in and checkout always load. See our privacy policy.