Tools, resources and prompts: three different things
An MCP tool is a function an AI assistant calls to do something in your CRM: it takes arguments, performs an action, and returns a result. An MCP resource is a read-only feed addressed by a URI that the assistant loads into its context without choosing any arguments at all. An MCP prompt is a parameterized template the server hands the client, so a person can pick a named workflow from a menu instead of describing it from scratch every time. Those three sentences are the whole mental model, and almost every confusion about the Model Context Protocol dissolves once they are separated.
The practical difference is who decides. A tool call is the assistant deciding: it looked at your request, picked crm_search_contacts, invented a query string, and now owns the consequences of that choice. A resource read is the server deciding: crm://tasks/today means one specific thing and returns the same shape every time, so there is no argument for the model to get wrong. A prompt is you deciding: you clicked daily-briefing in your client and the server supplied the wording.
That distinction has real consequences for cost and reliability. Tools are expressive and therefore risky, because an assistant that misunderstands the question makes a wrong call rather than no call. Resources are narrow and therefore safe, and they are the cheapest way to give an assistant a great deal of accurate context in a single request. Prompts are how you stop re-typing the same three paragraphs every Monday morning.
Pinlyx publishes 142 tools, 21 resources and 15 prompts on one endpoint. Of the tools, 78 are annotated read-only and 64 are annotated as writes. Everything below is the complete catalogue, grouped so that the groups match the way you would actually hand out access. If you want the protocol-level picture of how the server itself works, that lives on the MCP server overview; if you want the setup steps for a specific client, those live on connect Claude to your CRM.
How to read this reference
Every tool in this reference carries four things: the exact name your assistant will call, one plain sentence on what it does, the single scope the call requires, and whether it reads or writes. Those four columns are the entire contract. There is no hidden fifth condition, no per-tool pricing tier and no separate permission model layered on top of scopes.
Names are exact and case-sensitive. Every tool is prefixed crm_, and the rest of the name reads as a verb plus a noun: crm_list_deals, crm_send_social_message, crm_set_lead_score. If a name in your client does not appear on this page, it is not part of this server. The server itself is always the final authority: a tools/list call returns the live catalogue with the input schema for each tool, which is what your client reads at connection time.
curl -sS https://api.pinlyx.com/mcp \
-H "Authorization: Bearer csk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Scopes are the second column that matters. Each tool declares exactly one required scope, written as an area and a verb joined by a colon: contacts:read, deals:write, telegram:send. The ordering is deliberate and worth memorizing, because writing it the other way round is the single most common mistake people make when configuring a key. There is no read:contacts; there is only contacts:read.
Scopes are attached to the API key, not to the assistant, not to the session and not to the individual call. You mint a key in the panel, tick the scopes that key is allowed to use, and hand the key to one client. Two assistants with different jobs should hold two different keys, because that is the only way their permissions can differ.
When a call needs a scope the key does not hold, the server answers with JSON-RPC error code -32002 and names the missing scope in the error data. It does not fail generically and it does not silently return an empty result, both of which are far worse failure modes for an AI agent that will otherwise conclude you have no deals.
{
"jsonrpc": "2.0",
"id": 7,
"error": {
"code": -32002,
"message": "...",
"data": {
"requiredScope": "deals:write",
"granted": ["contacts:read", "deals:read"]
}
}
}That shape makes the fix mechanical. Read requiredScope from the error, compare it to granted, and decide whether the assistant should have it. Frequently the answer is no, and the right response is to rephrase the request rather than widen the key. An assistant that keeps asking for webhooks:write is telling you something about how it interpreted your instruction.
The third column is the read or write annotation. It comes from the tool definition itself, so any MCP client that shows a confirmation dialog before write operations gets that signal from the server rather than from a guess about the name. One tool is annotated destructive on top of being a write: crm_delete_webhook. One tool is annotated as a write even though it changes nothing in your CRM: crm_run_agent, because each run spends AI credits.
Two practical notes before the catalogue. First, MCP responses are camelCase, which differs from the REST v1 API where fields are PascalCase, so code that consumes both needs to know which surface it is talking to. Second, the MCP server is a Business plan feature: a valid key on a lower plan is refused with HTTP 402 rather than a scope error, which is a different problem with a different fix. Pricing details are on the pricing page.
Contacts and CRM depth (11 tools)
Eleven tools cover the contact record itself and the four things layered on top of it: tags, lead score, ownership and the activity timeline. Four of them read and seven of them write, which makes this the single largest write surface in the catalogue and the group most worth thinking about before you hand out a key.
The split matters because the read half is harmless and the write half is not. An assistant holding only contacts:read can answer any question about who a person is and what was said to them. Add contacts:write and the same assistant can retag your database, reassign owners and overwrite lead scores. Those are recoverable actions, but recovering them by hand across a few hundred contacts is a bad afternoon.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_search_contacts | Finds people by name, username or phone number and returns the 25 most recently contacted matches. | contacts:read | Read |
crm_get_contact | Opens one contact by id and includes the last ten messages exchanged, so the assistant has real context before it says anything. | contacts:read | Read |
crm_get_contact_activity | Returns the contact timeline newest first: notes, stage moves, tag changes, score changes and assignments. | contacts:read | Read |
crm_list_tags | Lists the workspace tag dictionary along with how many contacts each tag is attached to. | contacts:read | Read |
crm_add_contact_note | Appends a timestamped note. The notes field holds 500 characters, so a long note pushes the oldest text off the front and can remove earlier notes. | contacts:write | Write |
crm_update_contact_stage | Moves a contact along the pipeline: lead, conversation, proposal, negotiation, then won or lost. | contacts:write | Write |
crm_create_tag | Adds a tag to the dictionary without attaching it to anybody. Asking twice for the same name returns the existing tag rather than a duplicate. | contacts:write | Write |
crm_tag_contact | Attaches an existing tag to a contact by tag id or exact name and logs a TagAdded activity. An unknown name is rejected instead of quietly creating a tag. | contacts:write | Write |
crm_untag_contact | Detaches a tag from a contact and logs a TagRemoved activity. Running it twice changes nothing the second time. | contacts:write | Write |
crm_set_lead_score | Sets a lead score from 0 to 100 by hand, marks it as a manual override of the AI score and logs a ScoreChanged activity. | contacts:write | Write |
crm_assign_contact | Gives a contact an owner on your team, or clears the owner when no user id is supplied. Logs an Assigned or Unassigned activity. | contacts:write | Write |
What you would actually ask for
The natural-language shape here is a question about a person, not a question about a table. You name somebody and the assistant works out that it needs to search first, open the record second and read the timeline third. Tagging requests are the other common shape, and they are the reason the tag dictionary is a separate read tool: an assistant that cannot list your tags will invent one, and an invented tag name gets rejected rather than created.
- "Who is Selin Kaya, what have we talked about, and has anyone on the team been assigned to her?"
- "Tag every contact I spoke to this week about the enterprise plan with the enterprise-interest tag, and tell me first which tags already exist."
Two rules save you from surprises. First, crm_tag_contact never creates a tag, so a workflow that invents tag names has to call crm_create_tag before it. Second, the notes field is a fixed 500 characters and older text falls off the front, so treat notes as a rolling scratchpad and put durable facts in tags, score or a deal.
Conversations and messaging (5 tools)
Five tools cover the one-to-one messaging history stored in the CRM and the two direct sends that reach a person on Telegram or X. Three read, two write, and the two writes are the ones that put words in front of a human being, so they sit behind their own scopes rather than sharing a general write scope.
The separation is deliberate. Reading conversation history needs contacts:read, the same scope that reads the contact record, because a message thread is part of the contact. Sending needs telegram:send or twitter:send, one scope per channel, so you can build an assistant that reads everything and sends on exactly one network.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_recent_conversations | Lists recently active contacts with a preview of the last message, newest activity first. The fastest answer to who needs a reply. | contacts:read | Read |
crm_get_conversation | Returns one contact thread newest first, up to 50 messages per call. Pass a message id in before to page further back. | contacts:read | Read |
crm_search_twitter_messages | Searches the X direct messages already stored in your CRM by free text and returns the 25 most recent matches. | contacts:read | Read |
crm_send_telegram_message | Queues an outbound Telegram message from one of your connected accounts, addressed by contact id or username. It is queued, not sent inline. | telegram:send | Write |
crm_send_twitter_dm | Sends an X direct message synchronously through your connected X session. The contact must already exist on the twitter platform with an X user id. | twitter:send | Write |
What you would actually ask for
Almost every messaging request starts as a triage question and ends as a drafting question. You want to know who is waiting, then you want the reply written, and only sometimes do you want it sent. Because the two send tools are separately scoped, you can leave the last step to yourself for weeks and still get the value: the assistant reads, ranks and drafts, and you paste. When you are ready to close the loop, add one send scope, not both.
- "Show me everyone who messaged in the last two days without a reply from us, ranked by how long they have been waiting."
- "Read my whole thread with this contact and draft a short Telegram follow-up that answers the pricing question they asked in March."
Telegram sends are asynchronous. crm_send_telegram_message returns once the job is queued, and the jobs tools further down this page are how you confirm the message actually left. X direct messages go out synchronously, so a failure surfaces in the tool result itself.
Email inbox (7 tools)
Seven tools cover the shared email inbox, and none of them sends mail. Three read mailboxes and threads, two set workflow state, two connect and re-test a mailbox, and every one of them is explicitly non-sending. That is the whole design: an assistant can connect the mailbox, read it, summarize a thread, close it, hand it to a colleague, and still be structurally incapable of emailing a customer.
The read tools also carry work that has already been done for you. A thread returned by crm_get_email_thread includes any AI summary and lead score computed when the mail arrived, so an assistant asking for context does not have to re-read forty messages to rank a lead.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_search_email_threads | Searches inbox threads by subject and preview text, with filters for status, contact and unread state. Read only, and it does not send mail. | email:read | Read |
crm_get_email_thread | Returns one thread as plain-text messages oldest first, plus any AI summary and lead score already stored against it. | email:read | Read |
crm_set_email_thread_status | Moves a thread between open, pending and closed. It changes workflow state only and sends nothing. | email:write | Write |
crm_assign_email_thread | Hands a thread to a teammate, or unassigns it when no user id is given. It sends nothing. | email:write | Write |
crm_list_email_accounts | Lists the connected mailboxes with sync status, per-mailbox thread and unread counts, and the mailbox slots left on the plan. Credentials are never returned. | email:read | Read |
crm_add_email_account | Connects a mailbox over IMAP and SMTP. Hosts and ports autofill for the common providers, both connections are authenticated first, and nothing is saved unless both succeed. | email:write | Write |
crm_test_email_account | Re-authenticates a connected mailbox with the credentials already on file and updates its status from the result. Diagnoses a mailbox that stopped syncing. | email:write | Write |
What you would actually ask for
Email requests are usually about the queue rather than a single message. People ask what is still open, who has been ignored longest, and which threads can be closed because the customer already got an answer somewhere else. The assignment tool turns that into something useful for a team: a morning pass that reads every open thread, decides who owns it and files it, without ever writing a word to a customer.
- "Summarize every open email thread from the last week, say what the customer is actually asking for, and flag the three that look most likely to churn."
- "Close the threads where the customer already replied thank you, and assign anything mentioning invoices to the finance owner."
email:write governs status, assignment and mailbox connection. Sending is a separate scope: the advanced email:send scope exists and is left unchecked by default when you mint a key, so a routine inbox assistant never gets accidental sending rights. A mailbox password passed to crm_add_email_account is stored encrypted and is never returned by any tool.
Deals (4 tools)
Four tools cover the sales pipeline: two read the deal list and one deal in detail, two create a deal and move it between stages. This is the clearest example of the safe-write boundary on the whole surface, because one specific transition is missing on purpose.
crm_update_deal_stage accepts lead, qualified, proposal, negotiation and lost. It does not accept won. Marking a deal won books an income entry in the ledger, and booking revenue is a decision a person makes in the panel, not something an assistant does because a conversation sounded positive. Creating a deal already closed is refused for the same reason.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_deals | Lists deals ordered by stage and then value, each with a count of its open tasks. | deals:read | Read |
crm_get_deal | Returns one deal with its linked tasks and the resolved contact name. | deals:read | Read |
crm_create_deal | Creates a deal in an active stage. A title is required, and a deal cannot be created already won or lost. | deals:write | Write |
crm_update_deal_stage | Moves a deal to lead, qualified, proposal, negotiation or lost. Moving to won is deliberately not supported here. | deals:write | Write |
What you would actually ask for
Pipeline questions are forecasting questions. You want the shape of the funnel, the deals that have gone quiet, and the one action that would move the biggest number. Because deal reads are cheap and deal writes are narrow, this is a good group to grant in full: an assistant with deals:read and deals:write can keep the board honest all week and still cannot invent revenue.
- "What is in my pipeline right now, grouped by stage, and which three deals have had no activity in two weeks?"
- "Create a deal for the agency I spoke to yesterday at fifteen thousand in the qualified stage, and move the stalled one to lost with a note explaining why."
Tasks (3 tools)
Three tools cover to-dos and reminders: one lists them, one creates them, one changes their status. Tasks are the cheapest place in the CRM for an assistant to write, because a wrong task costs you five seconds to delete and a wrong message costs you a customer.
That makes tasks:write the first write scope worth granting when you are still nervous about giving an assistant any write access at all. It gives you a real feedback loop: you can watch what the assistant decided to create, judge whether its reasoning was sound, and decide from evidence whether to widen the key.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_tasks | Lists tasks sorted by due date and then priority, which is what answers what is due and what is overdue. | tasks:read | Read |
crm_create_task | Creates a task with a required title, plus an optional contact link, deal link, due date and priority. | tasks:write | Write |
crm_complete_task | Marks a task done and stamps the completion time, or reopens it by passing an open or in-progress status. | tasks:write | Write |
What you would actually ask for
The useful pattern is turning a conversation into commitments. An assistant that has just read a thread knows what you promised, and creating three tasks with due dates is a far better record of that than a note nobody reads. The reverse works too: an end-of-day pass that closes everything already done keeps the list credible enough that you keep looking at it.
- "Read yesterday’s conversations and create a task for every promise I made, with a due date matching what I said."
- "What is overdue, what is due today, and in what order should I work through it?"
Pipelines (2 tools)
Two read-only tools describe the shape of your CRM rather than its contents: which boards exist, what stages they have, in what order, and how many contacts are sitting in each stage. There is no write tool here at all, because board structure is a configuration decision rather than a daily operation.
These are orientation tools. An assistant that calls crm_list_pipelines before it moves anybody gets stage names from your workspace instead of guessing generic ones, which is the difference between a stage move that lands and a stage move that gets rejected.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_pipelines | Lists every pipeline board with its ordered stage columns and the live contact count in each stage. | pipelines:read | Read |
crm_get_pipeline | Returns one board by id with the same ordered stages and per-stage contact counts. | pipelines:read | Read |
What you would actually ask for
You rarely ask for a pipeline directly. You ask a question about your funnel and the assistant reaches for these first to find out how your funnel is actually named. The one time you do ask directly is when you are diagnosing a bottleneck, because per-stage counts across every board is a picture you cannot get from a single deal list.
- "How are my boards set up, and which stage has the most contacts stuck in it?"
- "Before you move anyone, list my pipeline stages so we agree on what qualified actually means here."
pipelines:read is a small, safe scope worth granting to almost any assistant. Without it, an assistant guesses stage names, and guessed stage names produce rejected write calls that look like bugs.
Finance (4 tools)
Four tools, all read-only, all under finance:read. This group is reporting and nothing else. It reads the ledger, invoices and revenue-source configuration, and it cannot move, charge, settle or refund a single unit of currency.
That constraint is worth stating plainly because finance is where people are rightly most nervous about AI access. crm_list_invoices returns no payment link. crm_list_transactions cannot create, edit, refund or settle an entry. crm_revenue_sources_summary never returns a key or credential. Nothing in this group can be chained into a payment.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_finance_summary | Reports realized income, expense and net per currency, outstanding totals and the largest expense categories over a window. Reads the ledger, moves nothing. | finance:read | Read |
crm_list_transactions | Lists ledger entries newest first with optional filters. It cannot create, edit, refund or settle a transaction. | finance:read | Read |
crm_list_invoices | Lists invoices newest first with an outstanding summary per currency. It cannot create, send, void or pay an invoice, and it returns no payment link. | finance:read | Read |
crm_revenue_sources_summary | Lists configured external revenue sources with last-sync status, total ingested count and last event time. Keys and credentials are never returned. | finance:read | Read |
What you would actually ask for
Finance questions over MCP are the ones that would otherwise mean exporting a spreadsheet on a Friday afternoon. Because the entire group is read-only, you can grant finance:read to an analysis assistant without the usual argument about blast radius. The worst case for a leaked finance:read key is that somebody sees numbers, which is a real risk but a bounded one, and it is not the same category as a key that can spend.
- "How did we do last month by currency, what is still outstanding, and which expense category grew fastest?"
- "Which invoices are overdue, how much is owed in total, and which customers do they belong to?"
A finance:write scope exists on the key form and is left unchecked by default. Nothing in the MCP catalogue on this page requires it, which is the clearest possible signal that finance over MCP is a reporting surface.
Sequences (4 tools)
Four tools cover outbound sequences: two report on them and two control whether they are running. Notice what is not here. There is no tool to create a sequence, edit its steps, change its message copy or enroll a contact into it. The MCP surface can start and stop the machine, and it cannot rebuild it.
That is the right boundary for automated outreach. Pausing a live campaign because the AI noticed an error spike is exactly the kind of judgement you want an assistant making at three in the morning. Rewriting the copy that goes to two thousand people is not.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_sequences | Lists outbound sequences with status, target counts and progress, which answers what campaigns are running. | sequences:read | Read |
crm_get_sequence_status | Returns a deep report on one sequence: status, target, processed, successful and failed counts, its message steps and recent job activity. | sequences:read | Read |
crm_pause_sequence | Stops a sequence queueing new messages. Jobs already in flight still run, and pausing a paused sequence does nothing. | sequences:write | Write |
crm_resume_sequence | Starts a paused sequence queueing again. | sequences:write | Write |
What you would actually ask for
The high-value request is a safety net rather than a campaign builder. You ask the assistant to watch failure rates and pull the handbrake, and because pause is idempotent it can do that without worrying about double-firing. The reporting half answers the weekly question of which campaign is worth its slot.
- "Check every running sequence and pause anything whose failure rate went above one in five, then tell me what you paused and why."
- "Which of my sequences is converting worst, and what does its step list look like compared to the best one?"
Pause is not a cancel. In-flight jobs still run, so the correct verification after a pause is to watch the outbound jobs list until it drains rather than assuming the queue emptied instantly.
Social inbox (7 tools)
Seven tools cover direct messages across every connected network: Instagram, Facebook, X, LinkedIn, TikTok, YouTube, Threads, Pinterest, Reddit, Bluesky, Telegram and WhatsApp. Five read and two write. This is the largest read group after contacts, and for a very practical reason: an assistant answering a stranger on Instagram needs far more context than one replying to a known contact.
The one to reach for first is crm_social_inbox_summary. A single call returns conversation and unread totals overall and per network, plus the threads still waiting on a reply, oldest first. That is a whole triage pass in one request instead of a dozen, which matters when your budget is 60 requests a minute.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_social_accounts | Lists the social accounts connected to the workspace with platform, handle and posting limits. Call it first to learn which account id to use. | social:read | Read |
crm_social_inbox_summary | One call for the whole inbox: conversation and unread totals overall and per network, plus the threads still waiting on a reply, oldest first. | social:read | Read |
crm_list_social_conversations | Lists DM threads most recently active first, with participant, unread count and last-message preview. Also how you find a conversation id. | social:read | Read |
crm_get_social_conversation | Returns one thread with the participant details, the bridged CRM contact and the last ten messages. Read this before drafting a reply. | social:read | Read |
crm_list_social_messages | Pages through a thread, oldest first inside a page. Voice notes carry their transcript and translated messages carry both wordings. Pass beforeMessageId to walk back. | social:read | Read |
crm_send_social_message | Sends a DM into an existing thread. It reaches a real person immediately, pauses AI auto-reply for the linked contact and records the send on the CRM timeline. | social:write | Write |
crm_mark_social_conversation_read | Clears a thread unread badge on the network as well as in the CRM. Marking an already-read thread changes nothing. | social:write | Write |
What you would actually ask for
The request people actually make is some version of who is waiting and what should I say. That resolves into a summary call, a thread read for the two or three that matter, and a draft. Whether the draft goes out is a separate decision governed by a separate scope, and plenty of teams run this loop for months with social:read only, using the assistant as a very fast reader and writer while a human presses send.
- "Which social conversations are still waiting on us, across every network, and who has been waiting longest?"
- "Read this Instagram thread and draft a reply in the same language the customer used, matching how long their messages are."
crm_send_social_message is the tool that most obviously touches the outside world, and it carries platform rules with it. WhatsApp only allows a free-form reply within 24 hours of the customer’s last message, so a thread that has gone quiet for two days will refuse a casual follow-up no matter how the request was phrased.
Social posts (6 tools)
Six tools cover scheduled and published content: three read the calendar and its results, three schedule, edit and cancel. Publishing is the other place besides direct messaging where a tool call becomes visible to the public, so the read and write halves sit under separate scopes, posts:read and posts:write.
One detail changes how you phrase requests. crm_schedule_social_post creates one post per target account, so asking for the same thing on Instagram and LinkedIn produces two posts, not one post with two destinations. Per-platform rules are enforced at schedule time: TikTok and YouTube need a video, Instagram needs media, and X caps the text at 280 characters.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_social_posts | Lists scheduled and published posts, newest scheduled time first, with status, published URL and any failure reason. | posts:read | Read |
crm_get_social_post | Returns one post with its full content, media, schedule, status and published URL. | posts:read | Read |
crm_social_post_stats | Reports publishing volume and outcome over a recent window, by status overall and per network, plus the last publish time. | posts:read | Read |
crm_schedule_social_post | Schedules a post on one or more connected accounts, creating one post per account. scheduledAt is required unless publishNow is set, which publishes to a real audience straight away. | posts:write | Write |
crm_update_social_post | Edits the text, media or scheduled time of a post that has not gone out. Anything published, in flight, failed or cancelled is rejected. | posts:write | Write |
crm_cancel_social_post | Cancels a scheduled post so it never publishes. A post that has already gone out cannot be withdrawn from here. | posts:write | Write |
What you would actually ask for
Content requests come in two flavors. The planning flavor asks what is already queued and where the gaps are, which is pure posts:read. The production flavor asks for a week of posts to be written and scheduled, which needs posts:write plus social:read for the account list, because the account roster lives with the social inbox rather than with posts.
- "What is going out this week, on which networks, and where are the empty days?"
- "Draft five posts about the new pricing page and schedule them across LinkedIn and X for weekday mornings next week."
Watch publishNow. Everything else in this group is reversible up to the moment of publication, and publishNow removes exactly that window. A safe house rule is that an assistant may schedule but only a person may publish immediately.
Google Ads (52 tools)
52 tools put paid search next to the pipeline it is supposed to be filling: 26 of them read and 26 write, across exactly two scopes, ads:read for every report and ads:write for anything that changes a live ad account. This is the single largest family in the catalogue, because Google Ads exposes as much surface as the rest of this CRM combined: reporting at five levels plus time series and per-dimension segments, Keyword Planner research and a spend forecast, conversion tracking and Customer Match audiences, ad extensions, labels, portfolio bidding strategies and campaign experiments, on top of the budget, bidding and status changes the account runs on day to day.
This is the one group where a mistaken write costs money rather than tidiness, so it is also the one with the most safety net. Most writes accept validateOnly to preview a change with Google before anything is sent, an applied change returns a changeId, and crm_google_ads_undo reverts most of them within 30 days. Ten of the 26 write tools are annotated destructive anyway, because removing an entity, deleting a shared list, or uploading real customer data to Google cannot be walked back the same way; those need confirm: true on top of the scope. The read half is where most of the day-to-day value sits: crm_google_ads_breakdown at search term level is how you find the queries worth excluding, and it needs nothing beyond ads:read.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_google_ads_account_alerts | Health check of one Google Ads account: everything that stops or throttles its ads, as alerts sorted by severity (critical, warning, info), each with a code, a plain explanation, the entity it concerns and the tool to use next. | ads:read | Read |
crm_google_ads_ad_details | Full content and review state of Google Ads ads: responsive search ad headlines and descriptions with their pinned position, final and mobile URLs, display path (path1, path2), tracking template, final URL suffix and custom parameters, display URL of older ad types, approval and review status with policy topics and evidence, ad strength with Google's suggestions to raise it (actionItems), primary status and reasons. | ads:read | Read |
crm_google_ads_ad_preview | Heuristic diagnosis of whether a search could show an ad from this account, built entirely from the account's own settings (campaign status, budget, schedule, location and language targeting, keywords, negative keywords and ad approval). | ads:read | Read |
crm_google_ads_add_keywords | Add keywords to a Search ad group. | ads:write | Write |
crm_google_ads_add_negative_keywords | Add negative keywords at the campaign, ad group or shared-list level. | ads:write | Write |
crm_google_ads_apply_label | Create a label, or assign it to, or unassign it from, campaigns, ad groups, ads and keywords. | ads:write | Write |
crm_google_ads_apply_recommendation | Apply or dismiss Google recommendations by id (from crm_google_ads_recommendations). | ads:write | Write |
crm_google_ads_assets | Assets (ad extensions) of a Google Ads account and everywhere each one is linked: sitelinks, callouts, structured snippets, call, price, promotion, image, lead form, business name and logo. | ads:read | Read |
crm_google_ads_auction_insights | Auction insights for Search: which other advertisers (by display domain) competed in the same auctions and how the account compares: impression share, overlap rate, how often they ranked above, and the account's outranking share. | ads:read | Read |
crm_google_ads_audiences | Audience (user) lists of a Google Ads account, newest first: type, membership status, estimated size, eligibility for Search/Display, and the Customer Match match rate of the latest upload. | ads:read | Read |
crm_google_ads_bidding_strategies | Portfolio (shared) bidding strategies of the account: type, status, targets and limits in the account currency, and which campaigns use each one. | ads:read | Read |
crm_google_ads_billing | Billing state of one account: the billing setup, whether it is on monthly invoicing, its account budgets, and the invoices issued this month and last month. | ads:read | Read |
crm_google_ads_breakdown | Performance one level below the campaign: ad groups, ads, keywords, search terms and several more specialised levels, with the diagnostics needed to act on it. | ads:read | Read |
crm_google_ads_budget_pacing | Today's spend against budget for every enabled campaign: spent so far, expected spend by now, pace, monthly cap and projected month spend. | ads:read | Read |
crm_google_ads_bulk | Apply many keyword-family changes in one call: status, bids, negatives and keyword adds, each checked and reported on its own. | ads:write | Write |
crm_google_ads_campaign_settings | Live settings of one campaign: status, channel type, bidding strategy and its target, daily budget, networks and schedule. Read this before changing a budget or a bidding strategy. | ads:read | Read |
crm_google_ads_campaign_to_draft | Copy a live Search campaign into a new Ads Studio draft (paused) that a person can edit, approve and publish, for example into another connected account. | ads:write | Write |
crm_google_ads_campaigns | Campaigns of an account with their settings and performance for a window, most expensive first, including campaigns with no traffic. | ads:read | Read |
crm_google_ads_change_history | Who changed what in a Google Ads account, newest first: Google's own change history merged with changes made through Pinlyx tools. | ads:read | Read |
crm_google_ads_conversion_actions | Conversion tracking health of a Google Ads account: every conversion action, its type and status, and a recording verdict per action. | ads:read | Read |
crm_google_ads_create_ad_group | Create a new ad group in a Search or Display campaign, optionally with its first keywords, all in one atomic call. | ads:write | Write |
crm_google_ads_create_asset | Create an asset (ad extension) and optionally link it in the same atomic call. Image assets fetch from a public https URL. | ads:write | Write |
crm_google_ads_create_bidding_strategy | Create a portfolio (shared) bidding strategy that several campaigns can use, and optionally attach existing campaigns to it in the same atomic call. | ads:write | Write |
crm_google_ads_create_rsa | Create a responsive search ad in a Search ad group, checked against every Google length and count rule before anything is sent. | ads:write | Write |
crm_google_ads_customer_match | Sync CRM contacts into a Google Ads Customer Match list, so campaigns can target, exclude or find people like existing customers. | ads:write | Write |
crm_google_ads_experiments | Campaign experiments (A/B tests Google Ads runs by splitting a campaign's traffic): status, dates, control versus treatment and the traffic split. | ads:read | Read |
crm_google_ads_forecast | Keyword Planner forecast for a new Search campaign: expected clicks, cost and average CPC over the forecast period, plus conversions with maximize_conversions. | ads:read | Read |
crm_google_ads_geo_search | Find Google Ads location ids by name, or look up known ids, for use with the targeting and ad preview tools. | ads:read | Read |
crm_google_ads_keyword_ideas | Keyword Planner ideas from up to 20 seed keywords, a page URL, or a whole site: average monthly searches, competition and the top-of-page bid range. | ads:read | Read |
crm_google_ads_labels | List the account's labels, optionally with every campaign, ad group, ad and keyword each one is assigned to. | ads:read | Read |
crm_google_ads_link_asset | Link an existing asset to the account, a campaign or an ad group, or remove that link (unlinking needs confirm: true). | ads:write | Write |
crm_google_ads_manage_experiment | Create and run a campaign experiment on a Search or Display campaign: schedule it, end it, promote it or turn it into an independent campaign. | ads:write | Write |
crm_google_ads_manage_negative_list | Create, attach, detach, rename or delete a shared negative keyword list (a list of negatives reusable across campaigns). | ads:write | Write |
crm_google_ads_negative_keywords | List negative keywords of an account: campaign-level, ad group-level, and shared negative keyword lists, with the campaigns each list is attached to. | ads:read | Read |
crm_google_ads_recommendations | Google's recommendations for one account, with the estimated weekly impact before and after applying and the account optimization score. | ads:read | Read |
crm_google_ads_remove_negative_keywords | Remove negative keywords at the campaign, ad group or shared-list level. Applying it for real needs confirm: true. | ads:write | Write |
crm_google_ads_save_conversion_action | Create a Google Ads conversion action, or change an existing one: status, whether it feeds bidding, and its counting type. | ads:write | Write |
crm_google_ads_segments | Performance split by one dimension: device, network, hour of day, day of week, country, region, city, age, gender or conversion action. | ads:read | Read |
crm_google_ads_summary | Account-level performance for a window: spend, impressions, clicks, CTR, average CPC, conversions, conversion value, ROAS and search impression share. | ads:read | Read |
crm_google_ads_targeting | Full targeting of one campaign: locations, languages, ad schedule, device bid modifiers, and audiences and demographics with their mode. | ads:read | Read |
crm_google_ads_timeseries | Performance over time for the account, one campaign or one ad group: a point per day, week, month or hour, in the account time zone. | ads:read | Read |
crm_google_ads_undo | Revert a Google Ads change made through Pinlyx tools, by the changeId that write returned. Removals and changes older than 30 days cannot be undone. | ads:write | Write |
crm_google_ads_update_ad | Edit an existing ad in place; it keeps its id and history. Changed text goes back through Google policy review. | ads:write | Write |
crm_google_ads_update_ad_group | Rename an ad group and/or change its tracking template or final URL suffix. | ads:write | Write |
crm_google_ads_update_keyword | Change a keyword's match type and/or its own final URL. Changing match type gives the keyword a new id. | ads:write | Write |
crm_google_ads_upload_conversions | Send offline conversions (for example won CRM deals) to a conversion action of the workspace's own account, so Smart Bidding learns from real results. | ads:write | Write |
crm_list_google_ads_accounts | List the Google Ads accounts connected to the workspace and whether each can be used, with currency, time zone and today's remaining request allowance. Call it first, because every other Google Ads tool needs a customerId from here. | ads:read | Read |
crm_set_google_ads_status | Pause, enable or remove one or more campaigns, ad groups, ads or keywords in a single call. Removing needs confirm: true. | ads:write | Write |
crm_update_google_ads_bid | Set or clear a manual max CPC bid on an ad group or a keyword, in the account currency, not micros. | ads:write | Write |
crm_update_google_ads_bidding | Switch a campaign's bidding strategy or change its current target, including target impression share and portfolio strategies. | ads:write | Write |
crm_update_google_ads_budget | Set the daily budget of a campaign in the account currency. Takes effect immediately; a shared budget needs confirmShared: true. | ads:write | Write |
crm_update_google_ads_targeting | Change a campaign's locations, languages, ad schedule or device bid modifiers; several kinds can change in one atomic call. | ads:write | Write |
What you would actually ask for
Ads questions still split cleanly in two. The diagnostic ask is pure ads:read and it is where most of the value sits, because the answer is a list of specific things to change rather than another chart. The execution ask needs ads:write, and it belongs on a key you supervise, because the same call that pauses a losing ad group will happily pause a winning one, and a handful of writes here send real data to Google or spend real money the moment they run for real.
- "Which search terms spent the most last month without converting, and which campaigns did they come from?"
- "Before you change anything, show me what a 20% budget increase on the top campaign would look like, and only apply it once I say go."
ads:write is the only scope on this server whose mistakes can arrive as an invoice from someone else, and it now carries the most safety net of any group: validateOnly previews almost any write, an applied change returns a changeId, and crm_google_ads_undo reverts most of them within 30 days. Google still bills what the account spends, so a wrong daily budget is real money the same day, and a Customer Match upload sends real contact data to Google the moment confirm is true. The house rule that survives contact with reality is that an assistant may report, may preview, and may pause, and only a person raises a budget, removes an entity, or confirms a Customer Match sync.
Meta & TikTok Ads (12 tools)
Twelve tools put Facebook, Instagram and TikTok reporting and control next to Google Ads, under the same two scopes: ads:read for every report, ads:write for anything that changes a live campaign or ad set. Eight read and four write, and every call runs server side with the OAuth or API grant you connected in the panel, the same as Google Ads.
Meta covers Facebook and Instagram together through one ad account, with ad set and ad level detail, targeting and creative, and a pixel health check worth reading before trusting the purchase or lead numbers a campaign reports. TikTok is narrower today: connected accounts, campaigns and status/budget changes, because that is what the connected surface covers so far. Both follow the Google Ads write pattern: validateOnly previews a change, and a status or budget change is recorded in the ads change log so it can be reverted by calling the tool again with the previous value; neither network exposes an undo endpoint the way crm_google_ads_undo does.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_meta_ad_accounts | List the Meta (Facebook and Instagram) ad accounts connected to the workspace: account id, name, currency, time zone, connection status and any issue that stops it from being used. | ads:read | Read |
crm_list_tiktok_ad_accounts | List the TikTok advertiser accounts connected to the workspace: account id, name, currency, time zone, connection status and any issue. | ads:read | Read |
crm_meta_ads_breakdown | Meta ad sets or ads: status, optimization goal, bid, budget, learning phase and targeting for ad sets; creative and review status for ads. Flags likely creative fatigue. | ads:read | Read |
crm_meta_ads_campaigns | Meta campaigns with status, objective, bid strategy, budget and performance for a window. | ads:read | Read |
crm_meta_ads_summary | Account-level Meta Ads performance for a window: spend, impressions, reach, frequency, clicks, ctr, cpc, cpm, the top conversion actions Meta reports, purchase value and ROAS. | ads:read | Read |
crm_meta_pixel_status | Health of the Meta pixels shared with an ad account: whether each is firing, event counts by type, and whether server-side events back up the browser ones. | ads:read | Read |
crm_set_meta_ads_status | Set a Meta campaign, ad set or ad to ACTIVE or PAUSED, or to ARCHIVED / DELETED, which stop delivery for good (need confirm: true). | ads:write | Write |
crm_set_tiktok_ads_status | Set a TikTok campaign to ACTIVE (ENABLE) or PAUSED (DISABLE). | ads:write | Write |
crm_tiktok_ads_campaigns | TikTok campaigns with status, daily budget and performance (spend, impressions, clicks, conversions, conversion value, ROAS) for a preset window. | ads:read | Read |
crm_tiktok_ads_summary | Advertiser-level TikTok Ads performance for a preset window: spend, impressions, clicks, ctr, cpc, conversions, conversion value and ROAS. | ads:read | Read |
crm_update_meta_ads_budget | Change the daily or lifetime budget of a Meta campaign or ad set, in the account's currency as major units. Raising it more than 3x needs confirm: true. | ads:write | Write |
crm_update_tiktok_ads_budget | Change the daily budget of a TikTok campaign. Raising it more than 3x needs confirm: true. | ads:write | Write |
What you would actually ask for
The request people actually make is a cross-check: how is this campaign doing on Meta compared with Google, and is the pixel actually catching the purchases the summary reports. Reads answer both without touching anything; writes pause or re-budget once you already know which one is underperforming.
- "Compare this week's Meta and TikTok spend against Google Ads for the same campaigns, and flag anything Meta counts as delivering but the pixel has not fired for in three days."
- "Pause the Meta ad sets whose frequency is above 3 with CTR down at least 20% from last week, that's the creative fatigue signal."
crm_set_meta_ads_status can archive or delete a campaign, ad set or ad, which stops delivery for good and cannot be reactivated; that needs confirm: true, same as a Google Ads removal. TikTok's write tools have no validate-only mode on the network side: once validateOnly is left off, TikTok's own API is called for real, with no dry run to catch what TikTok itself would reject.
Ads Studio, alerts and attribution (9 tools)
Nine tools cover the parts of advertising that sit above a single network: building and approving a campaign draft before it exists anywhere, watching connected Google Ads accounts for trouble, and joining ad spend on any network to what actually happened in the CRM. Four read and five write.
Ads Studio is where a campaign is drafted, validated and approved by a person before any tool can publish it, across Google, Meta and TikTok in the same builder. crm_save_ad_draft writes the spec, crm_dry_run_ad_draft checks it against the real network without creating anything, crm_submit_ad_draft sends it for a person's approval, and crm_publish_ad_draft is refused until that approval happened. The alert tools configure and read a monitor that checks connected Google Ads accounts on a schedule and delivers everything as a webhook, never as something this tool returns as it happens. The attribution report is the only tool on the server that answers whether ad spend on any network actually produced a lead or a won deal.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_ads_alerts | Current alert settings (which events are watched, the thresholds), which connected accounts are monitored, when the monitor last ran, and the most recent alerts it raised. | ads:read | Read |
crm_ads_attribution_report | Ad spend joined with CRM results, per campaign or per network: spend and platform conversions from Google Ads, Meta and TikTok next to the CRM leads and deals won they produced. | ads:read | Read |
crm_configure_ads_alerts | Turn ad account alerts on or off and choose which of the five ads.* events they watch, and their thresholds. | ads:write | Write |
crm_dry_run_ad_draft | Ask the ad network to validate a draft without creating anything. Run it before submitting and again before publishing. | ads:write | Write |
crm_get_ad_draft | One Ads Studio draft in full: the campaign spec exactly as it would publish, its local validation issues, the reviewer note, and the publish result. | ads:read | Read |
crm_list_ad_drafts | Ads Studio campaign drafts (Google, Meta, TikTok), most recently updated first, with status and the next step to take on each. | ads:read | Read |
crm_publish_ad_draft | Publish an Approved draft into its ad account. Refused unless a person approved it in Ads Studio; created paused on Google. | ads:write | Write |
crm_save_ad_draft | Create an Ads Studio draft, or change one. Saving over a submitted or approved draft sends it back to Draft for re-approval. | ads:write | Write |
crm_submit_ad_draft | Submit a Draft or Rejected draft for approval; its status becomes PendingApproval. Only a person can approve it, in Ads Studio. | ads:write | Write |
What you would actually ask for
Two shapes of request show up here. One is process: build this campaign as a draft, validate it, and wait for me to approve it before anything reaches an ad network. The other is monitoring: tell me the moment a budget is about to run out or an ad gets disapproved, and tell me whether the money we're spending on ads is actually turning into revenue.
- "Draft a Search campaign from this brief, dry run it against Google, and show me the validation issues before you submit it for approval."
- "Turn on alerts for disapproved ads and budget exhaustion, and tell me if any connected account still needs a webhook subscribed to catch them."
Alerts are delivered exclusively as webhooks: crm_ads_alerts only reports settings and the most recent alerts already raised, it never blocks waiting for a new one. Without an active webhook endpoint subscribed to an ads.* event, alerts have nowhere to go, and crm_configure_ads_alerts tells you which of the events you just enabled still need one.
Webhooks (4 tools)
Four tools cover outbound webhook endpoints: two read the registry and its delivery history, two register and remove endpoints. This group contains the only hard delete in the entire catalogue, and it is annotated as destructive so a well-behaved client can warn before it runs.
The delivery-history tool is the quietly useful one. crm_list_webhook_deliveries returns status, attempt count, last response code and last error for one endpoint, newest first, which turns the worst question in integration work into a single tool call.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_webhooks | Lists registered endpoints with URL, subscribed event types and health. Signing secrets are never returned, only a short preview. | webhooks:read | Read |
crm_list_webhook_deliveries | Lists recent delivery attempts for one endpoint with status, attempt count, last response code and last error, newest first. | webhooks:read | Read |
crm_create_webhook | Registers an HTTPS endpoint, optionally narrowed to specific event types. The signing secret is returned once and cannot be retrieved later. | webhooks:write | Write |
crm_delete_webhook | Permanently removes an endpoint and stops every future delivery to it. This is the one call in the catalogue that cannot be undone. | webhooks:write | Write |
What you would actually ask for
This group answers debugging questions, and it answers them fastest when the assistant can see both halves: what is registered and what happened to the last deliveries. Ninety percent of webhook problems are one of three things, an endpoint that was never subscribed to the event, a receiver returning a non-2xx status, or an endpoint that was deleted and forgotten. All three are visible from webhooks:read alone.
- "My webhook stopped firing. Which endpoints do I have, what events are they subscribed to, and what did the last twenty deliveries return?"
- "Register an endpoint on my staging server for message events only, and show me the signing secret so I can store it."
Two things to remember. The signing secret from crm_create_webhook appears once in that response and is never retrievable afterwards, so an assistant that creates an endpoint has to hand you the secret in the same turn. And crm_delete_webhook is genuinely permanent, which is why webhooks:write is the scope least suited to a general-purpose chat assistant.
AI agents and outbound jobs (4 tools)
Four tools sit at the boundary between your own automation and the assistant looking at it. Two describe the AI auto-reply agents already running in your workspace, and two follow outbound message jobs through the send queue. This is how an assistant answers the question that follows every send: did it actually leave.
crm_run_agent deserves its own paragraph. It runs one of your agents against a sample inbound message and returns the reply it would have sent. Nothing is delivered, no contact hears from you and no CRM record is created, changed or deleted. It is annotated as a non-read-only tool for one reason only: each run calls an external model provider and spends AI credits.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_list_agents | Lists your AI auto-reply agents with status, channels, trigger and response mode, model and a 24-hour run count. | agents:read | Read |
crm_run_agent | Test-runs an agent against a sample message and returns the reply it would send. Nothing is delivered and no record changes. Flagged as a write only because each run spends AI credits. | agents:run | Write |
crm_list_jobs | Lists outbound Telegram send jobs newest first with status and error visibility, which answers whether your messages actually went out. | jobs:read | Read |
crm_get_job | Returns one job with its full text, target, status and last error, for diagnosing a specific send failure. | jobs:read | Read |
What you would actually ask for
The agent tools turn prompt tuning into something you can iterate on in a chat window: feed a real awkward customer message, read what the agent would say, adjust, run again. The job tools turn delivery from a hope into a fact. Together they cover the two things people worry about most when they automate replies, which is whether the wording is right and whether the message left the building.
- "Run my support agent against this angry message about a late refund and show me what it would send, without sending it."
- "Did everything I queued this morning go out? List anything that failed and show me the actual error."
agents:run is the one scope whose real cost is money rather than risk. It cannot damage your data, but a loop that runs an agent a hundred times spends a hundred model calls, so it belongs on assistants you supervise rather than on unattended schedules.
Analytics and connected accounts (4 tools)
Four read-only tools give an assistant the numbers and the account roster it needs to orient itself. Three sit under analytics:read and one, the account list, sits under contacts:read. That last placement surprises people, so it is worth saying out loud: crm_list_accounts is a contacts:read tool.
It matters because crm_list_accounts is the prerequisite for sending anything. Every send tool needs an account id, and this is where account ids come from. A key that has telegram:send but not contacts:read can send only to an account id you hardcode, which is occasionally what you want and usually a bug in your scope plan.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_dashboard_summary | Headline numbers for the workspace: total contacts, messages queued and sent today, and connected accounts. A ready-made daily standup. | analytics:read | Read |
crm_messaging_stats | Counts sent, failed and queued messages over a 1, 7 or 30 day window, optionally for a single account. | analytics:read | Read |
crm_top_contacts | Ranks the most-messaged contacts of the last 30 days by outbound volume, which is a decent proxy for who is warmest. | analytics:read | Read |
crm_list_accounts | Lists connected Telegram and X accounts with id, type, name, status and most recent activity. Required before sending, because it supplies the account id. | contacts:read | Read |
What you would actually ask for
These are the tools an assistant reaches for when you open a chat and say good morning. One dashboard call plus one stats call is enough for a useful standup, and the account list tells it which identities it is allowed to speak as. The trend question is the more valuable one, because a raw count today means nothing without the seven days behind it.
- "Give me a two-line standup: what happened yesterday, what is queued today, and is anything failing more than usual?"
- "How does this week compare with last week, and is one of my connected accounts responsible for most of the failures?"
Feedback and workspace (4 tools)
Four tools sit outside the scope system entirely: they answer with any API key, regardless of which scopes it holds, because a session should always be able to say who it is and always be able to report a problem, even one it hit because everything else on this page was filtered away.
crm_whoami is the one tool worth calling at the start of every session: it names the workspace, the key's own scopes, and every tool the connection cannot currently call, paired with the scope that would unlock it. The other three are a two-way channel to the Pinlyx team, filed in the same inbox as feedback sent from the panel: crm_submit_feedback files a report, crm_list_feedback reads the thread and any reply, and crm_reply_feedback writes back into it.
| Tool | What it does | Required scope | Mode |
|---|---|---|---|
crm_whoami | Describes this connection: the workspace, the key's own scopes, client and server names and versions, and every tool this connection cannot call with the scope it needs. | any | Read |
crm_list_feedback | Feedback this account has sent to the Pinlyx team, through this server or from the panel, with the team's replies. Reading it marks nothing as read. | any | Read |
crm_submit_feedback | Tells the Pinlyx team about a tool that is missing, misleading, slow or wrong, an unhelpful error, or something that worked well. Filed in the same inbox as panel feedback. | any | Write |
crm_reply_feedback | Writes back into one of this account's feedback threads, for example to answer a question from the Pinlyx team or add detail to a report. | any | Write |
What you would actually ask for
The natural request is diagnostic: why can't this assistant do X, or something about this tool did not work as expected. crm_whoami answers the first without guessing; crm_submit_feedback turns the second into something a person on the Pinlyx team actually reads, instead of a complaint that evaporates at the end of the conversation.
- "Why can't you create a deal right now? Tell me exactly which scope is missing."
- "That last Google Ads call returned something that looked wrong. File it as feedback with what you expected and what came back, and check whether the team has replied to anything I've sent before."
Never put passwords, API keys, tokens or personal data such as a contact's name, email or phone number into a feedback report. Both write tools are rate-limited: the same report within 10 minutes returns the original instead of filing a duplicate, and there is a 20-per-hour ceiling, which matters more for an assistant that might otherwise retry a failed report in a loop than for a person.
The 21 resources, and when to read one instead of calling a tool
A resource is a fixed, read-only view of your workspace addressed by a crm:// URI, and it takes no arguments. That single property is what makes resources valuable. A tool call requires the assistant to decide what to pass, and every decision is a chance to be wrong. A resource read requires no decision at all: the URI is the whole request, and the server returns the same well-shaped answer every time.
Read a resource instead of calling a tool whenever three conditions hold. The question is general rather than about one specific record. The default window or default ordering is what you wanted anyway. And you are at the start of a session, where the goal is to give the assistant enough context to reason well rather than to answer one narrow question. Priming a conversation with two or three resources is the highest-value request-per-token move available on this server.
Reach for a tool instead when you need a specific record by id, a non-default time window, a filter, or pagination. crm://deals/open gives you the ranked opportunity list; crm_get_deal gives you one deal with its tasks. crm://jobs/recent tells you whether sends are failing; crm_get_job tells you why one specific send failed. The resource answers the question you asked out loud, and the tool answers the follow-up.
{"jsonrpc":"2.0","id":2,"method":"resources/list"}
{"jsonrpc":"2.0","id":3,"method":"resources/read",
"params":{"uri":"crm://social/inbox"}}| Resource URI | What it returns | When to read it |
|---|---|---|
crm://me | Identity, plan and a summary of connected accounts for the key holder. | At the start of any session, so the assistant knows whose workspace it is looking at before it says anything about it. |
crm://accounts | Every connected Telegram and X account with type, status and last activity. | Before any send, in place of crm_list_accounts. The account id an assistant needs is right here with no arguments to guess. |
crm://sequences | Outbound sequences with status, daily limit and target progress. | For a campaign overview, in place of crm_list_sequences. Drop to the tool only when you need one sequence in depth. |
crm://recent-conversations | The last 20 active contacts with name, platform, last-message preview and unread flag. | To open a triage conversation, in place of crm_list_recent_conversations. It is the cheapest way to make an assistant useful in one turn. |
crm://plan | Current subscription plan, period, daily message limits and remaining seats. | Before queueing a large batch of sends, so the assistant knows the daily ceiling instead of finding it by hitting it. |
crm://kpis/7d | Sent, failed and queued message counts for the last seven days plus a per-day breakdown. | For trend questions, in place of crm_messaging_stats. The per-day series is what makes an answer about direction possible. |
crm://finance/summary | Realized income, expense and net per currency for the last 30 days. | For a quick read on financial health, in place of crm_finance_summary when the default 30-day window is what you wanted anyway. |
crm://deals/pipeline | Deal count and total value per pipeline stage. | For funnel shape rather than individual deals. One read answers where value is concentrated without paging a deal list. |
crm://tasks/today | Open tasks due today or already overdue, ordered by due date. | For a morning planning turn, in place of crm_list_tasks with filters the assistant would otherwise have to invent. |
crm://inbox | Up to 20 open email threads with subject, preview and unread count. | To find out who is waiting on an email reply, in place of a crm_search_email_threads call with an empty query. |
crm://pipelines | All contact pipelines with ordered stages and the live contact count in each stage. | To prime an assistant with your board structure before it moves anyone, in place of crm_list_pipelines. |
crm://jobs/recent | The last 20 outbound message jobs with status, target, account and a trimmed error summary. | For a delivery check after a batch of sends, in place of crm_list_jobs. Drop to crm_get_job only for a specific failure. |
crm://finance/invoices | Open invoices summarized per currency, plus the most overdue ones. | For collections questions, in place of crm_list_invoices. The most-overdue list is already sorted the way you would sort it. |
crm://tasks/overdue | Open tasks strictly past their due date, oldest first. | When you want only what has slipped. It is deliberately narrower than the today feed, which also includes tasks due later today. |
crm://agents | AI auto-reply agents with status, channels, response mode and rate limits, plus a seven-day run count. No persona text, no secrets. | To let an assistant see what is already automating replies before it suggests automating more of them. |
crm://webhooks | Outbound webhook endpoints with subscribed event types, active flag and recent delivery health. Signing secrets are never included. | To start a webhook investigation, in place of crm_list_webhooks. Reach for the deliveries tool only once you know which endpoint is suspect. |
crm://deals/open | Open deals that are neither won nor lost, ordered by value, with stage, win probability and expected close date. | For forecasting, in place of crm_list_deals. Value ordering and probability in one read is most of a weighted forecast. |
crm://social/accounts | Every connected social account with handle, timezone and daily post limit. | Before scheduling anything, in place of crm_list_social_accounts. Timezone and daily limit are exactly what a scheduling decision needs. |
crm://social/inbox | Unread totals per network plus the 20 most recently active social DM conversations with participant, preview and unread count. | To open a social triage turn. One read replaces a summary call plus a conversation list call. |
crm://social/posts/scheduled | Posts queued to go out, soonest first, with network, scheduled time and a content preview. | For content planning, in place of crm_list_social_posts filtered to pending. It is the upcoming calendar with nothing else in the way. |
crm://social/posts/published | The most recently published posts with their live URLs, plus anything that failed and why. | For a publishing retrospective, and for catching a failed post you would otherwise notice a week later. |
A pattern worth copying: pick the three resources that match the assistant you are building and load them at the start of every session. A sales assistant wants crm://deals/open, crm://tasks/today and crm://recent-conversations. A social manager wants crm://social/inbox, crm://social/accounts and crm://social/posts/scheduled. An operator on call wants crm://jobs/recent, crm://webhooks and crm://agents. Three reads, and the assistant is oriented.
Notice which resources are narrower than their tool equivalents rather than wider. crm://tasks/overdue is strictly past due; crm://tasks/today also includes what is due later today. Reading both is redundant, and asking for the wrong one produces an answer that is technically correct and practically useless. Pick by the question: what has slipped, or what is on the plate.
The 15 prompts, and what each one is for
A prompt is a named, parameterized template that the server publishes and the client presents to a person, usually as a slash command or a menu item. The server supplies the wording and pulls the relevant CRM data into it; you supply whichever argument the template needs, if it needs one at all. Most of the fifteen take no argument, because they operate over the whole workspace; the rest need you to name one contact, one deal, one email thread, one conversation or one connected account.
Prompts are worth more than they look. The wording of a recurring analysis request is the part people get wrong and then never revisit, so a prompt that already asks for a weighted forecast and the three deals most at risk produces better output than the version you would type at nine on a Monday. It is also consistent week to week, which is the only way a recurring report becomes comparable.
The argument column below describes what each prompt needs rather than the literal field name, because the exact argument names come back from a prompts/list call and any client that supports prompts will show them when you pick one. Two prompts are explicit about their own limits: summarize-email-thread does not draft or send a reply at all, and dm-reply-draft drafts but never sends.
{"jsonrpc":"2.0","id":4,"method":"prompts/list"}
{"jsonrpc":"2.0","id":5,"method":"prompts/get",
"params":{"name":"daily-briefing"}}| Prompt | What it produces | Needs | Where it earns its place |
|---|---|---|---|
summarize-contact | A summary of the relationship with one contact plus a concrete proposed next step. It pulls the last ten messages exchanged. | The contact you are asking about. | Two minutes before a call with someone you last spoke to in April and cannot remember why the conversation stopped. |
draft-followup-message | A Telegram follow-up written for the contact’s current pipeline stage and their recent conversation, with an optional tone selector. | The contact, and optionally the tone you want. | Clearing a follow-up list where each message has to reference something specific rather than reading like a template. |
daily-briefing | A morning standup digest built from today’s queued, sent and failed jobs together with the contact pipeline. | Nothing. It reads the workspace as it stands. | The first message you send your assistant every morning, ideally saved as a one-click prompt in your client. |
audit-account-health | A risk assessment of one connected account from seven days of job statistics: rate-limit pressure, error spikes and similar warning signs. | The connected account to audit. | A Telegram account has started failing sends and you want to know whether you are being throttled before you send more. |
weekly-finance-report | A weekly finance report from the last seven days of realized income and expense, grouped per currency. | Nothing. | A recurring Friday report for a business that invoices in more than one currency and does not want to reconcile by hand. |
deal-next-step | The single best next action for one deal, reasoned from its stage, value, probability and open tasks. | The deal in question. | A deal that has been in negotiation for three weeks and you cannot decide between another call, a discount or walking away. |
summarize-email-thread | A summary of one email thread, the customer’s open question and one recommended next action. It does not draft or send a reply. | The email thread. | Inheriting a forty-message support thread from a colleague and needing the actual unanswered question inside a minute. |
triage-inbox | A ranking of who to reply to first and why, built from the most recently active contacts with unread threads first. | Nothing. | Coming back from two days off to an inbox where everything looks equally urgent and nothing is. |
pipeline-review | A weighted forecast from open deals grouped by stage with value and probability, plus the three deals most at risk. | Nothing. | The Monday pipeline meeting, where the useful output is the at-risk list rather than the total. |
task-prioritize | One prioritized action list for today, built from overdue tasks plus everything due in the next 48 hours. | Nothing. | A task list that has grown past the point where due-date sorting is enough to tell you what to do first. |
outreach-plan | Next week’s outreach focus from active sequences and their target progress, with one improvement per under-performing sequence. | Nothing. | Planning campaign effort for the coming week when three sequences are running and only one is working. |
lost-deal-postmortem | A likely root cause for one lost deal and a concrete re-engagement play, reasoned from the deal data and its task history. | The lost deal. | A quarterly review of closed-lost deals, where the point is finding the pattern rather than relitigating one loss. |
social-inbox-triage | A ranking of which social DMs to answer first and why, across every connected network. | Nothing. | A brand account collecting messages on Instagram, WhatsApp and LinkedIn at once with one person answering all three. |
weekly-content-plan | A concrete posting plan for the coming week, combining connected accounts, what is already scheduled and how the last 30 days of posting performed. | Nothing. | Monday content planning where the hard part is remembering what already went out and which network you neglected. |
dm-reply-draft | A reply to one social DM thread using the real history, the participant’s language and the platform’s length conventions. It drafts only, never sends. | The social conversation to reply in. | Answering a customer who wrote in a language you read slowly, where getting the register right matters as much as the facts. |
Four of the fifteen are worth setting up as recurring habits rather than occasional requests: daily-briefing every morning, task-prioritize right after it, pipeline-review before your weekly sales meeting, and weekly-finance-report on Friday. Those four alone cover most of what people build custom dashboards for, and unlike a dashboard they explain the numbers.
The remaining eleven are situational, and the situations are specific. You reach for audit-account-health when sends start failing, for lost-deal-postmortem during a quarterly review, for summarize-contact two minutes before a call. That is the mark of a well-scoped prompt library: each entry has an obvious moment rather than being a general-purpose ask with a different name.
Read, write, and where the write tools stop
Of the 142 tools, 78 are annotated read-only and 64 are annotated as writes, and the write set deliberately stops short of irreversible money and identity actions. That boundary is a design decision rather than an implementation gap, and it is the part of this server most worth understanding before you decide how much access to grant.
Here is what the write tools will not do, stated as flatly as possible. They will not create a ledger transaction. They will not pay, send, void or create an invoice, and no tool returns a payment link. They will not move a deal to won, because winning a deal books revenue. They will not create a deal that is already closed. They will not send email, even from the two tools that manage email threads. And crm_run_agent drafts a reply and never delivers it, no matter how the request was phrased.
The reasoning behind each of those is the same: the action either moves money or reaches a person in a way that cannot be taken back, and the cost of an assistant getting it wrong is not proportionate to the convenience of it getting it right. Booking revenue from a chat window because a conversation sounded positive is a bad trade even when the assistant is right nine times out of ten.
There is exactly one hard delete in the catalogue. crm_delete_webhook permanently removes an endpoint, stops every future delivery to it, and cannot be undone. It is annotated destructive so a client that asks for confirmation before dangerous operations will ask before this one. Everything else in the write set is either additive or reversible from the panel.
Three write tools reach a human being directly: crm_send_telegram_message, crm_send_twitter_dm and crm_send_social_message. A fourth reaches an audience: crm_schedule_social_post publishes immediately when publishNow is set. Those four are the ones to think hardest about, and they are spread across four separate scopes precisely so you can grant one without granting the rest.
Several write tools are idempotent, which matters more for AI agents than for human-driven code because agents retry. Pausing a paused sequence is a no-op. Marking an already-read conversation read changes nothing. Cancelling an already-cancelled post is a no-op. Creating a tag that exists returns the existing tag rather than a duplicate. Tagging and untagging are both idempotent. That set of guarantees is what makes a retrying agent safe to run against them.
One write tool has a side effect worth knowing about in advance. crm_add_contact_note appends to a field that holds 500 characters, and when it fills up the oldest text is dropped from the front. It is a rolling scratchpad, not an archive. Durable facts belong in tags, lead score, a deal or a task, all of which have their own tools and none of which overwrite anything.
A useful way to think about the whole boundary: the MCP surface can do everything that a competent assistant could reasonably do on your behalf during a working day, and none of the things you would want a second person to confirm. If you disagree with where that line sits, the scopes are the adjustment mechanism, and the next section is how to plan them.
Rate limits, batching and getting a lot done in 60 requests
Rate limiting is per API key: 60 requests per minute by default, with a ceiling of 300 on the Business plan. Going over returns HTTP 429 with a Retry-After header saying how long to wait. Every tool call is one request, every resource read is one request, and the protocol handshake costs a request too, so the budget disappears faster than people expect once an assistant starts working through a list.
The failure mode is worth picturing. You ask an assistant to review fifty contacts. A naive plan is one search call, then fifty crm_get_contact calls, then fifty crm_get_contact_activity calls. That is 101 requests for one question, and the assistant will be sitting in a 429 backoff halfway through while you watch a spinner. The same answer is usually available in three or four requests if you ask for it differently.
Four habits keep you comfortably inside the budget:
- Prefer a resource over repeated tool calls. One read of
crm://recent-conversationsreplaces a listing call plus several detail calls when all you needed was who is waiting. One read ofcrm://social/inboxreplaces a summary call plus a conversation listing. - Ask for one summary rather than fifty lookups. Requesting a ranked shortlist with reasons produces a plan that fits in a handful of calls. Requesting a per-record report invites the assistant to fetch every record. Phrase the request around the decision you want to make, not the data you think it needs.
- Use the tools that already aggregate.
crm_social_inbox_summaryreturns per-network totals plus the waiting threads in a single call.crm_dashboard_summaryreturns headline KPIs in one.crm_finance_summaryreturns net per currency plus top expense categories in one. These exist so an assistant does not have to reconstruct them from primitives. - Give long-running automation its own key. The limit is per key, so a scheduled nightly job and an interactive assistant on the same key compete for the same 60 requests. Two keys with different scopes and different limits is both safer and faster.
When you do hit a 429, honor Retry-After rather than retrying immediately. A retry loop that ignores it will keep failing and burn its budget on failures, which is how a one-minute pause turns into a five-minute one. Well-behaved MCP clients handle this for you, but an agent framework you wrote yourself probably does not unless you made it.
For genuinely high-volume work, MCP is the wrong tool and that is fine. A nightly export of every contact belongs on the REST API, where you control pagination and concurrency directly. MCP is optimized for an assistant asking a few well-chosen questions during a conversation, not for bulk extraction. The trade-offs are laid out in detail on MCP versus REST API versus Zapier.