Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
BRIEFGATE_API_KEYYesAPI key (`bg_live_...` or `bg_test_...`). Obtain from the BriefGate dashboard.
BRIEFGATE_BASE_URLNoOverride for staging or local development.https://api.briefgate.dev
BRIEFGATE_MCP_HTTPNoSet to `1` to start Streamable HTTP instead of stdio.
BRIEFGATE_MCP_PORTNoPort for HTTP mode.3000

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
define_intakeA

Create a new client intake request — a branded portal where the client submits logos, copy, files, credentials, and other assets. BriefGate sends the invite email and chases the client automatically until all items are collected.

Call this once at the start of a project, after you know what assets you need. Returns { intake_id, portal_url, status, follow_up }. Save intake_id — you need it for all follow-up calls.

AFTER CREATING AN INTAKE, SET UP HOW YOU WILL LEARN IT IS DONE. Nothing pushes to you on its own: MCP is request/response, so the server cannot wake you when the client finishes. Creating the intake and never checking again is the common failure — the completed work then sits in the portal until a human happens to look. The returned follow_up block tells you which of the two mechanisms applies:

  • follow_up.recommended = "webhook" — the account already has an endpoint; deliveries will arrive there and you need do nothing further.

  • follow_up.recommended = "schedule" — no endpoint is registered. If you control a service that can receive public HTTPS, register one with manage_webhook. Otherwise tell the user to set up a recurring check (cron, a systemd timer, a scheduled task in their agent host) that calls get_intake_status every follow_up.schedule.every_hours hours until follow_up.schedule.until, and offer to configure it for them.

Example: { "project_name": "Website for John Finance", "client": { "email": "john@example.com", "name": "John", "language": "cs" }, "due_date": "2026-08-15", "branding": { "accent_color": "#1B2A4A", "sender_name": "Radim" }, "items": [ { "key": "logo", "type": "image", "label": "Company logo", "constraints": { "formats": ["svg","png"], "min_width": 512 } }, { "key": "hero_copy", "type": "longtext", "label": "Homepage headline (2–3 sentences)", "constraints": { "max_chars": 400 } }, { "key": "wp_admin", "type": "secret", "label": "WordPress admin credentials" }, { "key": "photos", "type": "file_list", "label": "Photos (5–10 images)", "constraints": { "formats": ["jpg","png","heic"], "min_count": 5, "max_count": 15 } } ] }

Item types: text, longtext, file, file_list, image, color_list, select (one of options[]), multiselect (several of options[]; min_count/max_count in constraints), boolean, url, secret (encrypted; revealed exactly once — store the value on the first read), structured (requires schema with JSON Schema).

DECISIONS — questions for the developer, not the client. An item with assignee="owner" and type select/multiselect is a question only the account holder can settle ("does the discounted plan cost 19 or 29?"). Never stop and wait for one: give it a "proposed" answer and carry on building. proposed = { value: "19", rationale: "matches the competitor we benchmarked" } records what you went with and why; it is stored separately from the real answer, so it can never be mistaken for one the developer gave.

Read the answer back from get_intake_results. meta..decided_by tells you which it is: "owner" means a person settled it, "agent_proposal" means the build is still standing on your own pick and may yet be overruled. You cannot confirm your own proposal — answering is the developer's, through the dashboard. Item keys must be snake_case (e.g. "logo", "hero_copy", "ga4_id") — they become property names in get_intake_results.

get_intake_statusA

Check the completion status of a client intake — which items are submitted, pending, or need revision; the history of automated chase emails sent; and when the client last opened the portal.

Use this to decide whether to send a manual reminder (send_chase), request a revision (request_revision), or fetch results (get_intake_results). Returns per-item status and chase history.

This is also the call a scheduled check should make when no webhook is registered — see follow_up in the define_intake response for the cadence. When status becomes "completed", fetch the results with get_intake_results and carry on with the work that was waiting on them.

get_intake_resultsA

Retrieve the typed submitted values from a client intake.

Files are returned as signed URLs valid for 24 hours — download them promptly or store the URL for reuse within that window.

Secrets (type=secret, e.g. passwords, API keys) are decrypted and returned in plaintext on the FIRST call only. After the first retrieval the secret is marked as read: subsequent calls return first_reveal: false in meta and omit the value. Store secrets immediately before proceeding — you cannot retrieve them again.

