Generated from the running server

The tools

This page is built by reading the live endpoint, not by hand, so it cannot describe a tool that no longer exists. 25 tools today.

claude mcp add --transport http headlessbrain https://mcp.headlessbrain.ai/mcp \
  --header "Authorization: Bearer YOUR_KEY"

Get a key at app.headlessbrain.ai. Connect your own provider keys there; nothing is stored in the clear and nothing is returned to a caller.

Before you write to anyone

Ask first. These answer whether a person may be contacted at all, and why not.

contact_checkMay we write to this person, and if not, why not. Ask BEFORE composing anything.
Asks the MASTER RECORD first (crm.person_status, 4,196 people), then the local gates: the never-contact list, clients, the DNC, whether they already declined, whether WE promised to stop writing to them, whether the mailbox exists, and whether they were already emailed and never answered. Pass a ful
email_verifyDoes this mailbox exist, before anyone sends to it.
Asks the receiving mail server about each address over SMTP and hangs up without sending. Returns VALID / INVALID / CATCH_ALL / UNKNOWN / NO_MX / BAD_SYNTAX plus a `sendable` flag. Read the flag, not the label. INVALID and NO_MX are proven dead. CATCH_ALL means the domain accepts every address so no

Campaigns

Plan gates everyone and creates nothing. Create builds a DRAFT. Starting is always separate.

campaign_planPlan a campaign: who may actually be contacted, who may not, and on whose authority.
Give it a name and a list of people (dicts with any of email, name, linkedin_url, conversation_id). Every person goes through the full gate, master record first. Returns the survivors, every refusal with the rule and the evidence behind it, and the practical problems with the plan (missing addresses
campaign_createCreate a LinkedIn campaign in HeyReach as a DRAFT. It is never started here.
Plans first (every person through the full gate, master record included) and refuses to create if the plan still has problems. Builds the lead list, creates the campaign with all three exclusion rules on, and attaches a ONE-message sequence with no view or like padding. By default it excludes HeyRea
li_campaign_controlStart, pause or resume a campaign. Guarded.
A live campaign will not move unless confirm_name exactly matches its name. ws-106001 is the Inside Sales lane's workspace with live campaigns in it, and a bare pause in a shared MCP is one mistyped id away from stopping the fleet.
li_add_leadsAdd leads to a campaign. Each lead needs at least profileUrl; firstName/lastName/companyName
optional. Refuses any lead without a profile URL. 64% of one campaign's failures on 2026-08-30 were unreachable or missing profile URLs, and load time is where that is cheap to fix.
li_listsLead lists in a workspace, with how many leads each holds.
li_sequenceThe message sequence a campaign actually sends. Read it before judging a campaign's numbers:
a sequence that opens with three view/like actions per lead spends its daily budget looking rather than talking.

The LinkedIn machine

What is actually sending, what is failing, and why.

li_healthOne answer to 'is the LinkedIn machine actually working'.
Counts seats that can send, seats that cannot, campaigns with no seat attached, and campaigns that are running but have nobody left in progress. Written because the fleet has twice looked healthy in a dashboard while sending nothing.
li_why_failingExplain WHY a campaign's invites are failing, grouped by what to do about it.
A failure count on its own reads as a broken seat. Usually it is not: dead profile URLs and people you are already connected to are list problems, and warming the seat will not touch them. Returns seat_implicated=true only when the errors are genuinely not explained by list quality.
li_seatsConnected LinkedIn sender seats in a workspace, with whether each can actually send.
auth_valid is the field that decides it. A seat can be 'active' and still be unable to send.
li_campaignsCampaigns in a workspace with their real progress counts (total, finished, in progress,
failed) and how many seats are attached. A campaign with zero seats sends nothing.
li_workspacesList the HeyReach workspaces this key can reach.

The inbox

Who is waiting on you. Reading a thread is required before replying to it.

li_needs_replyWho is waiting on a reply: conversations where THEY spoke last, newest first.
The question a LinkedIn inbox never answers directly. Returns their last message so the triage can happen without opening each thread.
li_threadThe full conversation, oldest message first. Read it before replying.
li_replySend a reply into an existing LinkedIn conversation. Gated.
Refuses: a client (they are never handled as a prospect), the never-contact book, an empty message, and any call that has not read the thread first. Pass confirm_read_thread=True only after actually calling li_thread on this conversation.
mail_needs_replyMessages from other people in the last N days that you have not answered.
Uses the mailbox's own \Answered flag rather than guessing who spoke last, because a thread can be answered from a phone and never touched again. Headers only.
mail_searchSearch the inbox by text. Returns senders, subjects and dates, never message bodies.
Bodies are deliberately absent: a tool that pours a mailbox into a model's context is a data-loss incident waiting for a reason to happen.

Research · local only

These read a private index that lives on the operator's own machine, so they work over a local connection and NOT over the hosted endpoint. Listing them without saying so would hand a customer six tools that cannot work for them.

research_findFind any file across everything Roki owns: 537,377 indexed artifacts, both local roots and
the Google Drives, cross-referenced to clients. kind narrows to image / document / data / deck / code and similar; client narrows to a client slug. This is the tool for "where is that contract" and "what do we have on X".
research_clientThe client roster, or one client. With no slug, lists every client the index knows.
research_promisesCommitments made on recorded calls: what we said we would do, who said it, and whether it
is still open. Every row carries the quote and the meeting it came from, so a promise can always be traced to the moment it was made.
research_peopleFind people we have actually met, by topic of the meetings they were in.
Searches 3,095 recorded meetings rather than a contact list, so it answers 'who have we spoken to about outbound' rather than 'who is in the CRM'.
research_meetingsSearch recorded meetings by topic. Returns the call, its date and its URL.
research_saidSearch what was actually SAID across the recorded calls, not just meeting titles.
This is the tool that answers 'did anyone ever tell us X'. Quotes come back with the meeting they belong to so a claim can always be traced to its source.

Everything else

gtm_morningThe whole morning in one call: is the machine working, is anything burning, who is waiting,