instantly-ai-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@instantly-ai-mcpList my campaigns and their lead counts."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
instantly-ai-mcp
An MCP server for the Instantly.ai v2 REST API that encodes what the API
actually does instead of trusting what its docs say. Every quirk below was reproduced against
the live API, not copied from a changelog or a forum post, and stays checked: npm run verify-gotchas re-probes the live account on demand and flags any claim whose real-world
behaviour has drifted from what's documented here (see
Why this table is machine-checked - it's a manual check,
not part of CI).
The gotchas
This table is the reason the repo exists. Every server built against this API eventually rediscovers these the hard way — usually by staring at an error that reads like the wrong thing. Captured live on 2026-08-21; see Why this table is machine-checked for how it stays honest.
# | Claim | Verdict |
1 | Cloudflare rejects the | HOLDS |
2 |
| HOLDS |
3 |
| HOLDS |
4 |
| REFUTED |
5 | The unfiltered | HOLDS |
6 | The campaign timezone field is a restricted enum: only | UNVERIFIABLE by the read-only probe |
7 | Webhook | UNVERIFIABLE by the read-only probe |
8 | Reads are not internally consistent — | UNVERIFIABLE (intermittent by nature) |
Notes on the interesting rows:
#3 — the live probe sent
campaign_ids: [id]and got back 5 leads, all 5 belonging to other campaigns. The parameter isn't just ignored, it's silently a no-op filter; the singularcampaignparameter is what actually scopes the query.list_leadsverifies every returned lead's owncampaignfield for exactly this reason and warns instead of trusting the filter.#4 — this was recorded
HOLDSon 2026-08-17 and flipped toREFUTEDon 2026-08-21.?id=now correctly filters analytics to the single campaign. See below for why that flip is the whole point of this repo.#5 —
UNVERIFIABLEon 2026-08-17 (no draft campaign existed in the account to test against), then confirmedHOLDSby the live integration suite (INSTANTLY_LIVE_TEST=1), which creates a throwaway draft campaign and confirms the unfiltered/campaigns/analyticsomits it. TheHOLDSabove is verified that way, not byverify-gotchas's read-only probe: that probe returnsUNVERIFIABLEwhenever no draft campaign already exists in the account (it never creates one), so running it against a no-draft account is expected to say "could not re-check", not contradict this row.list_campaignsreads fromGET /campaignsfor this reason — that endpoint does include drafts.#6, #7, #8 are
UNVERIFIABLEby the read-only probe on principle, not by accident: #6 and #7 would require a live write (creating a campaign / webhook) that the probe script deliberately never performs against a real account, and #8 is an intermittent read-consistency issue that can't be forced on demand.UNVERIFIABLEis a real, honest outcome here — see below.
Why this table is machine-checked
A hand-maintained quirk list rots. Claim #4 above is the proof: it was recorded as HOLDS on
2026-08-17 and refuted four days later, on 2026-08-21, when Instantly apparently fixed the
?id= parameter server-side. Four days is not a long tail — it's how fast an undocumented API
can move under a written-down assumption.
npm run verify-gotchas re-runs every claim's probe against the live API and prints a five-column
table (#, Claim, Verdict, Observed, Last checked) — a superset of the three-column summary above,
carrying the live probe's raw evidence and the date it ran. That is not the same shape as the table
above; don't expect a byte-for-byte match.
Each claim also carries a documented expected verdict (HOLDS for #1–#3 and #5, REFUTED for
#4, UNVERIFIABLE for #6–#8) — the currently-documented state, i.e. what this README says today.
The script exits non-zero only when a probe's actual verdict has genuinely changed from that
expectation (e.g. a documented HOLDS comes back REFUTED), and prints exactly which claim
drifted and in which direction. Re-confirming an already-documented REFUTED claim (like #4) is
not drift and does not fail the run — only a new change does.
UNVERIFIABLE is a real outcome the script reports honestly, not a failure it papers over, and it
never counts as drift in either direction. Some claims genuinely can't be checked by a safe,
read-only, non-destructive probe (see #6–#8 above); the script says so rather than guessing or
skipping silently. #5 is the clearest case: its documented HOLDS comes from the live integration
suite, not this probe, so the probe coming back UNVERIFIABLE (no draft campaign exists right now)
is reported as "could not re-check" — not a failure.
INSTANTLY_API_KEY=your-key npm run verify-gotchasverify-gotchas is run manually, not wired into CI — check .github/workflows/ci.yml, it only
runs build, typecheck, and test. That's a deliberate choice, not an oversight: CI has no live
API key (the script self-skips cleanly without one, printing a message and exiting 0 — see the top
of scripts/verify-gotchas.ts — so it would be a silent no-op there anyway), and this script exists
to touch a real account's read endpoints, which a repo's CI has no business doing unattended. Run it
locally against your own account when you want a fresh read.
Install
{
"mcpServers": {
"instantly": {
"command": "npx",
"args": ["-y", "instantly-ai-mcp"],
"env": { "INSTANTLY_API_KEY": "your-v2-api-key" }
}
}
}Get a v2 API key from Instantly's dashboard under Settings → Integrations → API. Requires Node 20+.
The safety model
Tools are grouped into three tiers, gated by environment variables. A disabled tier is not registered with the MCP server at all — a model talking to this server literally cannot see or attempt a tool it isn't allowed to use, this isn't a runtime permission check that a clever prompt could talk its way around.
Tier | Enabled by | Tools | Behaviour |
Read | always on | 6 tools | Read-only. |
Write |
| 5 tools | Creates/updates data, but nothing irreversible. |
Dangerous |
| 4 tools | Sends real email, activates campaigns, deletes data. |
The dangerous tier requires both flags on purpose: turning on routine writes (uploading leads,
blocklisting an address) never silently also enables campaign activation, sending, or deletion.
Those four tools additionally carry MCP's destructiveHint: true annotation — a hint that a
compliant client may act on (for example by prompting the user for confirmation) even when the
tier is enabled. It is client-enforced behaviour, not a guarantee this server makes: a client that
ignores the hint will call the tool without any extra confirmation step.
Tools
Read (always registered)
list_campaigns— list every campaign including drafts, with numeric status decoded.list_accounts— list connected sending mailboxes with warmup score, status, and daily limit.campaign_state— cross-check one campaign's state across three independent endpoints and report where they disagree, rather than picking a winner. The lead-list reading is page-scoped (one page, limit 100); a full page is reported plainly as page-limited, never as an Instantly disagreement.list_leads— list a campaign's leads, filtered by the singularcampaignparameter, with a warning if any returned lead's own campaign field disagrees. Reads one page (default limit 100);pageLimitedin the result tells you when more leads may exist beyond it.find_lead— find one lead by email via thesearchparameter; the correct second opinion whenlist_leadslooks wrong.searchis fuzzy, so the row is returned only when its own address matches the one asked for - a near-match is reported asnull, never as the lead.list_replies— list received replies with quoted-thread/signature stripped and interest status decoded.
Write (INSTANTLY_MCP_WRITE=1)
add_leads— upload leads to a campaign, verified by diff (not by count) across two independent read paths. On a campaign with more than 100 leads, the verification read is page-limited too - the result'spageLimitedandnotefields say so.blocklist_address— blocklist one full email address; structurally refuses bare domains.update_lead— patch a lead's fields.create_campaign— create a campaign as a draft (never sends); validates the timezone enum before any network call.create_webhook— create a webhook subscription; validates the event-type enum before any network call.
Dangerous (INSTANTLY_MCP_WRITE=1 and INSTANTLY_MCP_ALLOW_DANGEROUS=1)
set_campaign_status— activate or pause a campaign; activating starts sending real email immediately.send_reply— send a real, unrecallable reply to a lead. Plain text is HTML-escaped and line-broken for thehtmlbody rather than pasted in raw; passhtmlyourself to override.delete_lead— permanently delete a lead.delete_campaign— permanently delete a campaign and its history.
Known limitations
list_replies strips the quoted original thread and signature from each reply
(src/reply-text.ts). It is deliberately conservative: on ambiguous input it leaves the quote in
rather than risk deleting real text. Every remaining edge below therefore fails in the SAFE
direction - a quoted thread survives into the returned text, which is noise, rather than a
sentence being deleted, which is lost data:
An attribution naming only a weekday, e.g.
On Tuesday ... wrote:, carries none of the date/time signal the stripper requires, so it is not stripped.An attribution naming a lowercase sender with no address, e.g.
... at 8:22 AM, john wrote:, fails the sender-shape check (a real sender reads as an address, a capitalised name, or a pronoun) and is not stripped.A body that is entirely a signature (
--on the first non-blank line, with nothing before it) is returned whole, delimiter included, rather than emptied.
Two over-strips found during the build did delete real prospect text: a body beginning with
-- was emptied completely, and prose shaped like On May 5 reasons you wrote: ... was
misread as a quoted-thread marker and cut. Both were fixed before the first release and are
covered by the offline suite (test/reply-text.test.ts, "Fix round 4").
There is still no tool that returns a reply's raw, unstripped body.text. If a reply from
list_replies reads suspiciously short, check it in the Instantly dashboard before concluding the
prospect said less than they did.
Prior art
An existing package, instantly-mcp by
bcharleson, covers similar ground and was last published 2025-06-17. As of 2026-08-21, its npm
latest tag points at 1.0.5 while its next tag carries 3.0.5-1 — so a plain npx instantly-mcp installs a much older build than the package's own newest published code (dist tags
can change after this was written; re-check npm view instantly-mcp dist-tags for the current
state). This is stated factually, not as a knock: instantly-ai-mcp is an independent,
unaffiliated project with a different focus (the gotchas table and its self-verification) rather
than a fork or a replacement.
Testing
The fixture suite (npm test) runs entirely offline against mocked clients and needs no API key.
A separate live integration suite, gated behind INSTANTLY_LIVE_TEST=1 (and a real
INSTANTLY_API_KEY), exercises the real API — but it only ever creates, reads, and deletes its
own throwaway draft campaign (named zz-instantly-ai-mcp-throwaway-<timestamp>), never an
existing campaign or lead, and never activates or sends anything. It self-skips whenever the flag
or key is absent, which is always true in CI.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.
60+ Meta Ads tools for AI agents: audits, campaign management, audiences and CAPI tracking.
233 tools for Google, Microsoft, TikTok, LinkedIn Ads in Claude or ChatGPT. Writes need approval.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vojtaupan/instantly-ai-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server