Tools
Actions the agent can invoke (tools/call) — search contacts, send messages, create deals, etc.
CRM Solid ships a built-in Model Context Protocol (MCP) server. MCP is an open standard that lets AI agents — Claude Desktop, Cursor, Cline, and any other MCP-capable client — discover and call your CRM’s capabilities through a single, authenticated endpoint.
Once connected, an agent can search your contacts, send Telegram and X (Twitter) messages, manage deals and tasks, read finance summaries, run sequences, and more — all scoped to exactly the permissions on your API key.
The server speaks JSON-RPC 2.0 over HTTP and exposes three kinds of capabilities:
Tools
Actions the agent can invoke (tools/call) — search contacts, send messages, create deals, etc.
Resources
Read-only context the agent can pull in (resources/read) — current user, accounts, pipeline, KPIs.
Prompts
Pre-built prompt templates (prompts/get) — daily briefing, contact summary, pipeline review.
| Endpoint | https://api.crmsolid.com/mcp |
| Methods | POST (JSON-RPC), GET (server-sent stream) |
| Protocol | JSON-RPC 2.0 / MCP |
| Auth | Authorization: Bearer csk_live_… |
Authentication uses the same API key as the REST API — a csk_live_… key. Every request must include it as a Bearer token:
Authorization: Bearer csk_live_…Content-Type: application/jsonThe key’s scopes determine which tools, resources, and prompts the agent can use. A request for a capability whose requiredScope your key lacks is rejected. See Authentication to create a key and pick the right scopes.
Create an API key in the panel with the scopes you want the agent to have. Copy the csk_live_… value — it is shown only once. (See Authentication.)
Add the MCP server to your client’s config, pasting the key as the Authorization header. Use the tab for your client below.
Restart the client so it reloads its configuration and performs the MCP initialize handshake.
Verify the tools appear. Your client should list the CRM Solid tools (e.g. crm_search_contacts). If nothing shows up, double-check the endpoint URL and that the Bearer prefix is present in the header.
Add the server to claude_desktop_config.json:
{ "mcpServers": { "crmsolid": { "url": "https://api.crmsolid.com/mcp", "headers": { "Authorization": "Bearer csk_live_…" } } }}Config file locations:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
Add the server to ~/.cursor/mcp.json (or the project-level .cursor/mcp.json):
{ "mcpServers": { "crmsolid": { "url": "https://api.crmsolid.com/mcp", "headers": { "Authorization": "Bearer csk_live_…" } } }}Any MCP client that supports the streamable-HTTP transport uses the same shape — point it at the endpoint and supply the Bearer header:
{ "mcpServers": { "crmsolid": { "url": "https://api.crmsolid.com/mcp", "headers": { "Authorization": "Bearer csk_live_…" } } }}The server implements the standard MCP method set. Send these as JSON-RPC 2.0 envelopes to POST /mcp.
| Method | Purpose |
|---|---|
initialize | Handshake — first call required |
ping | Keep-alive / health check |
tools/list | Enumerate registered tools |
tools/call | Invoke a named tool |
resources/list | Enumerate available resources |
resources/read | Fetch a resource by URI |
prompts/list | Enumerate registered prompts |
prompts/get | Render a prompt with arguments |
Notifications:
| Notification | Behavior |
|---|---|
notifications/initialized | Sent by server after initialize completes |
notifications/cancelled | Returns HTTP 202; indicates async op cancellation |
Most clients handle these for you, but here is the raw wire format.
tools/list — discover available tools:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }tools/call — invoke a tool:
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "crm_search_contacts", "arguments": { "query": "acme" } }}resources/read — read a resource:
{ "jsonrpc": "2.0", "id": 3, "method": "resources/read", "params": { "uri": "crm://me" } }A full curl call:
curl -X POST https://api.crmsolid.com/mcp \ -H "Authorization: Bearer csk_live_…" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"crm_search_contacts","arguments":{"query":"acme"}}}'48 tools, grouped by the scope each one requires. A tool is only callable if your API key holds its requiredScope.
| Tool | Description | Scope |
|---|---|---|
crm_search_contacts | Search the user’s CRM contacts by name, username, or phone. Returns up to 25 results sorted by most-recently-contacted. | contacts:read |
crm_get_contact | Fetch a single contact by id, including the last 10 messages exchanged. | contacts:read |
crm_search_twitter_messages | Search the user’s stored Twitter (X) DMs by free-text. Use when the user asks “what did I say to X about Y”. Returns up to 25 most-recent matches. | contacts:read |
crm_list_accounts | List all connected accounts (Telegram + Twitter/X) with id, type, name, status, and most-recent activity. Required before sending any message — gives the agent the right accountId. | contacts:read |
crm_list_recent_conversations | Recently active contacts with their last message preview, ordered by latest activity. Use to surface “who needs a reply?”. | contacts:read |
crm_get_conversation | Full message thread for one contact, paginated newest-first. Pass before (an Id) to fetch the page older than that message. Returns up to 50 messages per call. | contacts:read |
crm_list_tags | List the user’s contact-tag dictionary with how many contacts each tag is attached to. | contacts:read |
crm_get_contact_activity | Fetch a contact’s activity timeline (notes, stage changes, tags, score changes, assignments) newest-first. | contacts:read |
crm_add_contact_note | Append a free-text note to a contact’s Notes field (timestamped). Use to record key facts the agent learned during a conversation. | contacts:write |
crm_update_contact_stage | Move a contact to a different pipeline stage (lead → conversation → proposal → negotiation → won/lost). Use after a meaningful sales event. | contacts:write |
crm_tag_contact | Attach a tag to a contact. Provide tagId, or tagName (created if it doesn’t exist yet). Logs a “TagAdded” activity. Idempotent. | contacts:write |
crm_untag_contact | Detach a tag from a contact. Logs a “TagRemoved” activity. Idempotent. | contacts:write |
crm_set_lead_score | Manually set a contact’s lead score (0–100). Marks it as a manual (non-AI) override and logs a “ScoreChanged” activity. | contacts:write |
crm_assign_contact | Assign a contact to a team member (owner), or unassign by omitting assignedToUserId. Logs an “Assigned”/“Unassigned” activity. | contacts:write |
| Tool | Description | Scope |
|---|---|---|
crm_send_telegram_message | Queue a Telegram outbound message. Specify accountId (one of the user’s connected Telegram accounts) and either contactId or username. Message is sent asynchronously. | telegram:send |
crm_send_twitter_dm | Send a Twitter (X) DM to a contact. Use when the user wants to reach out on X. The contact must already exist with platform=‘twitter’ and an XUserId. Sends synchronously through the user’s connected X session. | twitter:send |
| Tool | Description | Scope |
|---|---|---|
crm_list_sequences | List the user’s outbound message sequences with status, target counts, and progress. Use to answer “what campaigns are running?”. | sequences:read |
crm_get_sequence_status | Get a deep status report for one sequence: name, status, target/processed/successful/failed counts, message steps, and recent job activity. | sequences:read |
crm_pause_sequence | Pause an active sequence so no more messages are queued. Existing in-flight jobs will still run. Idempotent: pausing a paused sequence is a no-op. | sequences:write |
crm_resume_sequence | Resume a paused sequence so the worker starts queueing messages again. | sequences:write |
| Tool | Description | Scope |
|---|---|---|
crm_list_deals | List sales deals (pipeline) ordered by stage then value, with open-task counts. Use to answer “what’s in my pipeline?”. | deals:read |
crm_get_deal | Fetch one deal with its linked tasks and resolved contact name. | deals:read |
crm_create_deal | Create a new pipeline deal in an active stage. Title is required. Cannot create a deal already won/lost (closing a deal is done from the panel because “won” books revenue). | deals:write |
crm_update_deal_stage | Move a deal between pipeline stages. Allowed: lead, qualified, proposal, negotiation, lost. Moving to “won” is intentionally NOT supported here (it books an income ledger entry — do that from the panel). | deals:write |
| Tool | Description | Scope |
|---|---|---|
crm_list_tasks | List CRM tasks (to-dos / reminders) sorted by due date then priority. Use for “what’s due?” or “what’s overdue?”. | tasks:read |
crm_create_task | Create a task / reminder. Title is required; optionally link it to a contact and/or deal and set a due date and priority. | tasks:write |
crm_complete_task | Set a task’s status. Defaults to marking it done (stamps completion time); pass status to re-open (open/inprogress). | tasks:write |
| Tool | Description | Scope |
|---|---|---|
crm_search_email_threads | Search the user’s email inbox threads by subject/preview, with status/contact/unread filters. Read-only — does NOT send mail. | email:read |
crm_get_email_thread | Fetch one email thread with its messages (plain text, oldest-first) plus any AI summary/lead score. Read-only. | email:read |
crm_set_email_thread_status | Set an email thread’s workflow status (open/pending/closed). Does NOT send mail. | email:write |
crm_assign_email_thread | Assign an email thread to a team member, or unassign it by omitting assignedToUserId. Does NOT send mail. | email:write |
| Tool | Description | Scope |
|---|---|---|
crm_finance_summary | Realized income/expense/net per currency plus outstanding (pending) totals and the top expense categories, over a window. Use for “how is the business doing financially?”. Read-only. | finance:read |
crm_list_transactions | List ledger entries (income/expense) newest-first, with optional filters. Read-only — does NOT create transactions. | finance:read |
crm_list_invoices | List invoices newest-first with an outstanding (sent/overdue) summary per currency. Read-only — does NOT create or pay invoices. | finance:read |
crm_revenue_sources_summary | List configured external revenue sources with their last-sync status, total ingested count and last event time. Secrets (keys/credentials) are never returned. Read-only. | finance:read |
| Tool | Description | Scope |
|---|---|---|
crm_list_pipelines | List the user’s pipeline boards with their ordered stage columns and per-stage contact counts. Use to understand how the CRM is organized before moving/reading contacts. Read-only. | pipelines:read |
crm_get_pipeline | Fetch one pipeline board by id with its ordered stages and per-stage contact counts. Read-only. | pipelines:read |
| Tool | Description | Scope |
|---|---|---|
crm_list_webhooks | List the user’s registered webhook endpoints (URL, subscribed event types, health). Signing secrets are NEVER returned — only a short preview. Read-only. | webhooks:read |
crm_list_webhook_deliveries | List recent delivery attempts for one webhook endpoint (status, attempts, last response code, last error) newest-first. Use to debug “why isn’t my webhook firing?”. Read-only. | webhooks:read |
crm_create_webhook | Register a new webhook endpoint. Provide an HTTPS url and optionally a list of event types to subscribe to (default: all). The signing secret is returned ONCE in the response — store it immediately, it cannot be retrieved later. | webhooks:write |
crm_delete_webhook | Permanently delete a webhook endpoint. This stops all future deliveries to it and cannot be undone. | webhooks:write |
| Tool | Description | Scope |
|---|---|---|
crm_list_agents | List the user’s AI agents with a config summary (status, channels, trigger/response mode, model) and a 24h run count. Read-only. | agents:read |
crm_run_agent | Test-run (dry-run) an AI agent against a sample inbound message and return the reply it WOULD send. This is a safe playground — the reply is NEVER delivered to any contact and nothing is mutated. Optionally seed prior turns via history. | agents:run |
| Tool | Description | Scope |
|---|---|---|
crm_list_jobs | List outbound Telegram send-jobs (from crm_send_telegram_message and sequences) newest-first, with status and error visibility. Use to monitor “did my messages go out?”. Read-only. | jobs:read |
crm_get_job | Fetch one outbound message-job by id including its full text, target, status and lastError. Use to diagnose a specific send failure. Read-only. | jobs:read |
| Tool | Description | Scope |
|---|---|---|
crm_dashboard_summary | High-level KPIs for the user’s account: total contacts, messages queued/sent today, connected accounts. Useful as a daily standup for AI agents. | analytics:read |
crm_messaging_stats | Sent/failed/queued message counts over a window (1, 7, or 30 days). Optionally scoped to a single account. Use for “how am I doing this week?” style questions. | analytics:read |
crm_top_contacts | Most-messaged contacts in the last 30 days, ranked by outbound message volume. Useful for “who are my warmest leads?”. | analytics:read |
17 read-only resources the agent can pull in for context via resources/read. All return application/json. Resources respect your key’s scopes at read time.
| URI | Name | Description |
|---|---|---|
crm://me | Current user | Identity, plan, and connected-account summary for the API key holder. |
crm://accounts | Connected accounts | All connected Telegram and Twitter (X) accounts with type, status, and last activity. Pre-loaded so the agent can pick the right accountId without calling crm_list_accounts first. |
crm://sequences | Active sequences | Outbound message sequences (campaigns) and their current status, daily limit, and target progress. |
crm://recent-conversations | Recent conversations | Last 20 active contacts with name, platform, last-message preview, and unread flag — gives the agent immediate context on who needs attention. |
crm://plan | Subscription plan | Current subscription plan, period, daily-message limits, and remaining seats. Use to answer billing/quota questions before queueing more sends. |
crm://kpis/7d | 7-day KPIs | Sent/failed/queued message counts for the last 7 days plus a per-day breakdown — useful for trend-spotting without calling crm_messaging_stats. |
crm://finance/summary | Finance summary (30d) | Realized income/expense/net per currency for the last 30 days — a quick read on financial health without calling crm_finance_summary. |
crm://deals/pipeline | Deals pipeline | Deal count and total value per pipeline stage — the shape of the sales funnel at a glance. |
crm://tasks/today | Tasks due today / overdue | Open tasks that are due today or already overdue, ordered by due date — surfaces what needs action now. |
crm://inbox | Open email threads | Up to 20 open email inbox threads with subject, preview and unread count — who is waiting on a reply. |
crm://pipelines | Pipelines & stages | All contact pipelines (boards) with their ordered stages and the live contact count sitting in each stage — the shape of every funnel at a glance. |
crm://jobs/recent | Recent outbound jobs | The last 20 outbound message-sending jobs with status, target, account, and a trimmed error summary for any failures — quick visibility into delivery without calling a tool. |
crm://finance/invoices | Outstanding invoices | Open invoices (sent or overdue) summarized per currency, plus the most-overdue ones — money still owed to the business. |
crm://tasks/overdue | Overdue tasks | Open tasks whose due date has already passed (strictly before now), ordered oldest-first — distinct from crm://tasks/today which also includes today. |
crm://agents | AI agents | The user’s AI auto-reply agents with status, channels, response mode and rate limits (no secrets/persona text) plus a 7-day run count — what is currently automating replies. |
crm://webhooks | Registered webhooks | Outbound webhook endpoints with their subscribed event types, active flag and recent delivery health. Signing secrets are NEVER included. |
crm://deals/open | Open deals | Open deals (not Won or Lost) ordered by value, with stage, win probability and expected close date — the live opportunity list ranked by size. |
12 pre-built prompt templates exposed via prompts/get. Each renders a ready-to-run prompt by pulling the relevant CRM data. Arguments marked with a * are required.
| Prompt | Title | Description | Arguments | Scope |
|---|---|---|---|---|
summarize-contact | Summarize a contact | Summarizes the relationship with a CRM contact and proposes a concrete next step. Pulls the latest 10 messages exchanged with the contact. | contactId* | contacts:read |
draft-followup-message | Draft a follow-up message | Drafts a Telegram follow-up message tailored to the contact’s stage and recent conversation. Optional tone selector. | contactId*, tone | contacts:read |
daily-briefing | Daily CRM briefing | Builds a “morning standup” digest from today’s queued/sent/failed jobs and the user’s contact pipeline. | — | analytics:read |
audit-account-health | Audit a connected account | Pulls the last 7 days of job stats for a connected Telegram/X account and asks for a risk assessment (rate-limit pressure, error spikes, etc.). | accountId* | analytics:read |
weekly-finance-report | Weekly finance report | Builds a weekly finance report from the last 7 days of realized (completed) income/expense, grouped per currency. | — | finance:read |
deal-next-step | Suggest a deal’s next step | Given a deal’s stage, value, probability and open tasks, recommends the single best next action to move it forward. | dealId* | deals:read |
summarize-email-thread | Summarize an email thread | Summarizes an email inbox thread and surfaces the customer’s open question plus one recommended next action. Does not draft or send a reply. | threadId* | email:read |
triage-inbox | Triage the inbox | Pulls the most recently active contacts (unread first) and asks the model to rank who to reply to first and why. | — | contacts:read |
pipeline-review | Review the deal pipeline | Pulls open deals grouped by stage with value and probability, then asks for a weighted forecast and the 3 deals most at risk. | — | deals:read |
task-prioritize | Prioritize today’s tasks | Pulls overdue tasks plus those due in the next 48 hours and asks for a single prioritized action list for today. | — | tasks:read |
outreach-plan | Plan next week’s outreach | Summarizes active sequences with their target progress and asks for next-week outreach focus and one improvement per under-performing sequence. | — | sequences:read |
lost-deal-postmortem | Lost-deal post-mortem | Given a lost deal’s data and its task history, asks for the likely root cause and a concrete re-engagement play. | dealId* | deals:read |
Prompt argument details:
draft-followup-message → tone (optional): Voice for the draft: 'friendly' (default), 'professional', or 'urgent'.requiredScope for it. Add the scope to the key (or create a new key) in Authentication.401 Unauthorized — the Authorization header is missing, malformed, or the key was revoked. Ensure the value is Bearer csk_live_… (note the space).isError: true — the call reached the tool but the operation failed (bad arguments, not-found id, etc.). The error payload inside result explains why.https://api.crmsolid.com/mcp and restart the client to re-run initialize.