---
name: gopigeon
description: >-
  Route AI agents through the gopigeon MCP server to set up form endpoints and
  durable message queues. Use this skill whenever a user wants to add a contact,
  feedback, signup, or lead-capture form to a site; needs a "form backend" or
  "form endpoint" without running a server; wants form submissions emailed or
  forwarded to Slack, Discord, or a webhook; is building a webhook receiver or an
  ingest queue for an agent workstream; or mentions gopigeon by name. It points
  the agent straight at the tool it actually needs (create_endpoint) instead of
  getting lost in the nine-tool surface, and teaches the claim-flow gotcha — the
  first real submission is irreversible — along with the dry_run and
  inspect_endpoint tools that verify an integration without burning it. Don't use
  it for building form UI/markup, general transactional email, or as a database
  to query.
metadata:
  version: "0.2.0"
---

# gopigeon

gopigeon turns a single HTTP POST into a form backend. `create_endpoint` returns
a live URL that accepts form submissions and fans them out to email, Slack,
Discord, or webhooks — no signup, no server, no API key to start.

This skill exists because the MCP exposes **nine tools across two surfaces**
(forms and queues), and for the overwhelmingly common case — "add a contact
form" — an agent needs one tool plus, optionally, one verification probe. The
tool descriptions are a menu; this skill is the recipe. Use it to route straight
to the right tool and to verify an integration without tripping the claim-flow
gotcha.

## The one decision: forms or queues

Before touching a tool, decide which surface the task wants. This is the most
important call, because it determines whether most of the nine tools are
irrelevant noise.

**Forms** — a human (or a browser form) submits, and a person receives it.
Contact forms, feedback widgets, signup forms, lead capture, "email me when
someone fills this out." This is the overwhelming majority of uses. The front
door is `create_endpoint`; `inspect_endpoint` is the verification helper.

**Queues** — a *program* publishes messages and a *program* consumes them,
durably, one at a time with cursors and acks. Agent job ingestion, a webhook
event stream an agent works through, programmatic pipelines. Uses `create_queue`
/ `publish_to_queue` / `pull_queue` / `ack_queue`.

If the task is a form, ignore the five queue tools entirely — they are
progressive disclosure for later, not part of the basic path. When in doubt, it
is a form: queues are the exception, reached for deliberately.

## Forms: the workflow

1. **Create the endpoint.** Call `create_endpoint` with the `recipient` email —
   the address that should receive submissions. No API key required. It returns
   `form_id`, `endpoint_url`, and a `claim_note`. Use the values it returns
   directly; do not reconstruct the URL by hand.

2. **Wire the URL in.** Drop `endpoint_url` into the form. For a plain HTML form
   it is the `action` attribute:

   ```html
   <form action="https://api.gopigeon.dev/f/f_abc123" method="POST">
     <input name="email" type="email" required />
     <textarea name="message" required></textarea>
     <button>Send</button>
   </form>
   ```

   For a JavaScript submit: `fetch(endpoint_url, { method: 'POST', body: new
   FormData(form) })`.

3. **Verify before handing off.** Confirm the wiring with a side-effect-free
   check (see the next section) rather than a real test submission.

4. **Hand off.** Tell the user submissions go to their inbox, and that they will
   receive a one-click claim email on the first real submission.

The endpoint accepts both content types, so use whatever the form naturally
produces:

- `application/json` — any keys. There is **no fixed schema**; every key you send
  is stored and forwarded.
- `application/x-www-form-urlencoded` — what a plain HTML form posts, so a
  no-JavaScript fallback form works without any extra handling.

## The claim flow — and how to verify safely

A new endpoint is **unclaimed**. The recipient becomes its owner by clicking a
one-click link in the email gopigeon sends on the **first non-spam submission**.
That is the entire signup: no account, no password, until a real submission
proves someone wants the endpoint.

The thing to flag to the user: **the first real submission is irreversible.** It
sends a live email and consumes the one-time claim link. So never fire a casual
"does this work?" submission against an endpoint whose recipient is someone else
— that test *becomes* their first real email and claim link.

But you do not have to risk it. gopigeon has two no-side-effect verification
paths (v0.3.0+) — prefer them over a real test submission:

