# GrowFast agent quickstart

Source: https://growfast.sh/agents

## 1. Discover

| Resource | Where |
| --- | --- |
| llms.txt (summary) | https://growfast.sh/llms.txt |
| llms-full.txt (full documentation) | https://growfast.sh/llms-full.txt |
| MCP server card | https://growfast.sh/.well-known/mcp/server-card.json |
| Official MCP Registry name | sh.growfast/growfast |
| OpenAPI 3.1 spec | https://growfast.sh/openapi.json |
| Pricing as markdown | https://growfast.sh/pricing.md |
| OAuth metadata | https://growfast.sh/.well-known/oauth-protected-resource |

## 2. Authenticate

- A GrowFast account owned by a human is required. There is no agent self-signup: the owner signs up at growfast.sh/sign-up (email and password, or Google).
- OAuth 2.1 with PKCE and dynamic client registration: the client discovers the endpoints from the server, the owner sees a consent screen naming the app, and clicks Allow. Only claude.ai, chatgpt.com and loopback redirect addresses are accepted.
- Or an API key the owner creates under Settings > API keys, sent as `Authorization: Bearer sk_live_...` (or `x-api-key`). This is the path for Cursor and scripts.

## 3. Minimal call sequence

| Call | Arguments | Returns |
| --- | --- | --- |
| tools/list | (JSON-RPC method, no arguments) | The tools this key may call, each with annotations (readOnlyHint, destructiveHint, idempotentHint). |
| scan_domain | {"domain": "yourproduct.com"} | The ideal customer profile, a first cold email draft and best-fit companies scored 1-10, each with an MX-checked contact address and the page it was read from. About 30 seconds. Saved to the account and counted against scan quota. |
| draft_outreach_emails | {"seller": {"productName": "Acme", "valueProposition": "Invoice reconciliation for agencies"}, "leads": [{"company": "Globex", "email": "<address from the scan>", "website": "globex.com"}]} | Up to 10 drafts, each to the decision-maker the company's own site names (when it names one). Nothing is sent or saved. 10-60 seconds. |
| set_reddit_monitor | {"productDomain": "yourproduct.com", "productName": "Acme", "productPitch": "Invoice reconciliation for agencies", "keywords": "invoice reconciliation, agency billing"} | Starts listening on Reddit for that product, replacing that product's earlier settings (up to 6 keywords). Read results with list_reddit_matches. |
| list_reddit_matches | {"product": "yourproduct.com", "status": "new"} | Posts where the author needs the product, best first, each with a drafted reply and DM. The owner posts them. |

On the full server (/api/mcp with an API key) get_email_allowance, list_sending_domains, import_leads, export_outreach and list_autopilots are read or dry-run tools. set_autopilot and send_reply send real email and are marked destructive: call them only when the owner has told the agent to. set_autopilot with enabled: true makes GrowFast send every day without a per-send confirmation, and send_reply has no confirm parameter and none of the postal-address, daily-limit or sender-health checks of POST /api/outreach.

## Limits and quotas

- Free accounts and anonymous visitors: 3 domain scans a day, no sending.
- Starter: 1,000 scans a month, 250 outreach emails a month.
- Growth: 5,000 scans a month, 1,500 outreach emails a month.
- Agency: no monthly scan cap, 10,000 outreach emails a month.
- An account sends at most 500 emails a day; each sending domain ramps up over four weeks (the managed GrowFast address stops at 50 a day).
- At most 5 tool calls per JSON-RPC batch and a 64 KB request body.
- draft_outreach_emails takes up to 10 companies per call; set_reddit_monitor takes up to 6 keywords.

## Retries and idempotency

- Read-only tools (readOnlyHint true) can be retried freely.
- set_reddit_monitor and set_autopilot are idempotent (idempotentHint true): the same arguments leave the same settings. A retried set_autopilot does not undo emails already sent.
- scan_domain and send_reply are not idempotent (idempotentHint false): a retry makes a new scan and uses quota, or sends another email. Do not blindly retry send_reply after a timeout; check the thread first.
- There is no idempotency-key parameter.

## Errors the agent should handle

