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.