Use only_new=true to get only items submitted since the last call (useful in webhook-driven workflows). Use include_pending=true to also return partially filled items.

Returns { results: { : }, meta: { : { type, status, submitted_at, first_reveal? } } }.

For a DECISION (assignee=owner, type select/multiselect) results holds the answer currently standing and meta..decided_by says whose it is: "owner" once a person has settled it, "agent_proposal" while it is still your own pick. A proposed decision is returned even without include_pending — you need back the assumption you are building on. It does not bump revision, so an only_new read surfaces exactly the decisions a person has since answered or changed.

request_revisionA

Ask the client to resubmit a specific item with a note explaining what is wrong.

Use this after reviewing get_intake_results and finding an item that does not meet requirements — for example a blurry logo, copy that is too long, or a broken URL. The client is notified automatically and the item status moves to needs_revision.

Returns { status: "revision_requested", item_key }.

send_chaseA

Send a manual reminder to the client outside the automatic schedule.

Use when a deadline is approaching and the client has not responded to automatic reminders, or when you want to send an SMS after email attempts have failed. The automatic chase schedule continues after this call — this is an extra nudge, not a replacement.

Returns { sent: true }.

list_intakesA

List all intakes in your account, optionally filtered by status, client email, folder, or a text search.

Use this to get an overview of active projects, find a specific intake by the client's email when you have lost the intake_id, check how many intakes are currently in progress, or see what's in a folder from list_folders.

Returns { intakes: [...], total } where each intake includes intake_id, project_name, status, created_at, due_date, folder_id, and portal_url.

add_itemsA

Add new items to an already-sent intake — for example, when you realise mid-project that you also need a favicon, social media assets, or additional credentials.

The client is notified about the new items. Existing items and their submitted values are not affected. Returns the updated intake object.

Items must follow the same key/type/label rules as define_intake (snake_case keys, type-specific constraints).

update_itemA

Change one item on an intake that is already with the client — its type, label, hint, whether it is required, and which file formats it accepts.

Reach for this when the field turns out to be the wrong shape: you asked for an image and the client only has their logo as a PDF, or what you asked for as a line of text is really a file. Widening the accepted formats or switching the type unblocks them without adding a duplicate item and waiving the original.

The item key cannot be changed — results come back under it, so renaming would break whatever reads them. Add a new item instead.

If the client has already answered and the change would make their answer invalid, the call fails and nothing is touched. Repeat it with discard_submitted_value: true to clear the answer and ask them again. A change that leaves their answer valid (a new label, a wider limit) never discards anything.

update_intakeA

Change settings on an intake that has already been sent — project name, due date, reminder cadence, quiet hours, which folder it's in, the client brief, or the client's name, phone, language, and timezone.

Use this instead of deleting and recreating the intake when a deadline moves or the chase cadence needs to change. If any of chase_schedule, chase_interval, chase_interval_unit, chase_at_time, max_reminders, respect_quiet_hours, due_date, or client.timezone is included, every pending reminder is cancelled and the schedule is re-planned from now — reminders already sent still count toward max_reminders. Raising max_reminders (or setting it to "unlimited") past the number already sent on a stalled intake reactivates it and resumes chasing.

The client's e-mail address cannot be changed here — the portal link and login are bound to it. Use manage_recipients to add, remove, or reinstate an address.

folder_id moves the intake to a different folder (an id from list_folders); set it to null to remove the intake from any folder. It never touches the chase schedule.

client_brief replaces the free-text brief shown to the client above the requested items; set it to null to clear it. Documents attached to the brief are managed via the dashboard or the REST endpoint POST /v1/intakes/:id/brief/files, not through this tool.

Fails if the intake is archived. At least one field must be given. Returns the full, updated intake object.

manage_recipientsA

Add, remove, or reinstate a person who receives an intake's invite and reminders, alongside or instead of the primary client.

action="add" invites another address the same way also_notify does at define_intake time — its own message, its own bounce state; pass name to address it by name. action="remove" stops future reminders to that address. action="reinstate" is for a bounce that was wrong — the person did get the e-mail — and clears the bounce flag so reminders resume; if that address was the only one still being chased, the schedule is re-planned from now.

Fails if the address is not on the intake, or — for reinstate — if it never bounced in the first place.