- **`inspect_endpoint`** — a no-auth, no-side-effect probe. Pass a form (`f_*`)
  or queue (`q_*`) ID; it returns `{exists, claimed, active}`, or
  `{exists: false}` if the ID is unknown (a valid answer, not an error). It is
  marked read-only and idempotent. Call it before any real submission to confirm
  the endpoint exists and whether the claim slot is still open.
- **`dry_run: true`** — a parameter on `create_endpoint` (and `publish_to_queue`
  for queues). The backend runs the full guard cascade (CORS, rate-limit,
  honeypot, quota check) and returns a routing preview only — it creates nothing
  and sends nothing: no endpoint, no email, no claim event, no quota counter.
  Use it to confirm the recipient and routing are right before committing to a
  live endpoint.

So the recommended verification flow for a form integration: optionally preview
with `dry_run: true` on `create_endpoint`, create the endpoint for real, then
call `inspect_endpoint` to confirm it exists and the claim slot is still open —
and only then let the first real submission through. Still tell the user the
first submission triggers the claim email so it is not a surprise, but you no
longer need to fire a blind test submission to check.

## Reading submissions back

`get_submissions` and `list_endpoints` let an agent read submission data
programmatically, but they require `GOPIGEON_API_KEY` to be set in the MCP
config. Without that key, only `create_endpoint`, `inspect_endpoint`, and
`create_queue` work — that is expected behavior, not an error. If the user wants
programmatic read access, point them at generating a key (`POST /api/keys` from
the dashboard) and setting `GOPIGEON_API_KEY` in their MCP config.

## Queues — only when the task is genuinely program-to-program

If, and only if, the task is programmatic message passing, the queue surface
applies: `create_queue` returns a `queue_api_key` **once** (store it as
`GOPIGEON_QUEUE_API_KEY`), then `publish_to_queue` appends a message,
`pull_queue` reads with a cursor, and `ack_queue` advances that cursor after the
consumer has processed the messages. `publish_to_queue` also accepts
`dry_run: true` for a side-effect-free routing preview. `subscribe_form_to_queue`
is the bridge between the surfaces — it mirrors a form's submissions into a
queue, which is the natural upgrade when a form outgrows plain email relay.

This skill deliberately does not detail the queue protocol — see the MCP
`README.md` for the full publish/pull/ack worked example. The point here is only:
do not reach for queues on a plain form task.

## When this applies

**Use this skill when** the user wants to: add a contact, feedback, signup, or
lead-capture form to a site; needs a "form endpoint" or "form backend" without
running a server; wants form submissions sent to email, Slack, Discord, or a
webhook; is wiring a webhook receiver or an ingest queue for an agent
workstream; or names gopigeon directly.

**Skip it when** the user wants: a form *UI* component or markup library — this
skill is about the backend, not styling or HTML scaffolding; general
transactional email sending — gopigeon relays form submissions, it is not an
email API; or a database — gopigeon stores and forwards submissions, it is not a
datastore you query.

## Tool reference

Forms surface:

- `create_endpoint` — no auth. **Start here for any form task.** Accepts
  `dry_run: true` for a side-effect-free routing preview.
- `inspect_endpoint` — no auth, no side effects. Probes `{exists, claimed,
  active}` for an `f_*` or `q_*` ID. Use it before consuming the claim event.
- `get_submissions` — read submissions for an endpoint you own. Needs
  `GOPIGEON_API_KEY`.
- `list_endpoints` — list endpoints you own. Needs `GOPIGEON_API_KEY`.

Queue surface (programmatic ingestion only):

- `create_queue` — no auth. Returns `queue_api_key` once.
- `publish_to_queue` — append a message. Accepts `dry_run: true`. Needs
  `GOPIGEON_QUEUE_API_KEY`.
- `pull_queue` — read messages past a cursor. Needs `GOPIGEON_QUEUE_API_KEY`.
- `ack_queue` — advance the cursor. Needs `GOPIGEON_QUEUE_API_KEY`.
- `subscribe_form_to_queue` — mirror a form's submissions into a queue. Needs
  `GOPIGEON_API_KEY` (it mutates the form side).
