Pitch Protocol
Measured conclusion: Deep-tested. L2 outcome: tools_ok.
Founder-side MCP server for Pitch Protocol, agent-native venture capital. A founder's agent submits one application (about ten minutes, no web form, deck optional) and it is reviewed and matched against the theses of 15+
| Author | Pitch Protocol |
|---|---|
| Access | remote |
| Publisher key required | No |
| Measured state | Deep-tested |
| L1 liveness | alive |
| L1 latency | 139 ms |
| Last measured | 2026-10-26 |
Add to your agent
Copy this into your MCP client config:
{
"mcpServers": {
"Pitch Protocol": {
"url": "https://api.pitchprotocol.vc/mcp/founder",
"transport": "streamable-http"
}
}
}
Measured tools (7)
resend_verificationIssue a fresh 6-digit verification code. Supersedes any prior unconsumed code. **When:** founder didn't receive the first code, the code expired, or too many wrong attempts invalidated it. **Before you call:** nothing. Safe to call multiple times (rate-limited). **Returns:** confirmation the new code was emailed (in dev: the code itself). **On error:** - Rate-limited — the error tells you how many seconds to wait. Don't spam. - Already verified — status already past `draft`. Nothing to resend. Call `get_status` to confirm the current state.
Parameters:
applicationId(required) — string — Application id from `create_application`.
Hints: read-only no · destructive no · idempotent no · open-world yes
update_applicationUpdate an application's payload and/or contact email while it's still in `draft`. **When:** founder caught something wrong after `create_application` but before `verify_email`. Also when changing the email address. **Before you call:** - Full-replace on payload: send the WHOLE `PitchApplication` object, not a patch. Read current values from `get_status` if you don't have them. - Email change resets verification: `emailVerified` goes back to false and a fresh code is sent to the NEW address. Let the founder know. **Returns:** the fresh `StatusView` — markdown by default, JSON if `responseFormat: "json"`. Same shape as `get_status`. **On error:** - `notEditable` — status is past `draft`. Nothing to update; state is locked. Read `get_status` to understand where you are. - Validation failed — payload doesn't satisfy the schema. Fix per the error message and retry.
Parameters:
applicationId(required) — string — Application id from `create_application`.payload— ['string', 'null'] — Full PitchApplication JSON (optional). Replaces the current payload wholesale.contactEmail— ['string', 'null'] — New contact email (optional). Resets verification and issues a new code.responseFormat— string — `markdown` (default) or `json`. JSON returns the raw StatusView for programmatic use.
Hints: read-only no · destructive no · idempotent yes · open-world yes
get_statusread-onlyThe primary status endpoint. Returns the full current state of an application: status, email verification, deck state, intake questions (when ready), and a `nextAction` string. **While research runs (`status == "researching"`) — read this:** This call WAITS server-side. It holds for up to ~45 seconds and returns the instant research finishes (or after ~45s if nothing has changed yet). You do NOT sleep or set timers yourself — you just call it again. Research usually completes within a handful of these blocking calls (~5–10 min total). Between calls, give the founder a short "still researching…" note so they're not left wondering — but do NOT ask permission to keep checking, and do NOT hand control back as if it failed. Keep calling until `status` leaves `researching`. In all other states (`draft`, `intake`, `submitted`, `failed`, `withdrawn`) this returns immediately and `nextAction` is the founder-facing instruction — read it to them verbatim and act on their reply. **When to call:** - After `verify_email` — call again and again until status leaves `researching`. - When the founder asks for an update. - To read intake questions when `status == "intake"`. **Before you call:** nothing. **Returns:** markdown by default. Use `responseFormat: "json"` when you need to branch programmatically on `status` / `deck.state`. **On error:** `notFound` if the applicationId is wrong. Otherwise safe to call repeatedly.
Parameters:
applicationId(required) — string — Application id from `create_application`.responseFormat— string — `markdown` (default) or `json`. JSON returns the raw StatusView for programmatic use.
Hints: read-only yes · destructive no · idempotent yes · open-world no
submit_answersdestructiveSave the founder's answers to the intake questions. Upsert semantics with an explicit commit flag. **When:** `status == "intake"`, after research generates the questions. Read them from `get_status` → `intake.questions`. **Before you call:** - READ the questions to the founder verbatim. Ask only the question `text` — do not volunteer or invent any internal rationale for why we ask. - Collect answers conversationally; don't make them answer all five at once if they'd rather talk through them. - If `finalize: true`: show every answer back to the founder for confirmation first. This is one-way — after finalize they can't edit. - If `finalize: false` (autosave): no confirmation needed. **Answers shape:** array of `{questionId, answer}` objects. Only include question ids that were in the `get_status` response — other ids are rejected. **Upsert rules:** - Answers with matching `questionId` overwrite. - Prior answers for ids NOT in this batch are KEPT. - So you can save Q1 + Q2 in one call, Q3-Q5 in another, then commit with `finalize: true` + empty `answers: []` at the end. **On error:** - `unknown questionIds` — check spelling / the id list from `get_status`. - `missing required` — on `finalize: true`, every `priority=required` must have an answer. Error lists which are missing. - `alreadyAnswered` — you called finalize twice. Status is `submitted`; no more edits. - Wrong status — not in `intake` yet (still researching) or already past it.
Parameters:
applicationId(required) — string — Application id from `create_application`.answers(required) — array — Array of `{questionId, answer}` objects. Can be empty when finalize is true.finalize— boolean — If true, commits the answers and flips status to submitted. One-way — confirm with founder first.
Hints: read-only no · destructive yes · idempotent no · open-world yes
verify_emailConsume the 6-digit code the founder received and start the research pipeline. **When:** after `create_application`, and ideally after the deck has been uploaded over plain HTTP (see the `curl` printed by `create_application`). Founder has read the code from their inbox. **Before you call:** - CONFIRM you have the right code from the founder (not guessing, not stale). Once this succeeds, research starts and is irreversible. - If deck parsing is still pending, that's fine — research auto-defers and dispatches when the deck resolves. Don't wait, don't re-verify. **Returns:** `status: researching` + whether research was dispatched now or deferred on the deck. **On error:** - `wrong code` — response includes attempts-remaining. Ask the founder to check their inbox again. If the error says the code is invalidated, call `resend_verification` for a new one. - `no active code` — they never received one, or it expired. Call `resend_verification`. - Already verified — idempotent success; returns current status. Don't retry in a loop.
Parameters:
applicationId(required) — string — Application id from `create_application`.code(required) — string — The 6-digit numeric code from the founder's inbox.
Hints: read-only no · destructive no · idempotent yes · open-world yes
create_applicationCreate a new pitch application draft and send a 6-digit verification code to `contactEmail`. **When:** once you have a complete payload (research + deck + founder confirmed). One per conversation with a given founder. **Before you call:** 1. `get_application_schema` — know the fields, limits, enums. 2. Get the founder's source material — deck, memo, one-pager, website, or even a few sentences — and READ/parse it yourself (plus web search) to fill the payload. The deck is an input you read, not a file to upload. 3. Ask the founder for anything you can't find or confirm. Don't fabricate — leave gaps and ask. 4. Show the assembled payload to the founder for review before submitting. **Returns:** `applicationId` — required for every subsequent tool call — plus `codeSent` and (in dev) `devCode`. **Next:** ask the founder for the 6-digit code and call `verify_email`.
Parameters:
contactEmail(required) — string — Email where the 6-digit verification code will be sent. Must be the founder's real address.submittedBy(required) — string — Identifier for the agent/client submitting on the founder's behalf (e.g. your client name or ID). Required — every application must record who submitted it.payload(required) — string — Full PitchApplication JSON payload. Call `get_application_schema` for field list + limits.
Hints: read-only no · destructive no · idempotent no · open-world yes
get_application_schemaread-onlyThe authoritative field reference for the `PitchApplication` payload. **When:** call this FIRST in every session. Cache the response. **Before you call:** nothing — no inputs. **Returns:** markdown listing every field, type, limit, enum, plus a complete valid example. With this in context, you can assemble a payload that validates on the first `create_application`.
Hints: read-only yes · destructive no · idempotent yes · open-world no
Measured by MCPYP probing. Untested fields are omitted, never estimated. Listing is always free; MCPYP never proxies calls or stores user tokens.