manage_webhookA

Register, list, or remove a webhook endpoint so BriefGate pushes intake events to your service instead of you polling for them.

Use this ONLY if you control a service that can receive public HTTPS requests. An agent running in a terminal cannot — for that case do not register anything and check on a schedule with get_intake_status instead. A registered endpoint that cannot receive produces failing deliveries and a false impression that the work is being watched.

action="create" returns a "secret" exactly once. Store it somewhere durable outside this conversation: it is needed to verify the signature on every delivery (use verifyWebhookSignature from @briefgate/mcp/webhook) and it cannot be retrieved again. If it is ever exposed, there is no rotation in place — delete the endpoint and create a new one, which issues a fresh secret.

Events: intake.completed (all required items in — the one to act on), item.submitted (a single item arrived), client.viewed (the client opened the portal), chase.bounced (a reminder failed to deliver), intake.overdue (the due date passed with required items outstanding — the one to act on when work is blocked), intake.stalled (fires only when the intake sets max_reminders; without it this event never arrives).

list_foldersA

List the folders in your account, used to group intakes by client or project.

Call this before create_folder or before setting folder_id on define_intake, update_intake, or list_intakes — reuse an existing folder for a returning client instead of creating a duplicate.

Returns { folders: [{ id, name, sort_order, intake_count, created_at }] }.

create_folderA

Create a new folder to group intakes, e.g. one per client.

Call list_folders first and reuse a matching folder — only create one when none of the existing folders fits. Fails with folder_exists if a folder with this name already exists; use list_folders to find it instead.

Returns the created folder { id, name, sort_order, intake_count, created_at }.

loginA

Sign in without pasting an API key, the same way snyk_auth works: this opens a browser page where a human approves this device, then stores the issued key locally.

Call this whenever a tool reports "Not signed in" or that the stored key was revoked or expired.

This is a TWO-PHASE tool because approval can take minutes — longer than a single tool call should block for:

  1. The first call starts the sign-in and returns immediately with a URL and a short code (e.g. "WDJB-MJHT"). Tell the user to open the URL and confirm the code; a browser is also opened automatically when possible.

  2. Call login again (no arguments change) to check progress. While the human hasn't approved yet, it replies that it's still waiting. Once approved, the same call reports success and the key is saved — no further action needed, other tools start working immediately.

Do not wait silently for minutes on one call — call this tool again after telling the user to approve, and again if they say they've clicked Allow.

Has no effect if a key is already supplied via the --api-key flag or the BRIEFGATE_API_KEY environment variable — those always take priority over a locally stored one, so this tool says so instead of running the flow. Not available when this server is running as the shared hosted endpoint (mcp.briefgate.dev): there, connecting a client already triggers OAuth automatically.

logoutA

Remove the API key login stored locally for this BriefGate server, and best-effort revoke it on the server too (a DELETE /v1/keys/current call using that same key). If the revoke call fails — no network, the API is unreachable — the local copy is still removed; the response says so and points at the BriefGate dashboard to revoke it there instead. Not available when this server is running as the shared hosted endpoint.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.2/5.0

Scored across 15 tools

Disambiguation5/5

Each tool targets a distinct resource-action pair: intakes, items, folders, recipients, webhooks, and auth are cleanly separated. Even get_intake_status vs get_intake_results are clearly differentiated as progress tracking vs value retrieval. No two tools have overlapping purposes that would cause misselection.

Naming Consistency4/5

The set mostly follows a consistent verb_noun snake_case pattern (list_folders, get_intake_results, add_items, update_item, manage_webhook). Minor deviations exist: 'login'/'logout' lack an object, and 'define_intake' uses a different create verb than 'create_folder', but the overall pattern remains predictable.

Tool Count5/5

15 tools is well within the appropriate range for a dedicated intake-management product. Each tool serves a necessary role across auth, folders, intake lifecycle, item management, recipients, and webhooks, with no redundancy or bloat.

Completeness4/5

The core lifecycle is well covered: create, read status and results, update intakes/items, add items, request revisions, send chases, manage recipients and webhooks. The main gap is the lack of an explicit archive or delete tool for intakes (the archived state is referenced but not actionable via MCP), and no direct remove-item operation, though these are workaroundable via the dashboard.

Maintenance

ActivityMaintained
ResponsivenessNo issues