Formbridge
Mixed-mode agent-human form submission infrastructure. AI agents fill what they know, humans complete the rest.
Installation
npx formbridgeAsk AI about Formbridge
Powered by Claude Β· Grounded in docs
I know everything about Formbridge. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
FormBridge
Mixed-mode agent-human form submission infrastructure. AI agents fill what they know, humans complete the rest β with full field-level attribution, approval workflows, and webhook delivery.
The Problem
AI agents can gather most of the data for a form β but some fields need a human: signatures, file uploads, identity verification, subjective preferences. Existing form tools force you to choose: fully automated or fully manual. Nothing handles the handoff.
How FormBridge Works
Agent FormBridge Human
β β β
ββ POST /submissions βββββββββββΊβ Creates draft, returns β
β (fills known fields) β resumeToken + handoff URL β
β β β
β ββββββ Opens link βββββββββββββββββ€
β β Pre-filled form with β
β β attribution badges β
β β β
β ββββββ Fills remaining fields βββββ€
β ββββββ Submits βββββββββββββββββββ€
β β β
β βββ Webhook delivery ββββββββ€ Validated, approved, β
β (HMAC-signed) β delivered to destination β
- Agent creates a submission and fills fields it knows
- FormBridge generates a secure resume URL with a rotating token
- Human opens the link β sees pre-filled fields with "filled by agent" badges
- Human completes remaining fields, uploads files, submits
- Submission flows through validation β optional approval gates β webhook delivery
- Every field tracks who filled it (agent, human, or system) and when
Packages
Quick Start
Installation
npm install @formbridge/mcp-server
Option 1: HTTP API Server
import { createFormBridgeApp } from '@formbridge/mcp-server';
import { serve } from '@hono/node-server';
const app = createFormBridgeApp({
intakes: [{
id: 'contact-form',
version: '1.0.0',
name: 'Contact Form',
schema: {
type: 'object',
properties: {
name: { type: 'string', title: 'Full Name' },
email: { type: 'string', format: 'email', title: 'Email' },
message: { type: 'string', title: 'Message' },
},
required: ['name', 'email', 'message'],
},
destination: {
type: 'webhook',
name: 'Contact API',
config: { url: 'https://api.example.com/contacts', method: 'POST' },
},
}],
});
serve({ fetch: app.fetch, port: 3000 });
console.log('FormBridge running on http://localhost:3000');
Full submission lifecycle:
# 1. Agent creates a submission with known fields
curl -X POST http://localhost:3000/intake/contact-form/submissions \
-H 'Content-Type: application/json' \
-d '{
"actor": { "kind": "agent", "id": "gpt-4" },
"idempotencyKey": "req_abc123",
"initialFields": { "name": "John Doe", "email": "john@example.com" }
}'
# β { ok: true, submissionId: "sub_...", resumeToken: "rtok_...", state: "draft" }
# 2. Human completes remaining fields via resume token
curl -X PATCH http://localhost:3000/intake/contact-form/submissions/sub_.../fields \
-H 'Content-Type: application/json' \
-d '{
"resumeToken": "rtok_...",
"actor": { "kind": "human", "id": "user-1" },
"fields": { "message": "I'd like to learn more about your product." }
}'
# 3. Submit the completed form
curl -X POST http://localhost:3000/intake/contact-form/submissions/sub_.../submit \
-H 'Content-Type: application/json' \
-d '{
"resumeToken": "rtok_...",
"actor": { "kind": "human", "id": "user-1" }
}'
# β Triggers validation, approval (if configured), and webhook delivery
Option 2: MCP Server (for AI agents)
import { FormBridgeMCPServer } from '@formbridge/mcp-server';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new FormBridgeMCPServer({
name: 'my-formbridge',
version: '1.0.0',
});
server.registerIntake({
id: 'vendor_onboarding',
version: '1.0.0',
name: 'Vendor Onboarding',
description: 'Register new vendors',
schema: z.object({
companyName: z.string().describe('Legal company name'),
taxId: z.string().describe('Tax identification number'),
contact: z.string().email().describe('Primary contact email'),
w9Upload: z.string().optional().describe('W-9 form upload (human-only)'),
}),
destination: {
type: 'webhook',
name: 'Vendor System',
config: { url: 'https://api.example.com/vendors', method: 'POST' },
},
});
// Each intake auto-generates 4 MCP tools:
// vendor_onboarding__create β Start a new submission
// vendor_onboarding__set β Update fields
// vendor_onboarding__validate β Check completeness
// vendor_onboarding__submit β Submit for processing
const transport = new StdioServerTransport();
await server.getServer().connect(transport);
Option 3: React Form Renderer
import { FormBridgeForm, ResumeFormPage } from '@formbridge/form-renderer';
// Standalone form
function ContactPage() {
return (
<FormBridgeForm
schema={contactSchema}
endpoint="http://localhost:3000"
actor={{ kind: 'human', id: 'user-1' }}
onSuccess={(data, submissionId) => {
console.log('Submitted:', submissionId);
}}
/>
);
}
// Resume an agent-started form (pre-filled fields + attribution badges)
function ResumePage() {
const token = new URLSearchParams(location.search).get('token');
return (
<ResumeFormPage
resumeToken={token}
endpoint="http://localhost:3000"
/>
);
}
Option 4: CLI Scaffolding
# Interactive β walks you through setup
npx @formbridge/create
# Non-interactive
npx @formbridge/create --name my-intake --schema zod --interface http,mcp
Features
Core
- Submission State Machine β
draft β submitted β approved β deliveredwith configurable transitions - Field Attribution β Every field tracks which actor (agent, human, system) set it and when
- Resume Tokens β Secure, rotating tokens for handoff URLs (rotated on every state change)
- Idempotent Submissions β Duplicate requests with the same key return the existing submission
- Schema Normalization β Accept Zod schemas, JSON Schema, or OpenAPI specs as input
Collaboration
- Mixed-Mode Forms β Agents fill what they can, humans complete the rest
- Conditional Fields β Show/hide fields based on other field values (dynamic schema)
- Multi-Step Wizard β Progressive disclosure with step indicators and navigation
- File Upload Protocol β Signed URL negotiation for secure file handling (S3-compatible)
Production
- Approval Gates β Configurable review workflows that pause submissions until approved/rejected
- Webhook Delivery β HMAC-signed payloads with exponential backoff and delivery tracking
- Event Stream β Append-only audit trail for every state change, field update, and action
- Auth & RBAC β API key auth, OAuth provider, role-based access control, rate limiting
- Multi-Tenancy β Tenant isolation with configurable storage and access boundaries
- Pluggable Storage β In-memory (dev), SQLite (single-server), PostgreSQL (multi-replica HA), S3 (file uploads)
Developer Experience
- MCP Server β Auto-generates MCP tools from intake definitions for AI agent integration
- Admin Dashboard β React SPA for managing intakes, reviewing submissions, analytics
- CLI Scaffolding β
npx @formbridge/creategenerates a ready-to-run project - 5 Starter Templates β Vendor onboarding, IT access request, customer intake, expense report, bug report
- VitePress Docs β API reference, guides, walkthroughs, and concept docs
- CI/CD β GitHub Actions for lint, typecheck, and tests on Node 18/20/22
API Reference
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /health | Health check |
GET | /intake/:id/schema | Get intake schema |
POST | /intake/:id/submissions | Create submission |
GET | /intake/:id/submissions/:subId | Get submission |
PATCH | /intake/:id/submissions/:subId/fields | Update fields |
POST | /intake/:id/submissions/:subId/submit | Submit |
GET | /intake/:id/submissions/:subId/events | Get event stream |
POST | /intake/:id/submissions/:subId/approve | Approve submission |
POST | /intake/:id/submissions/:subId/reject | Reject submission |
POST | /intake/:id/submissions/:subId/uploads | Request file upload URL |
POST | /intake/:id/submissions/:subId/uploads/:uploadId/verify | Verify file upload |
GET | /webhooks/deliveries | List webhook deliveries |
GET | /analytics | Submission analytics |
Submission States
draft β submitted β approved β delivered
β rejected
- draft β Being filled by agent and/or human
- submitted β All required fields complete, pending review (or auto-approved)
- approved β Passed approval gates, queued for delivery
- rejected β Rejected by reviewer
- delivered β Webhook successfully delivered to destination
Storage Backends
FormBridge supports multiple storage backends, selected via the FORMBRIDGE_STORAGE environment variable.
| Backend | Value | Use Case | Dependency |
|---|---|---|---|
| In-Memory | memory (default) | Development, testing | None |
| SQLite | sqlite | Single-server production | better-sqlite3 |
| PostgreSQL | postgres | Multi-replica HA deployments | pg |
PostgreSQL Configuration
# Required
export FORMBRIDGE_STORAGE=postgres
export DATABASE_URL=postgresql://user:password@host:5432/formbridge
# Optional: install pg driver
npm install pg
import { PostgresStorage } from '@formbridge/mcp-server';
const storage = new PostgresStorage({
connectionString: process.env.DATABASE_URL!,
maxConnections: 20, // default: 10
idleTimeoutMillis: 30000, // default: 30000
});
await storage.initialize(); // runs migrations automatically
// Or use the factory:
import { createStorageFromEnv } from '@formbridge/mcp-server';
const storage = await createStorageFromEnv(); // reads FORMBRIDGE_STORAGE + DATABASE_URL
The PostgreSQL schema uses proper Postgres types: UUID for IDs, JSONB for structured data, and TIMESTAMPTZ for timestamps. The migration file is at migrations/001_init.sql.
Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FormBridge Core β
β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β Intake β β Submission β β Approval β β
β β Registry β β Manager β β Manager β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β Event β β Webhook β β Condition β β
β β Store β β Manager β β Evaluator β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Storage Layer β β
β β Memory (dev) β SQLite (prod) β S3 (file uploads) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β HTTP API β β MCP Server β β
β β (Hono) β β (Stdio + SSE transports) β β
β ββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β Auth / RBAC β β Rate Limiting β β
β β Multi-tenancy β β CORS β β
β ββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β React Form β β Admin Dashboard β
β Renderer β β (React SPA) β
ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β CLI Scaffolding β β Schema Normalizer β
β (create-formbridge)β β (Zod/JSONSchema/OpenAPI β IR) β
ββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
Project Structure
src/
auth/ # API key auth, OAuth, RBAC, rate limiting, tenant isolation
core/ # Business logic β submission manager, approval gates, events,
# state machine, condition evaluator, webhook delivery
mcp/ # MCP server, tool generator, stdio + SSE transports
middleware/ # Hono middleware (CORS, error handling)
routes/ # HTTP route handlers (submissions, approvals, uploads, events,
# webhooks, analytics, health)
storage/ # Storage backends (memory, SQLite, S3) + migration utility
types/ # TypeScript types and intake contract spec
packages/
admin-dashboard/ # React SPA β intake management, submission review, analytics
create-formbridge/ # CLI tool β interactive + non-interactive project scaffolding
form-renderer/ # React components β FormBridgeForm, ResumeFormPage, WizardForm
schema-normalizer/ # Converts Zod, JSON Schema, OpenAPI β unified IntakeSchema IR
shared/ # Shared utilities across packages
templates/ # 5 starter templates with full schema definitions
demo/ # Demo app with sample intakes and pre-configured workflows
docs/ # VitePress documentation site
tests/ # 1,339 tests across 50 files
.github/workflows/ # CI (lint + typecheck + tests on Node 18/20/22) + release
Development
# Install dependencies
npm install
# Run all 1,339 tests
npm run test:run
# Watch mode
npm test
# Type checking (zero errors)
npm run typecheck
# Lint (ESLint flat config v9)
npm run lint
# Build
npm run build
# Run the demo app
cd packages/demo && npm run dev
Testing
The test suite covers:
- Core logic β Submission lifecycle, state machine transitions, approval workflows, field attribution
- API endpoints β Full HTTP request/response testing for all routes
- MCP server β Tool generation, server initialization, transport handling
- Storage backends β Memory, SQLite, and S3 storage with edge cases
- CLI scaffolding β End-to-end CLI tests (interactive + non-interactive)
- Schema normalization β Zod, JSON Schema, and OpenAPI conversion
- Condition evaluation β Dynamic field visibility rules
- Webhook delivery β HMAC signing, retry logic, delivery tracking
1,339 tests passing across 50 test files, 85.9% code coverage
Roadmap
- npm package publishing (5 packages live on npm)
- PostgreSQL storage backend
- Real-time collaboration (WebSocket field locking)
- Email notifications for pending approvals
- Form analytics dashboard with charts
- Hosted cloud version
Contributing
Contributions welcome! Please open an issue first to discuss what you'd like to change.
git clone https://github.com/agentkitai/formbridge.git
cd formbridge
npm install
npm run test:run # All tests pass
npm run typecheck # Zero errors
npm run lint # Clean
π§° AgentKit Ecosystem
| Project | Description | |
|---|---|---|
| AgentLens | Observability & audit trail for AI agents | |
| Lore | Cross-agent memory and lesson sharing | |
| AgentGate | Human-in-the-loop approval gateway | |
| FormBridge | Agent-human mixed-mode forms | β¬ οΈ you are here |
| AgentEval | Testing & evaluation framework | |
| agentkit-mesh | Agent discovery & delegation | |
| agentkit-cli | Unified CLI orchestrator | |
| agentkit-guardrails | Reactive policy guardrails |
License
MIT Β© 2026 Amit Paz
