cheapinboxes-mcp
by cosankov
README.md
# cheapinboxes-mcp
MCP server for the [CheapInboxes API](https://api.cheapinboxes.com/docs/) plus [Porkbun](https://porkbun.com) domain buying — run the whole cold-email infrastructure pipeline from any MCP client (Claude Code, Cursor, Claude Desktop, …) instead of clicking through dashboards:
**buy domains on Porkbun → import them into CheapInboxes → provision Google/Microsoft mailboxes → grab credentials / sync to Instantly, Smartlead, EmailBison, PlusVibe.**
32 tools: 8 for Porkbun, 21 for CheapInboxes, two raw escape hatches that reach every endpoint of both APIs, and a `runbook` tool that teaches the model the end-to-end flow.
## Setup
Requires Node 18+ (uses global `fetch`).
```bash
git clone https://github.com/cosankov/cheapinboxes-mcp.git
cd cheapinboxes-mcp
npm install
```
### Keys
| Variable | Where to get it | Needed for |
|---|---|---|
| `CHEAPINBOXES_API_KEY` | CheapInboxes dashboard → Integrations → API | all `ci_*` tools |
| `PORKBUN_API_KEY` + `PORKBUN_SECRET_KEY` | porkbun.com → Account → API Access (enable API access per domain too) | all `porkbun_*` tools |
The two sides are independent — with only a CheapInboxes key the `porkbun_*` tools error cleanly and everything else works, and vice versa.
Keys are read from `process.env` first, then from the first `.env` file found: `$CHEAPINBOXES_MCP_ENV` → `.env` next to `server.mjs`. Easiest: copy your keys into a `.env` in the repo root (gitignored):
```
CHEAPINBOXES_API_KEY=ci_live_...
PORKBUN_API_KEY=pk1_...
PORKBUN_SECRET_KEY=sk1_...
```
### Register with your MCP client
Claude Code / Cursor (`.mcp.json`):
```json
{
"mcpServers": {
"cheapinboxes": {
"command": "node",
"args": ["/absolute/path/to/cheapinboxes-mcp/server.mjs"]
}
}
}
```
(Or pass the keys via the `"env"` block instead of a `.env` file.)
### Verify
```bash
npm run smoke
```
Boots the server over stdio, lists all tools, live-pings Porkbun, and checks the CheapInboxes key — each side reports `[OK]` or a clean error telling you which key is missing.
## The flow
Ask your MCP client to run the `runbook` tool, or follow it yourself:
1. `porkbun_check_domain` per candidate — availability + live price. **Rate limit: 1 check / 10 s.**
2. `porkbun_register_domain` — `dry_run` defaults to **true** (preview, no charge); pass `dry_run: false` to buy. `cost_cents` must exactly match the checked price (Porkbun's own guard). Live runs auto-send an `Idempotency-Key`, so retries can't double-charge.
3. `ci_stage_imports` with the purchased domains (`source_provider: "porkbun"`).
4. `ci_quote` — cart of `{domain, tld, staged_import_id, mailboxes: {provider, count}}`; imported domains are $0.
5. `ci_checkout` — same cart with mailbox personas `{first_name, last_name, email_prefix}`; optional `integration_id` auto-connects mailboxes to a sending platform. **Charges the card on file.**
6. Poll `ci_list_domains` with the returned `order_id` until nameservers appear (or `ci_domain_nameservers` per domain).
7. `porkbun_set_nameservers` — point each domain at the CheapInboxes nameservers.
8. Poll `ci_get_domain` until `status: "active"` (`include_runs: true` adds provisioning-step history for debugging).
9. `ci_mailbox_credentials` for logins (password, app password, IMAP/SMTP) or `ci_sync_integration` to push mailboxes to your sequencer.
## Tool map
| Area | Tools |
|---|---|
| Guide | `runbook` |
| Porkbun | `porkbun_ping`, `porkbun_pricing`, `porkbun_check_domain`, `porkbun_register_domain` ⚠💰, `porkbun_list_domains`, `porkbun_get_nameservers`, `porkbun_set_nameservers`, `porkbun_dns` |
| CheapInboxes discovery | `ci_org`, `ci_tld_pricing`, `ci_mailbox_pricing`, `ci_search_domains` |
| Import → order | `ci_stage_imports`, `ci_list_staged_imports`, `ci_remove_staged_import`, `ci_quote`, `ci_checkout` ⚠💰, `ci_get_order` |
| Domains | `ci_list_domains`, `ci_get_domain`, `ci_domain_nameservers` |
| Mailboxes | `ci_list_mailboxes`, `ci_get_mailbox`, `ci_mailbox_credentials` 🔐, `ci_create_mailboxes` ⚠💰, `ci_update_mailbox` |
| Platform sync | `ci_list_integrations`, `ci_sync_integration` |
| Billing | `ci_billing_summary` |
| Escape hatches | `ci_api` (any CheapInboxes endpoint), `porkbun_api` (any Porkbun endpoint) |
⚠💰 = spends real money. 🔐 = returns secrets.
The escape hatches cover everything not curated: CheapInboxes DNS records, DMARC, forwarding, webhooks, cancellations, invoices, TOTP codes, org members; Porkbun SSL bundles, glue records, email forwarding, contacts, marketplace.
## Safety rails
- `porkbun_register_domain` previews by default; a purchase requires an explicit `dry_run: false`, an exact `cost_cents` match, and gets an idempotency key.
- `ci_checkout` has no server-side dry run — **always run `ci_quote` first** (identical cart shape, so it's a copy-paste).
- Rate limits: CheapInboxes 120 req/min; Porkbun 1 availability check / 10 s, 1 registration attempt / 10 s, 50 registrations / day.
- Porkbun sandbox: use `pk1_sb_` / `sk1_sb_` keys (and `PORKBUN_BASE_URL` if needed) to rehearse purchases with fake credit.
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues