Quickstart — 5 minutes to your first intake
This guide walks you through installing BriefGate, connecting it to your coding agent, and sending your first client intake.
Prerequisites
- Node.js 18 or later — needed for the local package (Options 1 and 2 below). The hosted endpoint needs nothing installed.
- An MCP-capable agent — Claude Code, Cursor, claude.ai, or any client that speaks the Model Context Protocol.
- A BriefGate account — sign up at https://app.briefgate.dev/app. You don't need an API key up front: Options 0 and 1 below sign you in without one.
1. Connect BriefGate to your agent
Four ways to connect, all producing the same 13 tools. The first two need no API key to copy or paste.
Option 0 — hosted endpoint, OAuth (recommended for Claude Code and claude.ai):
claude mcp add --transport http briefgate https://mcp.briefgate.dev/mcpThen start Claude Code, run /mcp, pick briefgate and choose Authenticate. Your browser opens the dashboard, where you sign in and approve access — nothing to install, nothing to paste. Until you do this, the server shows as needing authentication and its tools stay unavailable. In claude.ai, use Settings > Connectors > Add custom connector with the same URL. Any MCP client that speaks Streamable HTTP and OAuth 2.1 connects the same way.
Option 1 — local package, device login (recommended for the Claude Code CLI when you'd rather not do a browser OAuth redirect, or for scripting a terminal agent):
claude mcp add briefgate -- npx -y @briefgate/mcp
npx -y @briefgate/mcp loginlogin prints a short code and opens the dashboard in your browser; approve it there. The API key it receives is stored in ~/.briefgate/credentials.json (directory mode 0700, file mode 0600) and used automatically from then on — no environment variable to set. Run npx -y @briefgate/mcp logout to remove it; this also revokes the key on the server.
Option 2 — local package, API key (for CI, scripts, or if you'd rather manage the key yourself):
claude mcp add briefgate -- npx -y @briefgate/mcp --api-key bg_live_xxxxxOr add manually to ~/.claude.json (the mcpServers key holds this for every project; for a config shared with your team, use .mcp.json in the project root instead):
{
"mcpServers": {
"briefgate": {
"command": "npx",
"args": ["-y", "@briefgate/mcp"],
"env": { "BRIEFGATE_API_KEY": "bg_live_xxxxx" }
}
}
}BRIEFGATE_API_KEY, if set, always takes precedence over a stored login credential.
Option 3 — hosted endpoint, API key (for CI or a client that cannot do an OAuth redirect):
claude mcp add --transport http briefgate https://mcp.briefgate.dev/mcp \
--header "Authorization: Bearer bg_live_xxxxx"For Options 2 and 3, get a key from the dashboard at https://app.briefgate.dev/app. To try things out during development without emailing a real client, create the intake with "send": false — it stays a draft — then check GET /v1/intakes/preview (or the dashboard preview) to see the exact subject line and sender name before anything goes out, and call POST /v1/intakes/:id/send when you're ready.
Restart your agent after changing its MCP config.
2. Your first intake
The example below creates an intake for a restaurant website project. Paste this into your agent's context (or call the define_intake MCP tool directly):
{
"project_name": "Bella Napoli — Website",
"client": {
"email": "owner@bellanapoli.com",
"name": "Marco Esposito",
"language": "en"
},
"items": [
{
"key": "logo",
"label": "Restaurant logo",
"help": "Upload your logo in SVG or PNG format with a transparent background. Minimum 512px on the shortest side.",
"type": "image",
"required": true,
"constraints": {
"formats": ["svg", "png"],
"min_width": 512,
"transparent_background": true
}
},
{
"key": "hero_copy",
"label": "Hero section tagline",
"help": "A short paragraph (up to 400 characters) that captures the spirit of the restaurant. This appears above the fold on the homepage.",
"type": "longtext",
"required": true,
"constraints": {
"max_chars": 400
}
},
{
"key": "opening_hours",
"label": "Opening hours",
"help": "Your regular opening hours. Use a simple format like '12:00-22:00' or 'Closed'.",
"type": "structured",
"required": true,
"schema": {
"type": "object",
"required": ["mon_fri", "sat", "sun"],
"properties": {
"mon_fri": { "type": "string", "example": "12:00-22:00" },
"sat": { "type": "string", "example": "12:00-23:00" },
"sun": { "type": "string", "example": "13:00-21:00" }
}
}
},
{
"key": "photos",
"label": "Food and interior photos",
"help": "Upload between 5 and 15 photos of your food, interior, and ambience. JPG, PNG, or HEIC.",
"type": "file_list",
"required": true,
"constraints": {
"formats": ["jpg", "png", "heic"],
"min_count": 5,
"max_count": 15
}
}
],
"chase_schedule": "default"
}The tool returns:
{
"intake_id": "in_8f3kQmR2",
"portal_url": "https://p.briefgate.dev/8f3kqmr2",
"status": "sent",
"items": [
{ "key": "logo", "status": "pending" },
{ "key": "hero_copy", "status": "pending" },
{ "key": "opening_hours", "status": "pending" },
{ "key": "photos", "status": "pending" }
],
"follow_up": {
"recommended": "schedule",
"reason": "No webhook endpoint is registered on this account. Register one if you run a service that can receive HTTPS; otherwise check on a schedule.",
"webhook": {
"active_endpoints": 0,
"events": ["intake.completed", "item.submitted"],
"register_with": "manage_webhook"
},
"schedule": {
"check_with": "get_intake_status",
"every_hours": 24,
"until": "2026-04-08T00:00:00.000Z"
}
}
}BriefGate immediately emails the client a personal link to portal_url, carrying a one-time sign-in token that the API never returns — so portal_url on its own does not open the portal. The intake status becomes sent. follow_up tells you how to learn the intake is done: register a webhook with manage_webhook, or poll get_intake_status every follow_up.schedule.every_hours hours until follow_up.schedule.until.
3. What happens next
- The client receives an email with a link to their personal intake portal.
- They upload or fill in each item directly in the browser — no account required.
- As they submit items, BriefGate fires webhooks to your endpoint (configure them in the dashboard under Settings > Webhooks).
- If the client does not complete the intake, the chase engine sends automatic follow-up emails on the schedule you specified.
- When all required items are submitted, the intake status transitions to
completedand a final webhook fires.
4. Check status
Via MCP (in your agent):
Call: get_intake_status
Args: { "intake_id": "in_8f3kQmR2" }Via REST:
curl https://api.briefgate.dev/v1/intakes/in_8f3kQmR2/status \
-H "Authorization: Bearer bg_live_xxxxx"Both return the completion percentage, per-item statuses, and a timeline of chase emails sent so far.
5. Get results when complete
Via MCP:
Call: get_intake_results
Args: { "intake_id": "in_8f3kQmR2" }Via REST:
curl https://api.briefgate.dev/v1/intakes/in_8f3kQmR2/results \
-H "Authorization: Bearer bg_live_xxxxx"The response contains typed, ready-to-use data:
- Text and longtext items return plain strings.
- Image and file items return signed URLs (valid for 24 hours), dimensions, MIME type, and checksum.
- Secret items return the decrypted plaintext in a
valuefield on the first call only (first_reveal: true). Store it immediately — subsequent calls omit the value. - Structured items return a validated JSON object matching the schema you declared.
Next steps
| Topic | Document |
|---|---|
| Full reference for all 13 MCP tools | mcp.md |
| All 12 item types and their constraints | item-types.md |
| REST API, webhooks, and authentication | rest-api.md |