Conduyt MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| CONDUYT_API_KEY | Yes | API key starting with cdy_ | |
| CONDUYT_API_URL | Yes | Base URL, https://conduyt.app | |
| CONDUYT_TIMEOUT_MS | No | Request timeout in milliseconds | |
| CONDUYT_MAX_RESPONSE_BYTES | No | Cap on the size of a tool result |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| conduyt_api_catalogA | Discover all Conduyt CRM API endpoints across 90+ domains, with full request and response schemas. Call this first to learn what the CRM can do — the response carries the exact, current endpoint counts. NOTE: the catalog is the full REST surface; not every endpoint has a dedicated MCP tool. Call conduyt_mcp_coverage to see exactly which endpoints are callable through MCP tools versus API-only. |
| conduyt_check_permissionsA | Check what the current API key can do — tier, scopes, rate limits, and usage stats. |
| conduyt_searchA | Global search across all CRM entities — contacts, deals, companies, tasks, plus notes, messages, activities and document text. Names, emails, phones and deal titles match from 2 characters; the text legs (note/message/activity/task bodies, message subjects, activity titles) need 3 or more and each runs under a 3-second budget — a leg cut at the budget is left out and the response says so ( |
| conduyt_mcp_coverageA | The REST-to-MCP coverage matrix: which of the catalog's API endpoints are callable through MCP tools (and by which tool), which are deliberately excluded (with reasons — e.g. interactive-only auth/billing, inbound webhook receivers, realtime browser surfaces), and which are planned but not yet wrapped. Use this to know up front whether a capability you discovered in conduyt_api_catalog is executable here, instead of failing mid-task. Ships with the package and matches this release's tools exactly. |
| conduyt_list_contactsB | List and search contacts with filtering. Returns paginated results with name, email, phone, tags, source, and assignee. |
| conduyt_get_contactB | Get a single contact with full details — profile, tags, custom fields, timeline, deals, and activity history. |
| conduyt_create_contactB | Create a new contact in the CRM. Email or phone is recommended but not strictly required. |
| conduyt_update_contactB | Update an existing contact's fields — name, email, phone, company, custom fields. customFields merge into existing values (omit a key to leave it unchanged). |
| conduyt_delete_contactA | Delete a contact by UUID (soft-delete — the contact is removed from lists/searches but the row is retained for audit, and its deals are unaffected). Use this to clean up test or duplicate contacts. There is no undelete endpoint, so treat it as irreversible via the API. |
| conduyt_add_tagsA | Add one or more existing tags to a contact by tag UUID. Tags must already exist (create them with conduyt_create_tag); this does NOT create tags. |
| conduyt_link_contact_to_dealA | Associate an existing contact with an existing deal (creates a deal↔contact link). A deal's primary contact is set at create time via contactId; use this to attach ADDITIONAL contacts (e.g. a decision-maker plus an influencer) to the same deal. Both must already exist and belong to your account. |
| conduyt_verify_line_typeA | Verify contacts' phone LINE TYPE (mobile/landline/VoIP) + carrier + validity via the tenant's own Twilio Lookup, stamping the results on each contact (Phone Verification custom fields). OPT-IN + TENANT-PAID (~$0.008/number on their Twilio): requires the account's lineTypeVerificationEnabled Twilio setting, configured Twilio credentials, and org-wide contact access (owner/admin/view_all). BATCHED + idempotent: each call verifies up to 50 not-yet-stamped contacts and returns { verified, remaining, done, byLineType } — CALL REPEATEDLY until done=true. Provide exactly ONE scope: smartListId or contactIds. |
| conduyt_list_dealsA | List deals with filtering by pipeline, stage, assignee, or status. Returns deal title, value, stage, contact, and dates. Filter by pipeline/stage NAME (the same names you import with) or by UUID — both camelCase (pipelineName) and snake_case (pipeline_name) argument names are accepted. An unknown name returns a clear error, never the whole account. |
| conduyt_get_dealA | Get a single deal with full details — value, currency, probability, stage, contact, expected close date, custom-field values, activities, tasks, and history. Use this to read structured custom-field data back out of a deal (e.g. for a P&L or balance-sheet model). |
| conduyt_create_dealA | Create a new deal in a pipeline with full attributes. Requires a pipeline and stage ID — use conduyt_list_pipelines to discover them. Supports currency (e.g. GBP), probability, priority, expected close date, and structured custom-field values. |
| conduyt_update_dealA | Update a deal — move stage, change value/currency, set probability or expected close date, reassign, mark won/lost, or write structured custom-field values. customFields are merged into existing values (omit a key to leave it unchanged). |
| conduyt_delete_dealA | Delete a deal by UUID (soft-delete — the deal is removed from lists/boards and its value drops out of pipeline totals, but the row is retained for audit). Use this to clean up test or mistaken deals. There is no undelete endpoint, so treat it as irreversible via the API. |
| conduyt_import_dealsA | Bulk-import deals from a list of rows in one call. Runs on the canonical import engine — pipelines and stages are resolved by NAME (create them first with conduyt_create_pipeline), contacts by email. Deduplicates on title + pipeline + contact, and intentionally does NOT fire deal-created automations/webhooks/SMS/email (bulk imports are side-effect-free by design). Requires an owner/admin API key. Returns the created/skipped/duplicate counts and any per-row errors. |
| conduyt_add_deal_tagsA | Tag a deal with one or more EXISTING tags by tag UUID. Tags must already exist (create them with conduyt_create_tag); this does NOT create tags. Deals support tags just like contacts — use this to segment high-value or priority deals. To tag several deals, call this once per deal. |
| conduyt_list_deal_viewsA | List the account's SAVED DEAL VIEWS (saved deal segments, e.g. 'Open deals over $10k'), each with its id, name, stored filter rules, and current deal count. Read-only — shows how the account segments its deals. |
| conduyt_list_tasksC | List tasks with filtering by assignee, status, or due date. Returns task title, description, due date, priority, and assignee. |
| conduyt_create_taskB | Create a new task. Can be linked to a contact or deal and assigned to a team member. |
| conduyt_get_taskA | Get a single task by UUID with full details — title, description, due date, status, priority, and the linked assignee, creator, contact, and deal. |
| conduyt_update_taskA | Update an existing task's fields. Only the fields you provide are changed; omit a field to leave it as-is. To mark a task done, prefer conduyt_complete_task. Requires tasks:edit. |
| conduyt_complete_taskA | Mark a task done (the idiomatic 'complete' action). Sets status to 'done', which the server stamps with completedAt and dispatches task.completed automations/webhooks. Requires tasks:edit. |
| conduyt_delete_taskA | Delete a task by UUID (hard delete — the task row is removed and a task_deleted activity is logged for audit). There is no undelete endpoint, so treat it as irreversible via the API. Requires tasks:delete. |
| conduyt_list_pipelinesA | List all sales pipelines with their stages. Use this to discover pipeline and stage UUIDs before creating or moving deals. |
| conduyt_create_pipelineA | Create a new sales pipeline, optionally with its full set of stages in one call. If stages are omitted, default New/Won/Lost stages are created. There is no fixed limit on stage count — pass as many as your funnel needs (e.g. eight active stages plus 'On Hold' and 'Declined/Dead'). |
| conduyt_update_pipelineA | Update a pipeline's name, description, or default flag. To add/edit/remove stages, use the stage tools. |
| conduyt_delete_pipelineA | Delete a pipeline. Deals in the pipeline must be moved or removed first. Cannot delete the default or an archived pipeline. |
| conduyt_create_stageA | Add a new stage to an existing pipeline. The stage is appended after the current last stage. Use this to extend a funnel (e.g. add 'On Hold' or 'Declined/Dead'). |
| conduyt_update_stageB | Update a stage within a pipeline — rename, recolor, reorder (sortOrder), or change its won/lost/system flags. |
| conduyt_delete_stageA | Delete a stage from a pipeline. The stage must be empty (no deals) — move or reassign deals first. |
| conduyt_list_activitiesC | List recent activities across the CRM — calls, emails, notes, meetings, deal changes, and system events. |
| conduyt_create_activityB | Log a new activity — a call, meeting, note, or custom event. Can be linked to a contact. |
| conduyt_ai_insightsA | Query AI-powered CRM insights. 11 query types: report_catalog (every saved report and dashboard this key can run), saved_report (run any saved report by name or id: rows, total, metric, chart data, pivot; optionally windowed with filters.period or filters.dateRange, reps and sources, paged with page / perPage), dashboard (run every tile of a dashboard by name or id, its saved filters or the filters passed for this run), pipeline_health (deals per stage, stale deals), sms_drip_status (SMS drip overview by provider/step), sms_responses_untouched (replied contacts with no follow-up), agent_followups (per-agent task performance), email_performance (open/click/reply rates), smart_view_summary (contact counts per saved view), team_activity (per-user activity counts), contact_import_history (recent import batches). |
| conduyt_list_automationsB | List all automations (workflows) in the account. Returns name, trigger event, status, and execution counts. |
| conduyt_get_automationA | Get a single automation with full details — trigger, actions graph, schedule, and execution stats. |
| conduyt_create_automationA | Create a new automation. Requires a name and trigger event. Use conduyt_resolve_names to convert human-readable names to UUIDs before building actions. |
| conduyt_update_automationB | Update an existing automation — change trigger, actions, schedule, or activation status. |
| conduyt_publish_automationA | Publish an automation — copies the draft actions to the live published version. The automation must have actions defined. The publish is bound to the draft revision you reviewed (fetched automatically unless you pass expectedConfigRevision). |
| conduyt_resolve_namesA | Resolve human-readable names to UUIDs. Use this before creating automations — converts tag names, pipeline names, user names, and custom field labels to their UUIDs. |
| conduyt_list_sequencesB | List email sequences (drip campaigns). Returns name, step count, enrollment stats, and active status. |
| conduyt_get_sequenceA | Get a single email sequence with full details — steps, enrollment stats, and configuration. |
| conduyt_create_sequenceC | Create a new email sequence with steps. Each step has a delay and email content. |
| conduyt_enroll_in_sequenceA | Enroll one or more contacts into an email sequence. Skips contacts already enrolled. |
| conduyt_unenroll_from_sequenceB | Remove a contact from an email sequence. Pauses their enrollment. |
| conduyt_sms_transportsA | What a workflow Send SMS step can speak through TODAY (GET /api/v1/sms/transports): twilio {connected, numbers[] = the account number + every active rep's assigned line, each a valid send_sms config.fromNumber}, projectBlue {connected, lines[] = Project Blue iPhone lines held by active reps, each lineId a valid config.projectBlueLineId for smsMode project_blue}, whatsapp {connected, sender = the account's WhatsApp sender for smsMode whatsapp; templates come from conduyt_whatsapp_templates}, voiceDrop {connected = Twilio is connected, recordings {hasDefault, templates[] = names valid as config.voiceDropRecording for smsMode voice_drop}}, webhook {providers = active webhook providers for smsMode webhook}, fromk {status connected | setup, connected, lines[] = the FromK.ai workspace's send-ready lines, each phoneNumberId a valid config.fromkPhoneNumberId for smsMode fromk}. Use it before building or editing a send_sms step so you never configure a transport that is not connected. Requires automations:view. |
| conduyt_whatsapp_templatesA | The account's WhatsApp templates (Twilio Content) with Meta's approval verdict (GET /api/v1/sms/whatsapp/templates): sid (a send_sms step's whatsappTemplateSid / conduyt_send_sms whatsappContentSid), friendlyName, language, body (the approved text with {{1}}, {{2}} placeholders), variables (the placeholder numbers to fill), approval (approved | pending | rejected | paused | disabled | unsubmitted | unknown), rejectionReason, category; plus |
| conduyt_voice_dropA | Place a voice drop to a contact (POST /api/v1/calls/voice-drop): an outbound Twilio call with answering-machine detection that plays one of the account's Voicemail Drop recordings (Settings → Twilio → Voicemail Drop; names from conduyt_sms_transports voiceDrop.recordings) when a machine answers, and hangs up quietly when a person answers unless onHuman is play. Governed like a call: calls-tier consent (a texting STOP does not block it, a DNC or litigator row does), the account's calling hours, one live call per lead. Placed from your own Twilio line (else the account number) unless fromNumber names a number the account owns. Returns 202 with the Call row; the outcome lands on it through the voice webhooks (disposition voicemail_drop = played to a machine, voice_drop_human = a person answered, voice_drop_live = played to a person, voice_drop_fax; status no-answer/busy when nobody picked up). Refusals carry a code (dnc, litigator, calling_window, active_call, missing_phone, voice_drop_recording_missing, voice_drop_not_configured); 429 and 502 are safe to retry. Requires dialer:create. |
| conduyt_send_smsB | Send an SMS message to a contact. Contact must have a phone number and not have opted out. Max 1600 characters. |
| conduyt_send_emailB | Send a single email to a contact. Requires either HTML or plain text body. Subject line max 998 characters. |
| conduyt_get_conversationA | Read the full conversation thread for one contact — the chronological SMS/email message history (both inbound replies and outbound sends), plus conversation state, unread count, and recent notes. Use this to see what a contact has replied before deciding how to follow up. Requires communications:view. |
| conduyt_list_messagesA | List individual messages across contacts with filters — read inbound replies and outbound sends account-wide, or scoped to one contact. Newest first. Use direction='inbound' to surface replies that need a response. Requires communications:view. |
| conduyt_sms_delivery_reportA | SMS provider delivery-outcome report for external-workflow SMS drips: per-automation entered vs delivered / rejected (invalid, litigator, DNC) / provider-error / workflow dead-end, plus a send-attempt 'why rejected' reason breakdown (line_type = 'not mobile' often WRONGLY rejected; landline_skipped / no_phone_skipped = Conduyt's own recorded skips). Use to answer 'what did the SMS provider do with our drips?' |
| conduyt_sms_drip_conversion_reportA | Conversion by drip STEP for external-workflow SMS drips: for each text in each SMS-drip automation, how many contacts were texted and how many of them replied, booked an appointment, moved their deal forward (to a non-Lost stage) or won, credited last-touch inside the attribution window (the next text, from any drip, closes the window early). Per-step and per-automation rates. Spans clamp to 90 days. Response |
| conduyt_speed_to_lead_reportA | Speed to lead: for every contact created in the window, the time to the FIRST HUMAN touch (a call placed by a person, a text or email a person sent through a connected provider, a note, or a completed task, inside the CRM): median and p90 seconds, leads reached within 5/15 min and 1/4/24 h, never reached, first-touch channel; overall, by assigned rep, by lead source and by who made the touch. Automation messages, campaign blasts and anything done outside the CRM are not touches (the response |
| conduyt_attribution_reportA | Attribution: where the window's new contacts came from and what they turned into: the contacts created in the window grouped by their first or latest touch (UTM source, medium, campaign, content, term, the channel, the landing page or the referrer), each group followed to appointments booked, deals won and revenue so far. Touches are captured on forms, booking pages, inbound webhooks, imports and contact creation through the API (pass an |
| conduyt_agent_performance_reportA | Agent performance: every active rep's numbers for the window next to their targets and next to each other: calls, conversations, appointments booked, deals won, revenue, activities, talk minutes, each with the target prorated to the window (daily once per day, weekly per 7 days, monthly per 30.4375 days) and the attainment; a score per rep and a team row. userIds (up to 10) is the compare set. Spans clamp to 366 days; the definition comes back as |
| conduyt_list_targetsA | The account's per-user targets (userId, metric, period, value). Admins and owners read everyone's; anyone else reads their own. Metrics: calls, conversations, appointments, deals_won, revenue, activities, talk_minutes; periods: daily, weekly, monthly. |
| conduyt_set_targetsA | Set per-user targets in one call (admins and owners): one row per user, metric and period is replaced; value 0 removes it; every user must be an active member. Up to 200 targets. |
| conduyt_call_performance_reportA | Unified call report: every call in the window, whatever carried it (the in-app dialer over Twilio, click-to-call Twilio, Project Blue), with the dialer analytics' definitions: calls, inbound and outbound, answered (network completed with talk time), connected and conversations (from the saved disposition), talk time and average talk, voicemails, missed inbound, appointments set and sales closed; overall and by user, transport, direction, disposition, day and hour of the account's timezone. Spans clamp to 366 days; the definition comes back as |
| conduyt_appointment_reportA | Appointment report: every appointment whose time (basis=start, default) or booking (basis=booked) falls in the window: booked, by status (scheduled, confirmed, completed, cancelled, no-show), the outcome of the ones already in the past (held or no-show, show rate), cancellations, reschedules and upcoming; overall and by assigned user, by calendar or booking page, by lead source, by the channel it came in on (booking page, call disposition, created in Conduyt, calendar) and by day. Reschedules count moves by the attendee, by a person in Conduyt, or synced from a connected calendar. Spans clamp to 366 days; the definition comes back as |
| conduyt_funnel_reportA | Stage funnel for ONE pipeline: every deal that entered each stage in the window (created in it, or moved into it) and what happened to that presence so far (advanced to a later stage, lost, moved back, handed off to another pipeline, still there; the five add up to the entries), with the median days a settled stay lasted, plus the pipeline cohort (deals created in the window by where they sit now: won / lost / open). Built from recorded stage moves, never from where deals sit now. Windows clamp to 90 days. GET /api/v1/reports/funnel |
| conduyt_list_callsA | List call-history records (read-only) with filters — review past inbound/outbound calls, their status, duration, and disposition. Newest first. Returns metadata only by default (NO call transcripts, NO recording/voicemail URLs — only hasRecording/hasVoicemail/hasTranscript flags), so a routine list never pulls raw transcripts into context. To read a specific call's transcript, use conduyt_get_call. Requires dialer:view. |
| conduyt_get_callA | Get a single call record by UUID (read-only) — direction, status, duration, disposition, notes, transcript text (if any), and the linked contact/user. Recording/voicemail URLs are withheld; hasRecording/hasVoicemail flags indicate their presence. Requires dialer:view. |
| conduyt_get_post_call_insightA | The post-call copilot's read of a RECORDED call (read-only): the transcription ledger state (none | pending | processing | done | failed | skipped, with the error or skip reason) and the stored insight — summary, sentiment, key topics, the suggested disposition with its confidence, a suggested deal stage move (only ever to a stage of the deal's own pipeline), a suggested follow-up task, and what it was grounded on (the account's AI knowledge, the client's configured dispositions). Nothing is applied by the copilot: a rep, or an agent through conduyt_update_deal / conduyt_create_task, acts on it. Only calls the client chose to record are transcribed — the recording switch and consent greeting are the client's own settings. The insight is built by the transcription worker within about a minute of the recording; while it is still owed |
| conduyt_sync_local_presenceA | Sync the dialer's Local Presence number pool from the account's Twilio subaccount. IMPORTANT — sync only adopts numbers that meet ALL of: (1) the Twilio FriendlyName contains a standalone 'LP' (or 'LocalPres'), e.g. 'LP Miami 305'; (2) the number is voice-capable; (3) it is a US +1 E.164 number. The first 50 matches in sorted order become the pool; anything already in the pool that no longer matches is REMOVED. So buying a number is not enough — name it with the LP convention in Twilio first, then run this. Returns pool/added/removed/matched. Requires settings:edit. |
| conduyt_get_dialer_settingsA | Read the account's Smart Dialing policy: autoAdvanceEnabled + pauseSeconds + advanceOn ('disposition' = the next dial waits for a saved disposition, 'timer' = the pause starts when the call ends), openLeadOnDial (the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' = an area-code match from the number pool, the rep's own line when no pool exists; 'did' = always the rep's own line), and localPresenceConfigured (whether a number pool exists). |
| conduyt_update_dialer_settingsA | Change the account's Smart Dialing policy (admin: settings scope). Send only the fields to change: autoAdvanceEnabled, pauseSeconds (1-60), advanceOn ('disposition' | 'timer'), openLeadOnDial (true = the lead's record opens as each Smart Dialing call goes out), smartDialCallerId ('local_presence' | 'did'). Returns the policy as saved. |
| conduyt_get_call_recording_settingsA | Read the workspace's call recording policy for both kinds of line. twilio = the workspace's Twilio lines: always an object, with everything off when the workspace never set it. Needs a key whose creator may view settings; without it the tool answers with an error instead of a policy. iphone = the iPhone line's OWN policy (outbound only); null = none was written, and the iPhone line then follows the Twilio lines' policy without its inbound part. Each object is the policy as it is APPLIED: inbound, outbound, disclosure { enabled, on: 'inbound' | 'outbound' | 'both' } (whether a recording disclosure is played and on which calls), consentGreeting (what is said; empty = the default sentence) and enabled (the OLD name of the outbound switch: the same value as outbound). A workspace that never saved the new shape is read the way the server reads its old one: outbound recording with the disclosure on whenever a wording is set. The workspace is responsible for consent where it operates. |
| conduyt_update_call_recording_settingsA | Change the workspace's call recording policy (admin: settings scope). line: 'twilio' (default) or 'iphone'. Send only what changes; what is not sent stays as it is. inbound / outbound: record calls the team receives / makes. disclosureEnabled + disclosureOn ('inbound' | 'outbound' | 'both'): play a recording disclosure and on which calls (send both together). On the iPhone line the disclosure plays on outbound calls only: 'inbound' is refused and 'both' is saved as 'outbound'. consentGreeting: the sentence that is said (500 characters at most). enabled: the OLD name of the outbound switch, accepted for older callers and sent as outbound (when both are sent, outbound decides); nothing else changes with it. Read conduyt_get_call_recording_settings first. The workspace is responsible for consent where it operates. |
| conduyt_list_companiesB | List and search companies. Returns name, domain, industry, contact count, deal count, and total deal value. |
| conduyt_get_companyA | Get a single company with full details — contacts (up to 100), deals (up to 50), and aggregated deal value. |
| conduyt_create_companyC | Create a new company record with business details. |
| conduyt_update_companyC | Update a company's details — name, domain, industry, address, or any other field. |
| conduyt_list_tagsA | List all tags in the account with contact counts. Use this to discover tag names and IDs. |
| conduyt_create_tagB | Create a new tag. Rejects duplicates. |
| conduyt_update_tagC | Rename a tag or change its color. |
| conduyt_delete_tagB | Delete a tag. Removes the tag from all contacts. |
| conduyt_merge_tagsA | Merge two tags — moves all contacts from source tag to target tag, then deletes the source. Useful for deduplicating tags. |
| conduyt_list_calendarsB | List all calendars in the account with appointment counts. |
| conduyt_list_appointmentsC | List appointments with filtering by date range, calendar, contact, assignee, or status. |
| conduyt_get_appointmentA | Get a single appointment with full details — contact, assignee, booking page, and notes. |
| conduyt_create_appointmentB | Create a new appointment. Times must include timezone offset (e.g. '2026-05-01T10:00:00-07:00'). |
| conduyt_update_appointmentB | Update an appointment — reschedule, reassign, change status, or add notes. Sends cancellation email if status set to 'cancelled'. |
| conduyt_appointment_outcomeA | Record an appointment's outcome (completed, no_show, cancelled) in one action: sets the appointment status AND moves the contact's most recently updated open deal to the stage the account mapped for that outcome in Pipeline settings (appointmentOutcomeStages). Returns { appointment, stageMove, reason }; reason explains when nothing moved (no_contact, no_deal, no_mapping, already_there, stage_move_failed). |
| conduyt_appointment_outcome_undoA | Undo the last outcome recorded on an appointment: the status returns to what it was before, and the deal returns to the stage the outcome moved it from — only if it is still in the stage the outcome put it in (a stage changed by hand since is left alone; the answer says stageRestored and reason). |
| conduyt_list_formsB | List web forms with submission counts. Filter by active status or search by name. |
| conduyt_get_formB | Get a single form with fields, settings, and submission count. |
| conduyt_create_formB | Create a new web form. Generates a unique slug automatically if not provided. |
| conduyt_list_form_submissionsC | List submissions for a specific form with contact details. |
| conduyt_list_invoicesC | List invoices with filtering by status, contact, or date range. |
| conduyt_get_invoiceA | Get a single invoice with line items, payments, contact, and company details. |
| conduyt_create_invoiceB | Create a new invoice with line items. Automatically calculates subtotal, tax, and total. |
| conduyt_update_invoiceA | Update a draft invoice — change items, contact, due date, or terms. Cannot update paid or voided invoices. |
| conduyt_send_invoiceA | Send an invoice to the contact via email. Generates PDF, creates Stripe payment link, and sends via email. |
| conduyt_list_webhooksB | List all registered webhooks with their events, status, and failure counts. |
| conduyt_create_webhookA | Register a new webhook endpoint. Returns the signing secret once — store it securely. Events: contact.created/updated/deleted, contact.tag_added/removed, deal.created/updated/stage_changed/won/lost/deleted, company.created/updated/deleted, message.sent/received, appointment.created/updated/cancelled, campaign.completed. |
| conduyt_update_webhookA | Update a webhook — change URL, events, or enable/disable. Reactivating resets the failure count. |
| conduyt_delete_webhookC | Delete a webhook endpoint. |
| conduyt_cancel_webhook_logA | Cancel ONE parked / queued / failed webhook log of a drip send whose outcome was unconfirmed (POST /api/v1/webhook-logs/{id}/cancel; admin or owner, the webhooks scope). Without a resolution the log is cancelled and the barrier STANDS (nothing is sent, the enrollment stays parked). resolution 'skip' assumes the step was delivered: the processor advances without sending. resolution 'resend' makes the processor rebuild and send the step AGAIN (a possible duplicate SMS): it is refused unless acknowledgeDuplicateRisk is true. Answers 404 (no such log), 409 webhook_log_in_flight (a request is in flight right now: retry in a minute), 409 webhook_log_not_cancellable (already cancelled / succeeded) or 409 step_already_sent (the step already carries sent evidence: a resend would only advance it, use 'skip'). The response carries resolution, resendScheduled, advanceScheduled, handedBack, markersResolved and barrierStanding. |
| conduyt_list_notificationsA | List notifications for the current user (determined by API key's associated user). |
| conduyt_create_notificationB | Send an in-app notification to a team member. Optionally triggers a web push notification. |
| conduyt_list_custom_fieldsB | List custom field definitions. Filter by entity type (contact, deal, or company) to see available fields. |
| conduyt_create_custom_fieldB | Create a new custom field definition for contacts, deals, or companies. Field types: text, number, date, select, multiselect, boolean. |
| conduyt_update_custom_fieldA | Update a custom field's label, options, or required status. Cannot change the field key or entity type. |
| conduyt_delete_custom_fieldB | Delete a custom field definition. Removes the field from all entities. |
| conduyt_get_contact_table_defaultsA | Read the account-level DEFAULT COLUMNS for the Contacts list: the column ids every user gets merged into their own layout on their next visit (each version once; users can rearrange afterwards). null = no account default (users see the built-in layout). Reads /api/v1/settings (settings:view). |
| conduyt_set_contact_table_defaultsA | Set the account-level DEFAULT COLUMNS for the Contacts list (settings:edit). Every user's saved layout gains the columns it lacks on their next visit (appended; nothing they already show moves); at most 8 ids; custom fields as 'custom:' (the key must exist). The write is revision-fenced: by default the tool reads the current row and names its |
| conduyt_list_smart_listsA | List all smart lists (segments) with contact counts. |
| conduyt_get_smart_listA | Get a single smart list with contact count and filter definitions. |
| conduyt_create_smart_listB | Create a new smart list (segment). Static lists have manually added contacts; dynamic lists use filter rules. |
| conduyt_update_smart_listC | Update a smart list's name, description, type, or filters. |
| conduyt_add_contacts_to_smart_listC | Add contacts to a static smart list. Max 500 contacts per request. |
| conduyt_get_smart_list_contactsA | Get contacts in a smart list. For static lists, returns the members; for dynamic lists, runs the filter query. |
| conduyt_list_usersA | List team members with optional performance stats. Returns name, email, role, status, and last login. |
| conduyt_get_userA | Get a single team member with full profile — name, email, phone, role, permissions, and activity. |
| conduyt_create_userA | Create a new team member directly (no invite email). Generates a random password. Use conduyt_invite_user for email-based onboarding. |
| conduyt_update_userA | Update a team member's profile, role, or permissions. Cannot modify your own role. To activate/deactivate a user, use conduyt_deactivate_user / conduyt_reactivate_user (status cannot be changed here). |
| conduyt_get_user_statsB | Get a team member's performance stats — contacts assigned, deals (total/won/value), tasks (total/completed/pending), and last activity. |
| conduyt_invite_userB | Invite a new team member via email. Sends an invite email with a link to set their password. |
| conduyt_deactivate_userA | Deactivate (soft-disable) a team member so they can no longer sign in. Optionally reassign their open records to another user. Requires the users:deactivate permission. |
| conduyt_reactivate_userA | Reactivate a previously deactivated team member, restoring their access. |
| conduyt_ai_import_contactsB | AI-powered bulk contact import. Accepts up to 1000 contacts with optional auto-tagging, smart list creation, and automation enrollment. Deduplicates by email, phone, or both. |
| conduyt_export_contactsB | Export contacts as JSON with filtering. Returns all matching contacts with tags and custom fields. |
| conduyt_export_dealsB | Export deals as JSON with filtering by status, pipeline, or search term. |
| conduyt_bulk_tag_contactsA | Add one tag to many contacts in a single call. Requires contacts:edit. |
| conduyt_bulk_untag_contactsA | Remove one tag from many contacts in a single call. Requires contacts:edit. |
| conduyt_bulk_edit_contactsA | Apply the SAME field changes to many contacts at once (one updates object → all ids). For different values per contact, use conduyt_bulk_update_contacts. Requires contacts:edit. |
| conduyt_bulk_update_contactsA | Apply DIFFERENT field changes per contact in one call (each row carries its own id + fields). For the same change across many, use conduyt_bulk_edit_contacts. Requires contacts:edit. |
| conduyt_bulk_delete_contactsB | Soft-delete many contacts in a single call. Requires contacts:delete. |
| conduyt_bulk_delete_contacts_matchingA | Soft-delete EVERY contact a list filter matches, across pages (#73, 2026-09-15) — the contacts page's "Select all N matching" action. FIRST CALL: pass the same filter you would give conduyt_list_contacts (search, tag, tags, source, reachability, company, company_id, assigned_to, created_from/to, updated_from/to, min_score, import_id, smart_view, smartListId, filters JSON, master_status, exclude_master_status, cf[key]) and expectedTotal = the meta.total that filter returned. The server re-counts and refuses when the set moved (409 expected_total_mismatch), refuses when some matching contacts are shared with you but not yours to delete (409 not_all_editable), then FREEZES the matching ids (max 50,000; 422 above) and deletes only those. Contacts with an upcoming appointment are kept (keptWithAppointments). If done=false the response carries remainingIds AND a signed continuation token: CALL AGAIN with ids = remainingIds and continuation = that token, verbatim (no filter, no expectedTotal) until done=true; busy=true means wait a moment first. The token is bound to you, this account and exactly those ids and expires after 2 hours (403 continuation_*); a continuation without it is refused. Empty filters are refused. Requires contacts:delete and an active subscription. |
| conduyt_bulk_dnc_contactsA | Add or remove a Do-Not-Contact / litigator mark for many contacts (compliance action). Requires the EXPLICIT 'dnc' API-key scope — an admin must grant it deliberately in Settings > API Keys (an unrestricted key does NOT imply it; without the scope this returns 403). Writes are also bound by contact-ownership rules for limited keys. To CHECK whether a number is already blocked, use conduyt_get_contact (dnc status) or the contacts dnc-status read. |
| conduyt_bulk_edit_dealsA | Apply the SAME field changes to many deals at once (one updates object → all ids) — e.g. reassign a set of deals to a user. For different values per deal, use conduyt_bulk_update_deals. Requires deals:edit. |
| conduyt_bulk_update_dealsA | Apply DIFFERENT field changes per deal in one call (each row carries its own id + fields). For the same change across many, use conduyt_bulk_edit_deals. Requires deals:edit. |
| conduyt_import_preflightA | Pre-check a contact import BEFORE running it — returns criticalWarnings (phone-less list bound for SMS, heavy create-only duplicate skips, double-mapped columns), duplicate/existing-match estimates, invalid emails, DNC/litigator hits, SMS-provider readiness, and plan-limit impact. Same engine the import wizard uses; call this before conduyt_ai_import_contacts on any sizeable list. |
| conduyt_create_batch_operationA | Queue a Run Batch: ONE task applied to many contacts, logged with progress and cancel (no undo). Tasks: enroll (automationId of a published workflow), delete (the #73 engine: cleanup runs, contacts with an upcoming appointment are kept), add_tag / remove_tag (params.tagId), assign (params.userId — one rep) or a round-robin pool (params.userIds, 2–50 reps rotated in order; a rep who is no longer an active member is skipped), set_source (params.source — OVERWRITES the lead source), set_status (params.status — one of the account's lead statuses; a lead with a won deal keeps its status). Pick the contacts ONE way: contactIds (up to 50,000), filterPayload (universal filters), or filter + expectedTotal — the same filter you would give conduyt_list_contacts plus the meta.total it returned; the server re-counts and refuses with 409 expected_total_mismatch when the set moved, then freezes the matching ids (max 50,000). The run is processed in the background; poll conduyt_get_batch_operation. Requires the admin or owner role and an active subscription. |
| conduyt_list_batch_operationsB | List Run Batch runs (newest first): task (operation + params with the display names), status (queued | running | completed | cancelled | failed), totals and progress, creator, comment. |
| conduyt_get_batch_operationC | One Run Batch run with its per-contact items: status per contact (pending | success | error | skipped) with the reason (e.g. 'kept: upcoming appointment', 'tag already applied', 'a lead a deal has won keeps its status'). |
| conduyt_cancel_batch_operationA | Stop a queued or running Run Batch. Contacts already processed stay as they are (there is no undo); claimed-but-unprocessed contacts go back to pending and are not touched. |
| conduyt_list_dncA | List active Do-Not-Call / litigator entries. Filter by search (phone or contact name) or tier. Requires the explicit 'dnc' API-key scope. |
| conduyt_add_dncA | Add a phone number (or a contact) to the Do-Not-Call or litigator list — e.g. "add this number to the do not call list". Phone entries block the NUMBER account-wide across dialer/SMS. Requires the explicit 'dnc' API-key scope; adding to the litigator tier is admin-only. |
| conduyt_remove_dncA | Remove (soft-delete) a Do-Not-Call / litigator entry by its entry id — unblocks the number/contact. Use conduyt_list_dnc to find the entry id first. Requires the explicit 'dnc' API-key scope. |
| conduyt_list_saved_filtersA | List YOUR saved contact filters (the web app's 'Saved' dropdown on All Contacts). Each entry has a name, the grouped filter payload, and sort. Saved filters are personal to the API key's user. Requires the 'saved-filters' scope. |
| conduyt_create_saved_filterA | Save a named contact filter for one-click re-use — e.g. "save a filter for Heather's Facebook leads". Since 2026-09-24 a saved filter IS a personal Smart View (the Smart Views tab), private to the key's user for every role (max 50 per user). Requires the 'saved-filters' scope. |
| conduyt_update_saved_filterA | Rename a saved filter (a personal Smart View) or replace its filters/sort. Owner-only — a personal view is its owner's for every role. Use conduyt_list_saved_filters or conduyt_list_smart_views to find the id. Requires the 'saved-filters' scope. |
| conduyt_delete_saved_filterA | Delete one of YOUR saved filters (a personal Smart View) by id. Owner-only. Requires the 'saved-filters' scope. |
| conduyt_list_drip_campaignsA | List SMS/email drip campaigns with enrollment counts and provider info. |
| conduyt_get_drip_campaignA | Get a single drip campaign with full details — steps, delays, send windows, and provider config. |
| conduyt_create_drip_campaignC | Create a new drip campaign with step delays, send windows, and provider configuration. |
| conduyt_update_drip_campaignB | Update a drip campaign — change name, schedule, provider, or activation status. |
| conduyt_list_drip_enrollmentsA | List drip campaign enrollments with contact and campaign details. Filter by campaign, contact, or status. |
| conduyt_batch_pause_enrollmentsC | Pause all active enrollments for a campaign or smart list. |
| conduyt_batch_resume_enrollmentsA | Resume paused enrollments for a campaign or smart list. |
| conduyt_batch_stop_enrollmentsA | Permanently stop enrollments for a campaign or smart list. Cannot be undone. |
| conduyt_cancel_drip_enrollment_barrierA | Cancel a drip enrollment's whole send barrier (POST /api/v1/drip-enrollments/{id}/cancel-barrier; admin or owner, the drip-enrollments scope): every parked / queued / failed webhook log of the enrollment is cancelled, including the case where no webhook log exists at all (the processor died after writing its marker). Without a resolution the barrier STANDS (nothing is sent). resolution 'skip' assumes the current step was delivered: the processor advances without sending. resolution 'resend' makes the processor rebuild and send the step AGAIN (a possible duplicate SMS): refused unless acknowledgeDuplicateRisk is true. Answers 404 (no such enrollment), 409 drip_send_in_flight (a request is in flight: retry in a minute) or 409 step_already_sent (the step already carries sent evidence: a resend would only advance it, use 'skip'). The response carries resolution, resendScheduled, advanceScheduled, logsCancelled, markersResolved, handedBack and barrierStanding. |
| conduyt_list_scoring_rulesC | List lead scoring rules. Each rule awards points when a condition matches a contact. |
| conduyt_create_scoring_ruleB | Create a lead scoring rule. Awards points to contacts matching a condition. |
| conduyt_update_scoring_ruleC | Update a scoring rule's name, points, condition, or active status. |
| conduyt_delete_scoring_ruleC | Delete a lead scoring rule. |
| conduyt_recalculate_scoresA | Recalculate lead scores for all contacts based on current scoring rules. Returns count of contacts processed and changed. |
| conduyt_list_productsB | List products in the catalog. Filter by active status or search by name. |
| conduyt_get_productA | Get a single product with full details — pricing, SKU, and metadata. |
| conduyt_create_productC | Create a new product in the catalog. |
| conduyt_update_productC | Update a product's name, price, description, or other details. |
| conduyt_list_templatesA | List email and SMS templates. Filter by channel (sms/email), category, or active status. |
| conduyt_get_templateA | Get a single email or SMS template with full content. |
| conduyt_create_templateC | Create a new email or SMS template. |
| conduyt_update_templateC | Update a template's content, subject, or category. |
| conduyt_dashboardB | Get a full CRM dashboard summary — pipeline stages with deal values, recent activities, contact/deal/task counts, admin metrics (overdue tasks, stale deals, unassigned items, team workload), billing summary, contacts needing follow-up, and overdue tasks. |
| conduyt_ai_compose_emailB | AI-powered email composition. Generates subject, body, and HTML based on contact context, deal stage, and desired tone. |
| conduyt_ai_enrich_contactC | AI-powered contact enrichment. Finds additional information about a person based on available details. Returns enriched fields like LinkedIn, Twitter, company, and job title. |
| conduyt_ai_summarize_contactA | AI-powered contact summary. Analyzes all interactions, deals, and activities to generate a summary with sentiment, key topics, and recommended next steps. |
| conduyt_ai_chatB | Conversational AI assistant grounded in your CRM. Send a multi-turn message thread and optionally pin it to a record (contact/deal) so the assistant has live context. Returns the assistant's reply. |
| conduyt_ai_improve_emailB | Improve an email draft. Rewrites the body (and optionally the subject) for clarity, tone, and persuasiveness. Pass instructions to steer the rewrite. |
| conduyt_ai_deal_insightsB | AI analysis of a single deal. Returns risk signals, momentum, and recommended next actions based on the deal's stage, activity, and history. |
| conduyt_ai_conversation_intelligenceB | AI analysis of a recorded/transcribed call. Returns summary, sentiment, topics, objections, and follow-up suggestions for the conversation. |
| conduyt_ai_call_dispositionA | AI-suggested call disposition. For a RECORDED call the answer is the post-call copilot's grounded insight (summary, disposition with confidence, deal stage move, follow-up) once the transcription worker has built it — HTTP 202 with pending:true while it is still owed (poll again in a few seconds; a pending answer costs nothing). Otherwise (unrecorded call, or the worker gave up) a metadata classifier proposes a disposition from the call's details. Nothing is applied. Requires dialer:view. |
| conduyt_ai_agendaA | The copilot's Today agenda for a user: what is on their calendar today (tenant timezone), callbacks they promised, messages waiting for a reply, overdue and due-today tasks, untouched new leads, recent-call follow-ups and deals going quiet — every visibility and opt-out rule applied — with a short brief on top (composed by the account's AI engine when available, otherwise a deterministic sentence built from the counts). Read-only. |
| conduyt_ai_plan_actionsA | Copilot actions — PLAN. Turn a natural-language request ('call Luis back tomorrow at 10', 'note on Ana: prefers texts', 'move the Roof deal to Proposal sent', 'draft a text to Ana about the quote') into a preview of concrete CRM actions resolved against records the caller can see (tasks, callbacks, notes, appointments, existing tags, deal stage moves, SMS/email DRAFTS). Nothing is written by this call. Returns the resolved actions (ready or with an issue such as an ambiguous name) and a single-use confirmationToken bound to that exact set; pass the actions array back UNMODIFIED with the token to conduyt_ai_execute_actions to apply. Drafts are never sent by the system. |
| conduyt_ai_execute_actionsA | Copilot actions — APPLY. Executes the ready actions from a conduyt_ai_plan_actions result through the same routes the UI uses (permissions, tenant scope, visibility, audit all apply). Send the plan's |
| conduyt_reply_suggestionA | Copilot Tier 2 — the suggested reply for a contact's LATEST inbound text or email (what they said, what they are asking, sentiment, and a draft reply shaped for the channel). Advice only: nothing is sent by this tool. state: ready | pending (the copilot has not read it yet) | none | decided | skipped (opt-out, do-not-contact, feature off). |
| conduyt_reply_suggestion_decideA | Copilot Tier 2 — record what was done with a suggested reply: accepted (the draft was taken into a composer), sent (with the outbound message id, after sending it through conduyt_send_message / the messages API), or dismissed. A suggestion moves once (accepted → sent is allowed). |
| conduyt_ai_daily_briefA | AI-generated daily brief for the current user. Summarizes today's priorities — deals needing attention, overdue tasks, hot leads, and recommended focus. |
| conduyt_ai_next_actionsB | AI-ranked next actions. Returns a prioritized list of suggested actions (replies to send, deals to advance, tasks to do) for a user. |
| conduyt_ai_feedC | AI activity feed — a chronological stream of AI-surfaced events and insights across the account. |
| conduyt_ai_usageA | AI usage and budget report for the account. Returns request counts and budget consumption over a rolling window. Requires an owner/admin API key — other roles get 403. |
| conduyt_ai_task_import_and_enrollA | AI task (PREVIEW ONLY): preview bulk-importing contacts and optionally tagging them, enrolling them in an automation, and adding them to a smart list. Returns what WOULD happen — counts, matches, and warnings — without persisting anything. Executing this is intentionally restricted to a human session in the app; agent/API-key callers can only preview. |
| conduyt_ai_task_segment_and_actA | AI task (PREVIEW ONLY): preview segmenting contacts by a filter and applying one action (add/remove a tag, assign to a user, or update a field) to the whole segment. Returns the matched count and what WOULD change, without persisting. Executing this is intentionally restricted to a human session in the app; agent/API-key callers can only preview. |
| conduyt_ai_task_pipeline_cleanupA | AI task (PREVIEW ONLY): preview finding stale deals in a pipeline and tagging, moving, notifying, or reporting on them. Returns the stale deals and what WOULD happen, without persisting. Executing a mutating action is intentionally restricted to a human session in the app; agent/API-key callers can only preview. |
| conduyt_workflow_validateA | Validate a workflow graph WITHOUT saving it. Returns errors and warnings so you can fix issues before creating or publishing. Always call this before conduyt_workflow_promote. |
| conduyt_workflow_simulateA | Dry-run a saved automation against a real or stub contact. Returns a step-by-step trace of what WOULD happen — no messages sent, no tags applied, no side effects. Checks compliance (DNC, opt-outs), provider readiness (SMS/email configured), and condition evaluation. Use this to verify a workflow does what you expect before publishing. |
| conduyt_workflow_promoteA | Safely publish a workflow. First validates the current graph — if there are errors, returns them and refuses to publish. If validation passes, publishes the draft to live. This is the recommended way to go live — it prevents broken workflows from reaching contacts. |
| conduyt_export_contact_dataA | GDPR data-portability export: returns the full portable JSON of everything held about a contact — profile, custom fields, tags, messages, notes, deals, activities, calls, appointments, files, and consent/suppression records. Read-only. Requires an owner or admin API key (the API enforces this). |
| conduyt_forget_contactA | IRREVERSIBLE GDPR right-to-be-forgotten erasure: permanently anonymizes the contact and erases their personal data EVERYWHERE it appears — messages, notes, deals, files, automations, and exports — across the whole account. Suppression/consent tombstones are kept so they are not re-contacted. THERE IS NO UNDO. Requires an owner API key (the API enforces this) and an explicit confirm='FORGET'. On a large tenant this can legitimately take tens of seconds. A 409 is retryable (a concurrent merge or in-flight automation) — retry once. |
| conduyt_list_smart_viewsA | List the account's Smart Views in sidebar order with their lead counts, audience (groupId + group name, members, isPersonal) and Smart Dialing settings (dialEnabled = it is a dialing priority; sortPosition = its rank; maxDialAttempts, maxDialAttemptsPerDay, dialCooldownMinutes, dialSchedule). Use it to answer "what does the team dial first?" or before changing a priority. |
| conduyt_update_smart_view_dialingA | Change one Smart View's Smart Dialing settings (admin key): make it a priority or not, the lifetime attempt cap, the per-day cap (null = no daily cap, counted in the account timezone), the cooldown between calls to the same lead, the shared pool and when a pool lead is assigned, and the retry schedule. Only the fields you pass change. Use conduyt_reorder_smart_views to change WHICH priority it is. |
| conduyt_get_smart_dialing_orderA | The Smart Dialing PRIORITIES, uncapped: every dial-enabled, account-wide contact Smart View in dial order (exactly the set the queue walks; personal views and deal views are never priorities) plus the candidates that could become one. Prefer this over conduyt_list_smart_views (capped at 100) before changing the priority order. |
| conduyt_set_smart_dialing_orderA | Set the Smart Dialing PRIORITY order (admin key): pass the dial-enabled Smart View ids in the wanted order — every dial-enabled view exactly once, nothing else. The server rebuilds the account-wide view order so views that are not priorities keep their slots. Prefer this over conduyt_reorder_smart_views for dialing. |
| conduyt_set_smart_view_audienceA | Who a SHARED Smart View is for (admin key): everyone on the account, one Team group (its CURRENT members, resolved when the view is read, so a rep added to the group later sees it and dials from it), or picked reps. A group replaces picked reps and vice versa. Personal views (a rep's own) have no audience. |
| conduyt_reorder_smart_viewsA | Set the SIDEBAR order of Smart Views (admin key). Pass EVERY view id from conduyt_list_smart_views in the wanted order (max 200, no duplicates) — views you leave out keep a stale position, so always send the full list. For the dialing priority use conduyt_set_smart_dialing_order, which only needs the dial-enabled ids. |
| conduyt_move_smart_viewA | Move ONE Smart View next to another in the sidebar order (admin key): pass the moved view's id and exactly one anchor, beforeId (it lands directly above that view) or afterId (directly below). Every other view keeps its relative position; no size limit, so use this on accounts with more than 200 views (conduyt_reorder_smart_views is capped at 200 ids). The order is the Smart Dialing priority for dial-enabled views. |
| conduyt_scheduled_export_get_settingsA | Get the account's scheduled-export configuration (enabled, frequency, entities) and whether the Enterprise feature is available on the current plan. |
| conduyt_scheduled_export_update_settingsA | Update scheduled-export settings. Enabling requires an Enterprise plan (403 upsell otherwise). Omitted fields keep their current values. Weekly exports run on Mondays; all exports run in the morning of the account timezone and files are kept 14 days. |
| conduyt_account_exports_listA | List recent scheduled account-export runs with per-file metadata (rows, truncation, size, expiry) and authed downloadPath for each completed file. Requires the explicit 'account-exports' API-key scope. Download the CSV bytes via the API or CLI using downloadPath — not through MCP. |
| conduyt_get_lifecycle_settingsA | Read the account's Lifecycle configuration (v2 + v3), shaped for read-before-write: dealWorkingMode and lostPropagation say how the tenant works leads and whether lost propagation is live; masterStatuses.effective is the full list a contact's masterStatus may take (the five built-in defaults plus the account's customs — the raw settings key stores only the customs); intakeDeals is the automatic deal-on-intake config, or null with an intakeDealsNote explaining that null can mean either not-configured or not-visible-to-your-key (the setting is admin-visible; member-tier responses omit it). |
| conduyt_update_intake_dealsA | Configure automatic deal creation on LIVE intake (inbound webhook contact upserts, public form submissions, public bookings). When enabled, each ELIGIBLE intake event mints a deal in the chosen pipeline/stage stamped with the trigger's own source. Exclusions that apply even under reInbound 'always': bulk imports never mint, staff/calendar/dialer-created appointments never mint, an exact replay of the same occurrence never mints twice, a same-source event for the same contact+pipeline within 10 minutes is treated as a delivery retry and skipped, and a contact whose masterStatus is terminal (won/lost/abandoned/disqualified) gets no new intake deals. reInbound governs contacts that already exist: 'if_no_open' (default, recommended) also skips when the contact already has an open deal in that pipeline; 'never' mints only for brand-new contacts. Requires settings:edit. |
| conduyt_update_deal_working_modeA | Set how this tenant works leads (Lifecycle v3). 'pipeline': every inbound contact gets a deal card in the intake pipeline — requires intakeDeals enabled with a pipelineId and stageId (conduyt_update_intake_deals first), and a new form/webhook/line cannot go live without a pipeline. 'status': the contact is the opportunity, no automatic cards (small shops). Switchable later; new tenants default to 'pipeline'. |
| conduyt_update_lost_propagationA | Turn LOST propagation on or off for this tenant (Lifecycle v3 P2). When on: a contact's masterStatus flips to 'lost' within a minute of its LAST open deal card closing lost (a per-minute resolver applies the rule on the committed state) (carrying that card's lostReason into masterStatusReason), a new open card on a lost/abandoned/disqualified contact reopens it, and a won contact never flips. Forward-only from the first enable (enabledAt is stamped server-side): existing history never flips by itself. A terminal masterStatus silences every drip, sequence and playbook for that contact, so read the nightly shadow report first (job run 'lost-propagation-shadow': contacts that would flip, their reasons, and the automations that would go quiet) before enabling. |
| conduyt_update_disposition_status_mapA | Set which lead status each call disposition sets when it is picked (by a rep after a call or by the AI auto-disposition): e.g. {"not-interested": "lost", "sale-closed": "won", "interested": "working"}. Keys are disposition values (built-ins like interested, not-interested, callback-requested, appointment-set, sale-closed, dnc-requested, voicemail, no-answer, wrong-number, or the account's custom outcomes); values are master statuses (open, won, lost, abandoned, disqualified, or the account's customs from conduyt_update_master_statuses). The map REPLACES the stored map (send the full map; {} clears every mapping); the rest of the account's disposition settings are untouched. An unknown disposition or status is a 422. A lead a deal has WON is never moved by an outcome; mapping to a terminal status (won/lost/abandoned/disqualified) closes the lead and stops its automations. Read the current map with conduyt_get_lifecycle_settings (dispositionStatusMap). |
| conduyt_get_agent_statusesA | Read the account's curated dialer agent statuses (2026-09-15): Available, Break, Lunch, Meeting, Training, Offline. Each carries a FIXED basis the dialer runs on (available = takes inbound calls and Smart Dialing hand-outs; break = signed in, not ringable; offline = signed out), the tenant's label, and whether the tenant hid it from the softphone menu. Admins rename or hide with conduyt_update_agent_statuses; Available and Offline can never be hidden. Reports bucket by basis; heartbeats and status logs also carry the chosen code (statusCode). |
| conduyt_update_agent_statusesA | Rename or hide the curated dialer statuses (settings.agentStatuses). labels: code → the label reps see (1–24 chars; omit a code or pass an empty string to restore the default); hidden: the codes removed from the softphone menu (available and offline are refused with a 422; a rep already on a hidden status keeps it until they change). Codes: available, break, lunch, meeting, training, offline. Fields you omit keep their stored value (the tool reads the current settings first); two visible statuses cannot share a label (422). Requires settings:edit. |
| conduyt_update_master_statusesA | Set the account's custom lead lifecycle statuses. The five defaults (open, won, lost, abandoned, disqualified) always exist and cannot be removed; this REPLACES the custom list on top of them (max 20 names, 1-40 chars each, letters/numbers/spaces/-/_ only). Terminal statuses stop all outbound automation for a contact. Requires settings:edit. |
| conduyt_list_pool_filter_setsA | The named filter sets behind the gear on Up for Grabs or Lead Pool (admin only): each set's name, Advanced Filters payload, enabled flag and order, plus the page's current pageVersion — every write must name it, so LIST FIRST. The page shows the UNION of the enabled sets; a page with an enabled rule-less set — or no set once the legacy filter is retired — is OPEN to every unassigned lead. |
| conduyt_create_pool_filter_setA | Add a named filter set to a pool page (admin only). A new set is a DRAFT (off) unless isEnabled is true. Enabling a set that would OPEN the whole page (no rule) is refused with 409 pool_opens unless acknowledgeOpensPool is true. Every tag name a rule carries must be a live tag (422 tag_missing); a custom field must exist (422 custom_field_missing). pageVersion is the one your list read answered (409 page_version_stale when the page moved since: re-list and retry). |
| conduyt_update_pool_filter_setA | Rename, refilter, enable / disable or reorder a pool filter set (admin only). Pass only what changes. Switching a set on or changing its rules reconciles the open offers the page no longer shows; a change that OPENS the whole page needs acknowledgeOpensPool. pageVersion is the one your list read answered for the set's page (409 page_version_stale when the page moved since: re-list and retry). |
| conduyt_delete_pool_filter_setA | Remove a pool filter set (admin only). Removing the LAST enabled set once the legacy filter is retired OPENS the page to every unassigned lead: refused with 409 pool_opens unless acknowledgeOpensPool is true. pageVersion is the one your list read answered for the set's page. |
| conduyt_get_lead_pool_settingsA | Read the admin-curated lead pool behind Up for Grabs / Lead Pool (settings.poolFilter + poolClaimDailyLimit). When enabled, an unassigned lead is offered only if it matches EVERY configured criterion: tagIds (any of), sources (any of), minScore (lead score >=), maxScore (lead score <=; min = max keeps one exact score), createdWithinDays (added to the CRM in the past N days: the contact's creation time — import, webhook, form, API or by hand; a re-import into an existing contact does not make it new). An empty criterion is skipped; enabled with nothing configured reads as disabled. Claims are gated by the same rules. tags carries the resolved tag names; criteria is the plain-English line the Up for Grabs page shows. Requires the settings scope. |
| conduyt_update_lead_pool_settingsA | Change the admin-curated lead pool (Up for Grabs / Lead Pool). Pass only what changes; every other criterion keeps its stored value. Criteria are ANDed: enabled, tagIds (contact has ANY of these tags; [] = no tag rule), sources (lead source is ANY of these; [] = no source rule), minScore / maxScore (lead score floor / ceiling, 0..1000, null = none; the same value for both keeps one exact score, e.g. "lead quality 4"), createdWithinDays (only leads ADDED to the CRM in the past N days — creation time, a re-import of an existing contact is not new; 1..365, null = none), poolClaimDailyLimit (0..200 grabs per agent per day, 0 = no cap). Enabling with no criterion at all is refused (it would read as disabled). maxScore below minScore is refused. Sends the settings revision it read; a 409 (another save landed first) returns the current settings to re-derive from. Requires settings:edit. |
| conduyt_list_up_for_grabsA | The Up for Grabs queue as the rep-facing page shows it: open claim offers plus the implicit pool of unassigned leads the account's curated pool filter admits (highest lead score first, up to 200), each with a teaser (name, company, source, score, city/state; phone and email only for admin keys) and eligibleCount. poolFilter is the active curation (tags resolved to names) and criteria the plain-English line under the page header — empty when curation is off. Claim with POST /api/v1/up-for-grabs/{contactId}/claim. Requires the up-for-grabs scope on the key. |
| conduyt_reply_capture_getA | Get the account's reply-capture state: whether it is configured and live, the capture domain and reply address, DNS records for a pending setup, and provider health. health='checking' with a healthWarning means the provider is re-checking DNS — capture stays active. degraded=true means the provider can no longer receive on that domain and it must be removed and set up again. needsSupport=true means an operator must reconcile it first. cleanupPending=true means a previous removal did not finish at the provider — call conduyt_reply_capture_remove again to complete it. After a removal: draining=true (with drainEndsAt) means the drain window is open — a domain that was live at removal keeps receiving replies until it closes (one that was degraded has no such guarantee); parked=true means it is retired and inbound-inert. Either way that name is permanently unavailable — use suggestedDomain when setting up again. |
| conduyt_reply_capture_setupA | Start reply-capture setup: creates the receiving domain at the email provider and returns the DNS records to add. The domain MUST be a strict subdomain of the account's own verified sending domain (omit it to use the suggested 'reply.'); anything else is refused. Requires a verified sending domain first. After adding the DNS records, call conduyt_reply_capture_verify. A 409 means capture is already configured, a setup is already in progress, the previous one still needs operator reconciliation, or the requested name belongs to a retired (drained/parked) domain — retired names are permanently unavailable, so read suggestedDomain from conduyt_reply_capture_get (e.g. 'reply2.') instead of retrying the old name. |
| conduyt_reply_capture_verifyA | Check the pending reply-capture domain's DNS and promote it to live once the provider reports it verified with inbound receiving in place. Returns verified=false plus the current DNS record states while records are still propagating — that is expected, not an error; poll sparingly (DNS takes minutes, and this endpoint is budgeted per account). Promotion is what turns on inbound matching and the Reply-To on outgoing email. |
| conduyt_reply_capture_removeA | Remove reply capture. Outcome depends on the domain's state. LIVE with a provider-backed setup: it DRAINS — the capture Reply-To stops on new email immediately, but the address keeps receiving for 30 days (drainEndsAt in the response) so late replies to already-sent emails still reach the contact's timeline; after that it parks, and the name is permanently retired (no account can ever set it up again — resuming capture means a NEW subdomain, see suggestedDomain on conduyt_reply_capture_get). LIVE legacy row with no stored provider id: removed immediately with NO drain — reply threading stops at once and the response says providerCleanup='manual' (an operator finishes the provider side); the name stays reusable. DEGRADED: drain lifecycle and permanent retirement, but receiving was already broken, so do NOT promise the 30-day delivery window. PENDING setup, a domain the provider has already lost, or an interrupted-removal retry (cleanupPending): torn down immediately, the row is deleted, and the name stays reusable. Requires an explicit confirm='REMOVE'. Sending-domain removal stays blocked by every capture row except a released tombstone — pending/cleanup rows clear right here, but a draining/parked row keeps blocking until support releases it after the drain. |
| conduyt_list_call_flowsA | List call flows (IVR routing graphs) with their status (draft/published) and attached phone numbers. |
| conduyt_get_call_flowB | Get one call flow including its draft and published graphs. |
| conduyt_create_call_flowA | Create a call flow. Starts as a DRAFT — edit the graph, validate, then publish to make it live on its number. |
| conduyt_update_call_flowA | Update a call flow's DRAFT (name, number, graph). Published behavior does not change until the next publish. Replacing draftGraph REQUIRES expectedDraftRevision (the API 428s without it; a concurrent graph edit then 409s instead of being overwritten — the token is graph-specific, so live calls and publish never invalidate it). |
| conduyt_delete_call_flowA | Delete a call flow. A PUBLISHED flow refuses deletion (409) — call conduyt_unpublish_call_flow first. |
| conduyt_validate_call_flowA | Validate a call flow's draft graph WITHOUT publishing — returns structured problems (unreachable nodes, missing targets, etc.). |
| conduyt_publish_call_flowA | Publish a call flow's draft, making it live on its phone number. Refuses an invalid graph. expectedUpdatedAt is REQUIRED (the API returns 428 without it): read the flow first and pass its updatedAt — a concurrent edit then fails 409 instead of being published over. |
| conduyt_unpublish_call_flowA | Unpublish a call flow — its number stops executing the graph (falls back to default routing). |
| conduyt_simulate_call_flowA | Answer "if someone calls right now, who picks up?" — simulates the DRAFT graph against LIVE member availability (DIDs, on-call state). No side effects. |
| conduyt_call_flow_rosterA | Get the routing roster: members with DIDs and their live availability — the people call-flow and ring-group steps can ring. |
| conduyt_list_ring_groupsA | List ring groups (simultaneous/sequential ring sets over member DIDs) with their numbers and members. |
| conduyt_get_ring_groupC | Get one ring group. |
| conduyt_create_ring_groupB | Create a ring group on an account number. Without memberIds the group is created INACTIVE. |
| conduyt_update_ring_groupA | Update a ring group (name, number, members, strategy, ring time, active). Replacing memberIds REQUIRES expectedUpdatedAt (the API 428s without it); passing it on any update makes a concurrent edit 409 instead of being overwritten. |
| conduyt_delete_ring_groupA | Delete a ring group. Its number keeps ringing default routing afterwards. |
| conduyt_release_ring_group_numberA | Release a phone number from ring-group routing (DESTRUCTIVE). confirm must be the EXACT phone number repeated as a string. A number still referenced by an ACTIVE ring group cannot be released — delete or repoint that group first; force does NOT bypass it. force exists only for numbers whose Twilio ownership cannot be verified, and then a non-empty forceReason is required. |
| conduyt_list_call_flow_numbersA | The voice numbers this workspace owns in Twilio, each with what answers it in Conduyt today (claimedBy: call flow / ring group / main line) and whether its Twilio voice webhook is already wired to Conduyt. Use it to pick a free number for a flow. |
| conduyt_get_call_flow_wiringA | Twilio's truth for a call flow's number: the voice webhook Twilio has right now vs the inboundUrl Conduyt needs, and whether they match (wired). A published flow that is NOT wired does not receive calls. |
| conduyt_wire_call_flow_numberA | Point the flow's number's Twilio voice webhook at Conduyt (the same step publish performs; use it when publish reported wiring.error, or after changing the number in Twilio). Admin. Returns the resulting wiring state. |
| conduyt_release_call_flow_tombstoneA | Release a number still held by a deleted call flow's tombstone: restores the number's pre-Conduyt Twilio configuration (verified) and lets the tombstone go. Admin. 404 when no tombstone holds the number; 409 when Conduyt still answers it and no prior configuration is known. |
| conduyt_upload_call_flow_audioA | Upload a greeting recording (mp3, wav or m4a, up to 10 MB) for use in a greeting node's audioUrl. Pass the file as base64. Returns { url } — put it on the greeting node via conduyt_update_call_flow. |
| conduyt_list_call_flow_functionsA | List the account's call-flow function endpoints — the HTTPS endpoints a flow's "Call a function" step may invoke mid-call (settings scope). |
| conduyt_create_call_flow_functionA | Register a call-flow function endpoint (admin). Conduyt POSTs a signed JSON snapshot of the call (X-Conduyt-Signature = sha256 HMAC of |
| conduyt_update_call_flow_functionA | Rename a call-flow function endpoint, change its URL, or rotate its secret (admin). |
| conduyt_delete_call_flow_functionA | Remove a call-flow function endpoint (admin). Refused while a PUBLISHED flow still calls it — edit and republish that flow first. |
| conduyt_test_call_flow_functionB | Send a real signed test call (callSid TEST, a sample caller) to a function endpoint and report the status, latency and the attributes it would save. |
| conduyt_project_blue_statusA | Project Blue connection status for this account (connected / not_configured, the API key masked) plus the current line assignments (which agent holds which iPhone line). Requires settings:view. |
| conduyt_project_blue_linesA | The LIVE Project Blue line inventory read from the vendor with this account's key: every line (lineId, E.164 phoneNumber, name) with its assigned agent (assignedTo) or null, plus |
| conduyt_project_blue_assign_lineA | Assign a Project Blue line to an agent, or release it (userId null). One line per agent and one agent per line: assigning a line another agent holds, or to an agent who already has a line, MOVES it — the response's |
| conduyt_project_blue_voice_statusB | Project Blue VOICE calling status: whether the vendor's Twilio Voice keys (Account SID, TwiML App SID, API Key) are stored, masked, and the caller ID that account presents for iPhone-line calls (the line itself once Project Blue verifies it, else the vendor-provisioned number). The secret is never returned. |
| conduyt_project_blue_voice_connectA | Store Project Blue's Twilio Voice keys for this account (from their dashboard: Settings → General → API Keys → Voice Calling API). Conduyt verifies them against Twilio READ-ONLY and records the caller ID that account can present; a rejected key set is refused with the reason. Pass clear=true to remove the keys (iPhone-line calls fall back to FaceTime Audio). |
| conduyt_whatsapp_statusA | WhatsApp connection for this account (GET /api/v1/settings/whatsapp): status connected | not_configured | twilio_required (a sender is stored but Twilio is disconnected), twilioConnected, and the sender {phoneNumber (plain E.164), sid}. WhatsApp rides the account's Twilio credentials; the workflow Send SMS step, conduyt_send_sms (transport whatsapp) and the contact composer can use it once connected. Requires settings:view. |
| conduyt_whatsapp_sendersA | The WhatsApp senders Twilio lists under this account's credentials (GET /api/v1/settings/whatsapp/senders): sid (XE…), phoneNumber, status (only ONLINE can be connected), displayName, connected (the stored one). 422 twilio_required without Twilio credentials. Requires settings:view. |
| conduyt_whatsapp_connectA | Connect the account's WhatsApp sender (PUT /api/v1/settings/whatsapp): pass the sender sid from conduyt_whatsapp_senders. Verified with Twilio before it is stored: it must be on this account and ONLINE (422 sender_not_found / sender_not_online), one sender belongs to one Conduyt account (409 sender_in_use), Twilio is required (422 twilio_required). Pass disconnect: true to forget the sender instead (DELETE): workflow steps on the WhatsApp channel stop sending. Requires settings:edit. |
| conduyt_fromk_statusA | FromK.ai connection for this account (GET /api/v1/settings/fromk): status connected | not_configured, the API key masked, the lines snapshot (phoneNumberId, phoneE164, status, provider, sendReady) and the webhook setup (the URL the tenant pastes into FromK.ai → Developers → Webhooks, whether the signing secret is stored, the events to subscribe). Requires settings:view. |
| conduyt_fromk_linesA | Refresh the FromK.ai line list from the workspace with the stored key and store it as the new snapshot (GET /api/v1/settings/fromk/lines): every line with sendReady (assigned, ownership verified, SMS-capable, on a real carrier). A send-ready phoneNumberId is a valid send_sms config.fromkPhoneNumberId / conduyt_send_sms fromkPhoneNumberId. 409 fromk_not_configured, 422 key_revoked, 502 vendor_unavailable (the old snapshot is kept). Requires settings:view. |
| conduyt_fromk_connectA | Connect or replace the account's FromK.ai workspace API key (PUT /api/v1/settings/fromk): fk_… with numbers:read, contacts:write and messages:send. Verified with FromK.ai before it is stored (it must list the workspace's lines: 422 key_rejected / key_scope, 502 vendor_unavailable, nothing stored). Pass disconnect: true to forget the key, the signing secret, the lines and every contact link instead (DELETE): workflow steps on the FromK.ai channel stop sending. Requires settings:edit. |
| conduyt_fromk_webhook_secretA | Store (PUT /api/v1/settings/fromk/webhook) or forget (DELETE, clear: true) the signing secret of the FromK.ai webhook endpoint the tenant pointed at Conduyt (whsec_…, shown once by FromK.ai when the endpoint is created). Until it is stored, FromK.ai replies and delivery reports are refused. 409 fromk_not_configured before the key is connected. Requires settings:edit. |
| conduyt_zoom_statusA | Zoom connection for this account (GET /api/v1/settings/zoom): status connected | not_configured, the Zoom account id and client id masked (the client secret is never returned). Requires settings:view. |
| conduyt_zoom_connectA | Connect or replace the account's Zoom Server-to-Server OAuth app (PUT /api/v1/settings/zoom): accountId, clientId, clientSecret from the Zoom App Marketplace app with scopes meeting:write/read/update/delete:meeting:admin + user:read:user:admin. Verified with Zoom before it is stored (a token must be issued and the app's own user readable: 422 credentials_rejected / scope_missing, 502 vendor_unavailable, nothing stored). Answers the app's user = the default meeting host. Pass disconnect: true to forget the app instead (DELETE): booking pages set to Zoom fall back to their written location. Requires settings:edit. |
| conduyt_zoom_testA | Prove the stored Zoom app still works (POST /api/v1/settings/zoom/test): a token is issued and the app's own user answers; pass hostEmail to also prove that user belongs to the Zoom account (the value a booking page's videoHostEmail must be). Read-only on Zoom, nothing is created. 200 with ok:false + code host_not_found | credentials_rejected | scope_missing | vendor_unavailable when it does not; 409 zoom_not_configured before connect. Requires settings:view. |
| conduyt_list_booking_pagesA | List the account's booking pages (GET /api/v1/booking-pages): slug, title, host, duration, active, video option. Requires calendar:view. |
| conduyt_get_booking_pageA | One booking page with every setting (GET /api/v1/booking-pages/{id}). Requires calendar:view. |
| conduyt_create_booking_pageA | Create a booking page (POST /api/v1/booking-pages): title, slug, userId (host) and durationMinutes at least; optional written location, videoProvider 'zoom' + videoHostEmail for one Zoom meeting per booking, availabilityRules override, embedAllowedOrigins, leadSource, brandName. Requires calendar:edit (admin/owner). |
| conduyt_update_booking_pageA | Update a booking page (PATCH /api/v1/booking-pages/{id}): only the fields given change. videoProvider 'zoom' turns on one Zoom meeting per booking (null turns it off and clears the host); videoHostEmail must be a user of the connected Zoom account (null = the app's own user). Requires calendar:edit (admin/owner). |
| conduyt_report_fieldsA | The field catalogue a custom report may use on a base: the entity's own columns, its per-row rollups (contacts/deals) and the account's custom fields, with type, operators and whether each can group, sort or be measured. Read this before building a report. |
| conduyt_list_reportsA | List the account's saved custom reports (shared ones and your own), with their definition and last-run status. |
| conduyt_create_reportB | Create a saved custom report. contacts/deals bases support rollup columns, cf: custom fields, a Smart View population and groupBy2 (see conduyt_report_fields). |
| conduyt_run_reportB | Run a saved custom report: a page of rows (per_page ≤ 500), the total, the metric, the chart data (groupBy) and, on contacts/deals with groupBy2, the two-dimensional grouped rows. |
| conduyt_preview_reportA | Run an UNSAVED report definition (10 rows) to check columns and filters before saving. Same fields as conduyt_create_report. |
| conduyt_update_reportB | Update a saved custom report: any create field, plus pivot (set a pivot grid, or null to remove it). Only the fields you pass change. |
| conduyt_export_reportA | Export every matching row of a saved report (up to 50,000) as CSV or XLSX text. Returns the file body; for a large report narrow the filters or ask for the scheduled delivery. |
| conduyt_list_report_schedulesB | The scheduled deliveries on a saved report (daily / weekly / monthly emails of the report as CSV, XLSX or PDF): cadence, time, formats, recipients, next and last run. |
| conduyt_create_report_scheduleA | Schedule a saved report to be emailed on a cadence. The delivery runs with the visibility of whoever creates it. Needs reports export. |
| conduyt_update_report_scheduleB | Change a schedule (only the fields you pass), including pausing (enabled: false) or resuming it. |
| conduyt_delete_report_scheduleB | Remove a schedule. Past deliveries stay downloadable until they expire (14 days). |
| conduyt_send_report_schedule_nowA | Build and email a schedule right now (one manual delivery; the schedule itself is untouched). Rate-limited to 3 per 10 minutes per schedule. |
| conduyt_report_schedule_deliveriesB | The delivery history of a schedule (newest first): status, rows, whether it was emailed, and download URLs for the files. |
| conduyt_list_dashboardsA | The dashboards this key can open (shared boards and its own; admins see all): name, filters, tiles. |
| conduyt_create_dashboardC | Create a dashboard: a board of tiles, each a saved report shown as a KPI, chart, table or pivot, with one set of filters for the whole board. |
| conduyt_get_dashboardC | One dashboard with its tiles and their reports. |
| conduyt_update_dashboardA | Rename, describe, share, replace the board filters, or reorder the tiles (tileOrder = every tile id once, in the new order). Only the fields you pass change. |
| conduyt_delete_dashboardB | Delete a dashboard (its tiles go with it; the saved reports stay). |
| conduyt_add_dashboard_tileA | Pin a saved report to a dashboard. kind kpi (style ledger | trend | goal; goal needs a target), chart (report needs a group by; style ranked | target | focus), table, or pivot (report needs a pivot). size s / m / l on a six-column grid. |
| conduyt_update_dashboard_tileB | Change a tile's style, size, title or target (null clears the target). |
| conduyt_remove_dashboard_tileA | Remove a tile from a dashboard (the saved report stays). |
| conduyt_run_dashboardA | Run every tile of a dashboard with the board filters applied (pass filters to override them for this run only): KPI tiles carry the value, the previous window's value, the delta, and for trend a series, for goal the progress and pace; chart tiles the chart data; table tiles the first rows; pivot tiles the pivot grid. A tile whose report fails carries its error and the rest still return. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 292 tools
The set has many overlapping clusters: AI insight tools (ai_insights, ai_summarize_contact, ai_daily_brief, ai_agenda, ai_next_actions, ai_feed, ai_chat), dashboard/report tools, sequence vs drip-campaign tools, and bulk edit vs bulk update variants. Detailed descriptions help, but with 292 tools an agent will often struggle to select the right one without first reading several similar candidates.
All names share the conduyt_ prefix and snake_case, which is helpful, but the verb_noun pattern is not consistent: many tools are noun phrases or configuration endpoints (conduyt_api_catalog, conduyt_mcp_coverage, conduyt_dashboard, conduyt_sms_transports, conduyt_voice_drop, conduyt_whatsapp_templates, conduyt_call_flow_roster). The conventions are readable but mixed enough to fall short of a predictable pattern.
292 tools is an extreme surface for a single MCP server and far beyond what an agent can reliably scan or choose from. Even though the CRM domain is broad, the count creates substantial cognitive and selection overhead, with many niche settings and reporting tools crowding out core actions.
Coverage is extensive across contacts, deals, tasks, pipelines, reporting, automations, calls, messaging, billing, settings, and integrations, with many lifecycle operations present. Some gaps remain, such as missing delete/update operations for a few core entities (appointments, activities, products, templates, invoices, sequences), but most workflows have workarounds.