Build a research-only outreach agent on Norbelys MCP
Build an agent on Norbelys MCP that researches people, builds segments, and drafts sequences — and is structurally unable to call a send-related tool.
By Gabriel Lara, Developer Relations, Norbelys
Founder-reviewed ·How we research and correct articles
The usual advice for a first agent integration is “start small.” On Norbelys MCP, that advice has a literal, buildable shape: connect an agent that can research your audience, build segments, and draft a sequence — and cannot, under any prompt or any mistake, put a message in front of a real person. Everything upstream of sending is genuinely useful on its own, and it’s the right place to build trust before an agent gets anywhere near your sending domain.
This is that build. Not a philosophy of guardrails — that’s a separate post — but the concrete tool list, config, and workflow for one narrow, safe agent, using the same MCP connection you’d set up for anything else. Nothing here requires a different server, a different key type, or a cut-down version of the API — it’s the full 83-tool catalog, with five specific doors locked before the agent ever sees them.
Why “just don’t ask it to send” isn’t enough
The obvious approach — connect the full MCP server and instruct the agent never to send anything — relies entirely on the model following an instruction it could ignore, misread, or get talked out of by a cleverly worded prompt buried in a piece of research it read. That’s not a guardrail, it’s a suggestion. A research-only agent needs the send-shaped tools to be genuinely unreachable, not merely discouraged.
The good news is that Norbelys’ MCP catalog makes this a short, precise list, once you know where to look.
The short list of tools that actually touch a real inbox
Only three tools put mail in front of a human or start a sequence sending on its own:
messages_create— the one send door. Even atest: truecall sends a real email to a real inbox.programs_launchandprograms_resume— either one starts a campaign sending against its enrolled audience.
These three carry the destructiveHint annotation for exactly this reason —
they’re the tools a well-behaved MCP client should pause on and ask you to
confirm before calling.
So the real deny-list for a research-only agent is five tools:
messages_create, programs_launch, programs_resume, senders_create,
senders_update. Everything else in the catalog — every read, plus creating
and editing people, groups, segments, custom fields, and even drafting a full
program with its cadence and A/B variants — never reaches a real inbox on its
own.
Building it, step by step
A research-only agent, from zero
Mint a dedicated key
Create an API key scoped to this agent specifically — not one you use for anything else. If the agent's behavior ever surprises you, revoking this one key kills it without touching any other integration. The key itself is still org-scoped, not tool-scoped, which is exactly why the next steps matter — see the key-hygiene post for the full reasoning.
Connect it like any other client
claude mcp add norbelys --transport http https://mcp.norbelys.com/mcp --header "Authorization: Bearer ak_<the-dedicated-key>" — the connect step doesn't change; the restriction happens next.
Deny the five tools explicitly
In .claude/settings.json for the project this agent runs in, add a permissions.deny rule for each of the five tool names, addressed as mcp__norbelys__<tool>. This is enforced by the client before the tool is ever invoked — not a prompt the model can talk itself past.
State the boundary in the project instructions too
Add a short, explicit note to the project's CLAUDE.md (or equivalent): this agent researches and drafts only; it never sends, launches, resumes, or edits a mailbox. This won't stop a determined misuse on its own, but it means the agent's own reasoning is aligned with the technical restriction, not fighting it.
Confirm the restriction actually holds
Ask the agent to attempt programs_launch on any program. A correctly configured client refuses before the call reaches Norbelys at all — you should see a permission denial, not a message from the API.
The .claude/settings.json block from step 3 looks like this:
{
"permissions": {
"deny": [
"mcp__norbelys__messages_create",
"mcp__norbelys__programs_launch",
"mcp__norbelys__programs_resume",
"mcp__norbelys__senders_create",
"mcp__norbelys__senders_update"
]
}
}
If your client doesn’t support a per-tool deny list the way Claude Code does,
the fallback is a client that at least honors destructiveHint with a
confirmation prompt for messages_create / programs_launch /
programs_resume — and manual discipline (or a wrapper you write yourself)
for the two senders calls the hint misses.
What the agent can actually do, unattended
With that boundary in place, the useful part of the workflow runs freely:
- Research the audience.
people_list/people_findwith segment and group filters,people_audienceSummaryfor a shape of who’s in the CRM before drilling in. - Check deliverability without risk.
verify_emailis a synchronous DNS/mailbox check against the target’s mail server — it never puts a message in anyone’s inbox, so it’s safe for an agent to run on every address it’s considering. - Build the audience.
segments_createfor a live filter, orgroups_createplusgroups_members_addfor a hand-picked list — both are ordinary writes to your own data, not anything reaching a recipient.people_create/people_bulkCreateif the research turns up new leads worth adding. - Draft the whole sequence.
programs_createandprograms_updatetake the complete cadence — steps, A/B variants, copy — inline. A program can be fully written, reviewed, and refined without a single sender attached or a single message queued. - Read what’s already gone out, for context.
messages_list/messages_findlet the agent study what past campaigns actually said, which is often better research material than a blank page.
Why this pattern beats “just be careful”
It’s worth being explicit about why a tool-level deny list is worth the extra five minutes of setup instead of just telling the agent to behave. A model following instructions is doing exactly that — following instructions, in whichever direction the loudest or most recent text in its context points it. Research material is exactly the kind of text an agent reads a lot of, and some of it will, eventually, contain something that looks like an instruction (“to unsubscribe, click here and confirm your email was sent” is the kind of boilerplate a scraped page can contain without anyone intending it as an attack). A deny list enforced by the client doesn’t care what the agent read or how it was phrased — the tool call never reaches the transport layer, which means it never reaches Norbelys either. That’s a materially different guarantee than a well-worded system prompt, and it’s the reason the guardrails post treats the approval gate as infrastructure rather than instruction in the first place.
Handing it back
The natural end state of a session is a proposal, not a launch: a segment
definition, a drafted program with its steps and variants, and the research
that justified the targeting — all sitting there, created, readable, and
completely inert until a human attaches senders and calls programs_launch
themselves. That handoff is deliberate. The agent did real work; the decision
to reach a stranger’s inbox stays a decision, made by you, every time.
Once you’ve run this pattern for a while and trust the agent’s research and copy, expanding its reach is just editing the deny list — nothing about the underlying connection changes. Norbelys doesn’t have a half-featured “safe mode” of the API for agents to grow into; it’s the same 83 tools the whole time, just fewer of them within reach until you decide otherwise.