| When | Signal | Do this |
| --- | --- | --- |
| No or invalid credential | HTTP 401 with WWW-Authenticate (resource_metadata); JSON-RPC error -32001 "Missing API key" | Start OAuth or ask the owner for an API key. An expired or revoked OAuth token answers invalid_token: sign in again. |
| Scan quota used up | HTTP 429, body {"error": "...", "quota": {"used", "limit", "window"}} | Stop scanning; tell the owner the limit and window. Do not retry in a loop. |
| REST POST /api/outreach only: plan does not include sending, or the monthly email allowance is spent | HTTP 429, body {"error": "...", "allowance": {...}} | Report it to the owner: sending needs a paid plan or a credit pack, bought at growfast.sh/pricing. |
| REST POST /api/outreach only: daily sending limit reached | HTTP 429, code "daily_limit", scope, remainingToday | Wait for the next day or send fewer emails. |
| REST POST /api/outreach only: sending paused for bounces or complaints | HTTP 403, code "sender_paused", reason | Do not retry. Hand off to the owner. |
| REST POST /api/outreach only: postal address missing | HTTP 400, code "postal_address_required" | Ask the owner to save a postal address in settings; sending is refused until then. |
| REST POST /api/outreach only: email content refused | HTTP 400, code "campaign_content" | Rewrite the email using the message, then ask the owner before sending. |
| Own list not confirmed or refused | HTTP 400 code "list_confirmation_required"; HTTP 422 code "list_refused" | Only set confirmOwnList to true when the owner has said the list is theirs. A refused list is mostly unmailable. |
| Validation | HTTP 400, body {"error": "..."} naming the missing or bad field | Fix the argument and call again. |
| Temporary failure | HTTP 503 with Retry-After, or JSON-RPC -32603 | Retry after the stated delay. |

## Hand off to the human

- Drafts: show the owner the drafts and the scan results, then let them send from the GrowFast dashboard (Outreach) or tell the agent, in so many words, to send.
- Replies: a human reply stops that contact's follow-ups and is forwarded to the owner; replies are sorted and arrive with an AI-drafted answer the owner can edit and send.
- Reddit: the agent drafts; the owner posts, or confirms each send after connecting their own Reddit account (at most 10 a day).
- Anything refused over REST with sender_paused, a missing postal address or a plan limit goes to the owner.

## Human oversight

### What the owner can see
| Mechanism | Detail |
| --- | --- |
| Consent screen | Before any MCP client connects the owner sees which app is asking, what it may do on the account (the ChatGPT and Claude connectors cannot send or post; the full server can) and clicks Allow or Cancel. |
| Outreach dashboard | Everyone emailed, with delivery and reply status, on the Results page; replies on the Replies page; Reddit matches on the Reddit page. CSV export of the whole history. |
| Autopilot report | Each day the autopilot emails the owner who it wrote to. |
| Weekly memo | A weekly email lists what to keep, change or stop. |
| API key list | Settings > API keys shows each key, including the ones created by OAuth (named "MCP: <app>"), with last-used time and expiry. |

### What needs the owner's approval
| Mechanism | Detail |
| --- | --- |
| Tool annotations | Every tool declares readOnlyHint, destructiveHint and openWorldHint; clients that honour them can ask the owner before send_reply, set_autopilot and set_reddit_monitor. |
| Drafts only on the directory connectors | The ChatGPT and Claude connectors cannot send email, post to Reddit or change an autopilot; the server refuses those calls for their keys. |
| REST /api/outreach: explicit confirmation to send | No MCP tool takes this flag (set_autopilot and send_reply have no confirm parameter). A campaign sent over REST is refused unless the call carries confirm: true. An imported list is refused unless confirmOwnList is true. |
| Reddit is the owner's click | A reply or DM goes out only after the owner confirms it, from their own connected account. |

### What the owner can stop or revoke
| Mechanism | Detail |
| --- | --- |
| Revoke access | Revoke any API key, including an OAuth-minted one, under Settings > API keys. OAuth keys also expire after 90 days by default. |
| Pause the autopilot | Turn it off in the dashboard or with enabled: false. |
| Automatic stops (autopilot and campaign sends; not send_reply) | Plan and credit limits, a 500-a-day account ceiling, a ramp on every sending domain, a pause when an account's last 14 days bounced above 5% or drew complaints above 0.3%, and no sending without a saved postal address. |
| Suppression | Anyone who unsubscribed, complained or bounced, on any GrowFast account, is never written to again; every email has a one-click unsubscribe link. |

A sent email cannot be recalled. Limits and pauses stop further sends; they do not unsend.
