Salesbot MCP Server – Documentation
The Salesbot LinkedIn MCP server implements the Model Context Protocol (Streamable HTTP) and lets AI agents (Claude, ChatGPT, Cursor) operate your Salesbot account — search leads, fill campaigns, generate and approve messages.
1. Endpoint
POST https://app.salesbot.cz/api/mcp- Protocol: MCP
2024-11-05(Streamable HTTP, JSON-RPC 2.0) - Method:
POST - Content-Type:
application/json - Accept:
application/json, text/event-stream(required)
2. Authentication
Every request must include an x-mcp-api-key header with your MCP API key (format sb_mcp_…). Generate the key in the Salesbot app under Settings → API → MCP.
x-mcp-api-key: sb_mcp_<YOUR_API_KEY>3. Client configuration
Add the following JSON to your MCP client configuration (Claude Desktop, Cursor, ChatGPT Developer Mode, etc.):
{
"mcpServers": {
"linkedin-automation": {
"url": "https://app.salesbot.cz/api/mcp",
"headers": {
"x-mcp-api-key": "sb_mcp_<YOUR_API_KEY>",
"Accept": "application/json, text/event-stream"
}
}
}
}4. Initialize (raw HTTP)
curl -X POST https://app.salesbot.cz/api/mcp \
-H "x-mcp-api-key: sb_mcp_<YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "my-client", "version": "1.0.0" }
}
}'5. List tools (tools/list)
curl -X POST https://app.salesbot.cz/api/mcp \
-H "x-mcp-api-key: sb_mcp_<YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'6. Available tools
Search & Discovery
search_linkedin_people- Searches LinkedIn by role, company, location or keywords. With connectionsOnly it uses the local connection cache without consuming the search limit. Results are not saved automatically: verify relevance, require a LinkedIn URL and persist an approved profile with upsert_linkedin_contact.
sync_linkedin_connections- Syncs first-degree connections through Unipile relations into the local cache. Respects cooldowns and supports a continuation cursor.
search_google_xray- Google X-Ray search — queries public LinkedIn profiles through Google operators (site:linkedin.com/in). Useful when you don't want to burn LinkedIn limits. Saves found profiles to the 'Google X-Ray' contact list (with deduplication) and returns IDs ready for campaigns or CRM.
search_linkedin_navigator- Processes a prepared Sales Navigator or regular LinkedIn search URL and returns raw results. To persist a profile and receive a contact_id, follow with upsert_linkedin_contact.
search_job_postings- Searches LinkedIn job postings by keywords, location, seniority, employment type and other filters. Returns listings with company information — ideal for finding who is actively hiring for a target role.
search_web- General Google search across the web (not just LinkedIn). Useful for job boards, company research, news and other content. Results are not saved to contacts.
get_job_posting_details- Loads a job posting's details, including the recruiting team — the recruiter or hiring manager who posted the role. Also shows applicant and view counts.
Contacts & Profiles
get_contact_profile- Returns the complete contact profile from the database — name (with vocative), headline, company, role, location, language, campaign status, interaction history. Serves as AI context for writing personalized messages or deciding the next step.
upsert_linkedin_contact- Imports an exact, already-known LinkedIn profile URL. If the contact exists, returns its ID; otherwise creates it in the CRM Imports list. This is the idempotent integration path before add_contacts_to_campaign.
list_contacts- Lists your contacts with ID, name, company and current status (e.g. invite_sent, connected, replied). Supports filtering by lead list or campaign. The AI picks IDs from this list for other tools.
list_lead_lists- Lists your contact groups with list ID, name, description and contact count. Use the list ID with list_contacts or add_contacts_to_list.
create_lead_list- Creates a named contact list and returns list_id. Repeating the same name returns the existing list instead of creating a duplicate.
add_contacts_to_list- Moves existing contacts by contact_id into the selected list_id. A contact belongs to one list; this does not create a copy.
enrich_contacts- Enriches existing contacts with complete LinkedIn profiles through the connected account — headline, location, current company and role, work history, education and skills. Ideal after Google X-Ray search; max 8 contacts per call.
Campaigns & Outreach
list_campaigns- Lists your campaigns with ID, name, status (draft/running/paused) and lead counts. The AI draws campaign_id from here when adding leads, generating messages or approving drafts.
list_campaign_queue- Returns campaign contact state including campaign_contact_id, message generation and approval status, scheduled action and the recommended next MCP tool.
add_contacts_to_campaign- Adds contacts by contact_id to a campaign and applies blacklist and deduplication, but does not send or schedule anything by itself. The response returns the next step, usually prepare_campaign_messages or start_campaign.
send_linkedin_message- Sends a one-off LinkedIn message to a specific contact outside a campaign. A configured delay is applied before sending; the action counts toward the daily message limit and is saved to the interaction history.
send_connection_request- Sends a LinkedIn connection invitation. The message is always empty (no text) — this is the set policy to prevent account blocking, regardless of account type (free or premium). The action counts toward the daily invitation limit.
AI drafts & Approvals
generate_campaign_message- Generates an AI message draft (Gemini) for a specific contact and campaign step based on the template and lead profile. The message is NOT sent — it is saved as a draft with 'pending_approval' status and waits for approval (e.g. via Claude/GPT or manually).
prepare_campaign_messages- Queues up to 10 missing campaign drafts for generation and immediately returns control to the agent. Check the state later with list_campaign_queue or list_pending_approvals.
list_pending_approvals- Returns a list of all AI drafts waiting for approval — for each draft returns the contact's name, headline, company and generated text. Serves as input for bulk review by an AI assistant (Claude/GPT), which can go through the drafts and decide to approve/reject.
approve_message- Approves a draft and hands it to the executor for sending within a campaign (respecting daily limits and allowed hours). Text can optionally be edited before approval. Parameter skip_gpt_check=false additionally runs a second check via gpt-5-nano — if GPT rejects the message, the draft is automatically returned to Gemini for rework based on GPT feedback.
reject_message- Rejects a draft with text feedback (e.g. 'too formal, cut to 2 sentences'). Salesbot marks the draft as rejected and Gemini generates a new version based on your feedback, which again waits for approval.
Campaign management
create_campaign- Creates a NEW campaign (saved as 'draft', not started automatically). You provide a name, profile and ordered steps (connect/message/visit, delays, AI prompts). Returns campaign_id; leads are then added via add_contacts_to_campaign.
update_campaign_settings- Updates settings of an existing campaign: name, description, daily limit, sender_context, auto-approve or status (paused/running). Only changes provided fields.
start_campaign- Starts (activates) an existing campaign — schedules actions for its contacts and sets status 'running'. The campaign must have contacts and steps. Respects daily limits, allowed hours and configured delays.
stop_campaign- Stops a running campaign — sets status 'stopped' and cancels pending scheduled actions. For a temporary pause use update_campaign_settings with status='paused'.
Inbox & Replies
list_inbox_chats- Lists recent LinkedIn conversations (inbox) in real time — returns chat ID, the other party, unread count and time of the last message.
get_chat_messages- Loads messages of a single LinkedIn conversation in real time (newest at the bottom). is_sender=true marks messages sent by you. Serves as context before writing a reply.
reply_to_chat- Sends a reply to an existing conversation only during your allowed hours. A configured delay is applied before sending, and the text is checked for prompt injection and unwanted links. Maximum 2 AI replies per thread; counts toward the daily message limit.
mark_chat_read- Marks a LinkedIn conversation as read (by chat_id) — so the thread doesn't reappear as unread after the AI processed it.
Posts, limits & web
publish_linkedin_post- Creates a LinkedIn post on behalf of a connected profile. By default the post is saved as a 'draft' on the LinkedIn Posts page where the user can review and publish it. With auto_publish=true the post is published immediately — but only when MCP human-in-the-loop approval is OFF; otherwise it stays as a draft and the user publishes it from the app. A configured delay is applied before the publish call. Image attachments must be added in the in-app post editor.
get_daily_limits- Checks hourly, daily and monthly usage, remaining quota, account type, ramp-up status, allowed hours and the recommended cooldown.
scrape_website- Loads readable text from a public web page so the AI can use it as context when writing/editing messages (e.g. a prospect's website). Returns plain text (no HTML, truncated) and contact emails found (emails_found, incl. mailto links). Weekly limit on the number of sites; internal/private addresses are rejected.
LinkedIn account
get_linkedin_status- Checks whether your LinkedIn account is connected and active, and if not, how to fix it. The AI calls this first when another tool reports the account isn't connected.
connect_linkedin- Generates a secure link with a custom domain that you open to connect (or reconnect) your LinkedIn account — no need to leave the chat.
CRM
set_deal_stage- Moves a lead through your CRM pipeline (stages are configurable — default: Prospect → Contacted → Demo → Won → Lost) and records the change in history. The AI uses it when you confirm a real-world event ('they booked a demo').
log_crm_note- Saves a structured summary of a conversation to the lead's CRM record — a concise recap, the prospect's pain points and overall sentiment — so future follow-ups stay personalized.
save_lead_message- Saves generated outreach copy for a lead (email, email follow-up, LinkedIn message or LI follow-up) as persistent CRM context. Does not send it.
list_lead_messages- Lists messages saved for a lead (email/LinkedIn drafts and follow-ups), newest first, so the AI can retrieve copy before sending it through the right channel.
create_task- Creates a follow-up task, optionally linked to a lead and with a due date (Pro plan). Turns 'remind me to send pricing on Thursday' into a tracked task.
get_lead_context- Returns the full CRM context for a lead before writing a pitch: profile, current pipeline stage, recent conversation summaries, open tasks, recent LinkedIn interactions and stage history.
export_crm- Exports your entire CRM (leads with pipeline stage and key fields) as CSV so you can back it up or open it in Excel.
update_contact- Updates a lead's contact details – email, phone, location, company, role or headline. Use it to enrich a lead (e.g. saving a found email). Only fields you provide are changed.
list_tasks- Lists your CRM tasks – filter by status (open/done/cancelled) and/or a specific lead. Returns id, name, due date, status and the linked lead's name so the AI can see open follow-ups.
complete_task- Marks a CRM task as done (or reopens/cancels it) by task_id. Use after finishing a follow-up.
list_crm_stages- Lists CRM pipeline stages (key, label, colour) and how many leads are in each. Stages are configurable.
add_crm_stage- Adds a new pipeline stage (e.g. 'Negotiation') with an optional colour. Appended to the end of the pipeline.
rename_crm_stage- Renames a stage label and/or changes its colour by key. The stage key and leads in it remain unchanged.
delete_crm_stage- Deletes a pipeline stage; its leads are moved to another stage (reassign_to or the first remaining one).
list_crm_fields- Lists custom fields defined on CRM leads (key, label, type).
add_crm_field- Adds a custom field to CRM leads (e.g. 'Budget' of type number). Types: text, number, date, url.
delete_crm_field- Removes a custom field definition by key.
set_lead_fields- Sets values of custom fields on a lead (by contact_id) – e.g. budget, renewal date. Only defined keys are accepted.
7. Limits & safety
- The MCP server respects daily limits, allowed hours, domain/company blacklists and stop-on-reply rules configured in your account.
- Connection requests are always sent without a message (anti-block policy).
- Before sending messages, a configured delay is applied as part of the operational cadence.
- Human-in-the-loop approval blocks messages and connection requests until you approve them in the app.
- A conservative MCP starting point is 10 actions per hour and 5 messages per hour per account; keep the first pilot below 100 total actions and roughly 30–50 messages per day.
- When LINKEDIN_SEARCH_PROTECTED, quota_protection or retry_after_seconds appears, do not retry immediately or bypass it through another LinkedIn search tool.
8. Recommended AI agent prompt
Add this prompt to the agent system instructions, a Cursor Skill or AGENTS.md. Adapt it to your approval workflow, but do not remove the safety steps.
You are the Salesbot Campaign Operator. Protect the LinkedIn account. Before discovery or outbound, call get_linkedin_status and get_daily_limits. If a tool returns LINKEDIN_SEARCH_PROTECTED, quota_protection or retry_after_seconds, never retry immediately and never bypass the cooldown with another LinkedIn search. Use search_google_xray, cached connections, or stop until the stated time.
Workflow: list_campaigns and list_lead_lists → verify contacts and use upsert_linkedin_contact when needed → add_contacts_to_campaign → list_campaign_queue → prepare_campaign_messages → list_pending_approvals → review every draft and approve_message or reject_message with feedback → start_campaign only after contacts and messages are confirmed. Never disable human-in-the-loop for speed. If state is unclear, inspect it instead of repeating a write action. Reuse the exact profile_id, list_id, campaign_id, contact_id, campaign_contact_id and step_id returned by Salesbot.9. Further reading
- /llms.txt – overview for LLM crawlers
- /mcp-server – MCP server landing page
- modelcontextprotocol.io – official MCP specification
- app.salesbot.cz – sign in and generate API key