Groundbase
Server Details
CRM for one-person businesses. Sends texts and email through your own accounts, runs campaigns and workflows, issues invoices. OAuth or API key.
- Status
- Healthy
- Uptime
- 97.5% over 23 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
TDQS
Scored across 104 tools
Tools are mostly distinct by entity and action, with clear names like contacts_create vs companies_create. Minor overlap exists between email_send and campaigns_manage for sending emails, and tasks_create bundles tasks/events/meetings, but descriptions clarify boundaries.
Nearly all tools follow a consistent snake_case entity_action pattern (e.g., contacts_list, deals_update). Minor deviations include singular entity names (activity_list, dashboard_summary) and multi-action 'manage' tools, but overall predictable.
104 tools is an extreme mismatch for a single MCP server, far exceeding typical 3-15 tool scoping. While the domain is broad, this volume risks overwhelming agents and exceeds the 50+ threshold for severe over-scoping.
The surface covers full CRUD for core entities (contacts, companies, deals, tasks, notes, tags, custom fields) and comprehensive lifecycle for invoices, quotes, campaigns, workflows, and time tracking. No obvious gaps in operations; even edge cases like payment reversal and webhook management are included.
Available Tools
59 toolsactivity_listARead-onlyIdempotentInspect
Recent activity, newest first: texts, calls, emails, notes, deal stage changes, task completions. Optionally scoped to one contact, company or deal.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 50. | |
| dealId | No | ||
| companyId | No | ||
| contactId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, idempotent=true, destructive=false, so the safety profile is covered. The description adds the ordering guarantee ('newest first'), which is genuinely useful behavior not in the annotations, but says nothing about pagination, truncation, or the result window.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, with the ordering guarantee front-loaded before the optional scope qualifier. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with no output schema, the description conveys the entity types returned and their ordering. The main omission is pagination/windowing behavior, but the schema's limit parameter and annotations cover most of the remaining risk.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25% (just limit). The description compensates for the three ID parameters by explaining they scope the feed to one contact, company, or deal, but leaves open whether they can be combined and says nothing about limit semantics beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the resource (a unified recent-activity feed) and enumerates the event types it returns (texts, calls, emails, notes, deal stage changes, task completions). This implicitly distinguishes it from the per-type siblings (calls_list, sms_list, notes_list) as an aggregate view, though it never names them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'Recent activity' plus the optional scoping sentence, so an agent can infer it answers 'what has happened lately for this record'. There is no explicit when-to-use versus calls_list/sms_list/notes_list, and no stated exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
addresses_manageDestructiveInspect
Postal addresses on a contact or company (contactId or companyId). list, create, update (omitted fields unchanged), delete (confirm first). A contact or company fetched by id already includes its addresses.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | ||
| label | No | e.g. 'home', 'office'. | |
| notes | No | ||
| action | Yes | ||
| street | No | ||
| country | No | ||
| province | No | State, province or region. | |
| addressId | No | ||
| companyId | No | ||
| contactId | No | ||
| is_primary | No | Make this the primary address (demotes the old one). | |
| postal_code | No |
billing_profiles_manageDestructiveInspect
Billing details on a contact or company (currency, terms, billing email, tax id). list (or contactId / companyId for one), save (create on exactly one, or edit by id), delete.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Edit this profile. Omit to create. | |
| notes | No | ||
| taxId | No | ||
| action | Yes | ||
| currency | No | ISO 4217. | |
| companyId | No | ||
| contactId | No | ||
| billingEmail | No | Where invoices and receipts go, if not the contact's own address. | |
| billingAddress | No | ||
| paymentTermsDays | No | 0 = due on receipt. |
calls_listARead-onlyIdempotentInspect
List call history (direction, duration, voicemail transcripts), or pass id to fetch one call with its recording details.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Call id. Returns that one call. | |
| limit | No | Default 100, max 500. | |
| contactId | No | ||
| voicemailOnly | No | Only calls that left a voicemail. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered. The description adds value by disclosing what the list returns (direction, duration, voicemail transcripts) and that single-call mode includes recording details, but it says nothing about pagination or how the default/vs max limit behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the primary list purpose front-loaded and the alternate `id` mode appended. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description partially compensates by naming returned fields, but leaves out pagination/limit behavior and the undescribed `contactId` parameter. Adequate for a simple read tool, but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, so the schema carries most parameter documentation; `limit`, `voicemailOnly`, and `id` are described there. The description only implicitly maps to `id` and doesn't mention `contactId` (undocumented in the schema) or limit semantics, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('List call history') and enumerates the fields returned, then names the alternate single-fetch mode via `id`. It clearly separates list vs. single-call behavior, though it does not explicitly contrast itself with neighboring list tools like sms_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing guidance: use the default list mode, or pass `id` to fetch a single call with recording details. There is no statement of when not to use it or of alternative tools, but the mode selection is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
campaigns_analyticsARead-onlyIdempotentInspect
Stats for one campaign (recipients, sent, delivered, unique opens/clicks, bounces, unsubscribes, replies, failures). With recipients: true, returns per-recipient rows instead, optionally filtered by status.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| limit | No | Recipients: default 100. | |
| status | No | Recipients filter. | |
| recipients | No | Return per-recipient status rows. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond that: what data is returned and the two distinct response shapes. It stops short of mentioning pagination behavior or default row counts, which rely on the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with zero filler. The primary mode and its metric list come first, and the alternate mode is appended as a compact clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing returned data and does so by enumerating metrics and both response shapes. It is close to complete for a read-only analytics tool; only pagination/default-limit behavior is left to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75%, with 'id' undocumented in both places. The description compensates meaningfully by clarifying that 'status' is a recipients-mode filter and that 'recipients' toggles between aggregate and row output — semantics the schema does not fully convey. The undescribed 'id' is self-evident given the context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Stats') and resource ('one campaign') and then enumerates the exact metrics returned (recipients, sent, delivered, opens/clicks, bounces, unsubscribes, replies, failures). It also disambiguates the second mode ('With recipients: true, returns per-recipient rows instead'), making it clearly distinct from the campaigns_manage sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the condition that switches to per-recipient output and when the status filter applies, which is implied usage guidance. However, it never states when to use this tool versus campaigns_manage or dashboard_summary, nor any prerequisites for the campaign id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
campaigns_manageADestructiveInspect
Email/SMS campaigns and newsletters. Actions: list (kind=newsletter for newsletters), get, create (draft; template_id starts a newsletter from newsletter_templates), update, delete, duplicate, test_send, send_now, schedule, pause, resume, stop, add_recipients, preview_audience, newsletter_templates. send_now/schedule/resume message real people: confirm first.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | list: name search. | |
| id | No | Campaign id; needed for all but list, create, preview_audience. | |
| to | No | test_send recipient. | |
| kind | No | list filter: newsletters, or everything else. | |
| name | No | ||
| role | No | newsletter_templates: another industry's set (e.g. real estate, mortgage, insurance). Default: the user's own. | |
| limit | No | ||
| steps | No | Drip steps (send_mode 'drip'): [{ delay_seconds, content_json, exit_on?, channel? }]. Step 0 sends at start; each later step sends delay_seconds after that recipient's previous actual send. exit_on { reply?, open?, click?, meeting? } skips the rest for a contact who did that. channel overrides the campaign channel for the step. | |
| action | Yes | ||
| status | No | list filter. | |
| channel | No | ||
| content | No | Single send. Email: { subject, preheader?, from_name?, from_email?, reply_to?, blocks: [{ type, props }] }; block types text {html}, header {html, level 1-3}, image {src, alt, width}, button {text, url, bgColor?}, divider {color?}, spacer {height}. from_email must be on a domain verified in Resend (resend_manage domains) or it fails per recipient at send time. reply_to should be a mailbox connected in Groundbase, or drip reply-exit cannot see replies. SMS: { body, media_urls? }. Merge tags like {{first_name}}, {{cf.<key>}} work in any string. Newsletter: content.kind 'newsletter' (one email, sent once). Extra blocks: section_header {title}; agent_card {photoUrl, name, title, phone, email, website, brokerage, note}; listing_card {imageUrl, status, price, address, beds, baths, sqft, url, buttonText}; market_stats {title, stats:[{label,value,change}], footnote}; quote {quote, author, role, avatarUrl}; footer {businessName, businessAddress, tagline, unsubText}. It will not send until the footer has a real business name and mailing address and no [bracketed] or $— placeholder is left anywhere; the refusal names the first one. | |
| audience | No | duplicate: copy goes only to people the (sent, email) campaign reached who did not open it. | |
| send_mode | No | ||
| contact_ids | No | add_recipients: up to 500. | |
| template_id | No | create: start a newsletter from this template (newsletter_templates). name defaults to the template name. | |
| scheduled_at | No | Unix seconds. | |
| enrolment_mode | No | 'once' (default) fixes its audience at start. 'ongoing' keeps sending until stop and takes new entrants (filter re-run every 5 min, add_recipients, workflow add_to_campaign). | |
| sending_window | No | { days: [0-6, 0=Sunday], start_hour: 0-23, end_hour: 1-24 (exclusive), timezone?: IANA or 'auto' (account tz) }. Sends due outside the window wait for the next open hour. null = no restriction. | |
| audience_filter | No | { all: [rules], any?: [rules] }. Rules: { type: "all_contacts" } or { type: "tag", op: "has"|"has_not", value: "<tag name>" }. all[] ANDs, any[] ORs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds traits beyond the annotations: create only produces a draft, and send_now/schedule/resume reach real people so confirmation is required first. Annotations already declare destructiveHint/openWorldHint, so the description's job is smaller, and it delivers the key safety nuance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and front-loaded: the resource is stated first, then a dense action list, then the one critical warning. The action enumeration is information-dense but each token earns its place for a multi-action tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 20-parameter, nested-object, 15-action tool with no output schema, the description routes actions adequately and flags the send-confirmation risk, but says nothing about permissions/auth, return shapes for list/get, or what delete destroys. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 75%, so the schema already documents most parameters and the baseline is 3. The description adds only a couple of action-specific hints (kind=newsletter for list, template_id for create) and does not clarify the other ~20 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (manage email/SMS campaigns and newsletters) and enumerates all 15 actions, which lets an agent see the scope immediately. It does not explicitly distinguish itself from near-neighbors like sms_send, email_send, or campaigns_analytics, so sibling differentiation is only implied.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides real context for the tricky actions: 'list (kind=newsletter for newsletters)', 'create (draft; template_id starts a newsletter from newsletter_templates)', and 'send_now/schedule/resume message real people: confirm first'. It stops short of naming alternatives (e.g. when to use sms_send instead) or listing exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
companies_listRead-onlyIdempotentInspect
Search companies, or pass id to fetch one in full (employees, deals, addresses, custom fields).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Company id. Returns that one company. | |
| limit | No | Default 50. | |
| offset | No | ||
| search | No | Matches name and website. | |
| deleted | No | List recently deleted companies instead (to restore). |
companies_manageDestructiveInspect
Change companies. create (name required; tags by name), update (omitted fields unchanged), delete (soft; confirm first), restore (ids from companies_list deleted).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| ids | No | restore: the deleted records to bring back. | |
| city | No | ||
| name | No | ||
| tags | No | ||
| notes | No | ||
| state | No | State or province. | |
| action | Yes | ||
| country | No | ||
| website | No | Include https://. | |
| industry | No | ||
| deletedAt | No | restore: undo one delete, everything it removed (its deleted_at from the deleted list). |
contacts_listRead-onlyIdempotentInspect
Search and filter contacts (tag, company, unsubscribed, sort), or id for one in full (tags, addresses, custom fields, recent activity). deleted: the recently deleted ones (to restore). duplicates: groups sharing an email or phone (to merge).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Contact id. Returns that one contact; other filters ignored. | |
| tag | No | Only contacts with this tag (name or id). | |
| sort | No | recent = last contacted. Default name. | |
| limit | No | Default 50. | |
| offset | No | ||
| search | No | Matches name, email, phone. | |
| deleted | No | List recently deleted contacts instead. | |
| companyId | No | Only contacts at this company. | |
| duplicates | No | List groups of live contacts sharing an email or phone instead. | |
| unsubscribed | No | Opted out of any channel / email / texts, or none (for an audience). |
contacts_manageDestructiveInspect
Change contacts. create (firstName required; tags by name), update (omitted fields unchanged), delete (soft; confirm first), merge (keepId + mergeIds: duplicates folded in, then deleted; confirm), restore (ids from contacts_list deleted), bulk_update (ids + set {city, source, position, companyId} and/or customField).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| ids | No | restore: the deleted records to bring back. | |
| set | No | bulk_update: { city?, source?, position?, companyId? }. | |
| tags | No | Tag names; missing ones are created. | |
| No | |||
| notes | No | ||
| phone | No | Normalised to E.164. | |
| action | Yes | ||
| keepId | No | merge: the contact that stays. | |
| lastName | No | ||
| mergeIds | No | merge: the duplicates folded into it. | |
| position | No | Job title. | |
| companyId | No | ||
| deletedAt | No | restore: undo one delete, everything it removed (its deleted_at from the deleted list). | |
| firstName | No | ||
| customField | No | bulk_update: { key (field id or key), value }. |
custom_fields_listRead-onlyIdempotentInspect
List custom field definitions: field_key (used in {{cf.}}), name, type, options, entity_type. mergeTags: true lists every merge tag usable in texts, emails and workflows ({{first_name}}, {{cf.}}…); unknown tags render empty.
| Name | Required | Description | Default |
|---|---|---|---|
| mergeTags | No | List merge tags instead. | |
| entityType | No | Omit for all. |
custom_fields_manageDestructiveInspect
Custom fields on contacts, companies or deals. create (field_key becomes {{cf.}}), update, delete (its values go too; confirm first), set_value (one record's value).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | Label, e.g. "Loan amount". | |
| type | No | ||
| value | No | ||
| action | Yes | ||
| options | No | Required for type select. | |
| entityId | No | ||
| fieldKey | No | snake_case, max 60 chars. | |
| position | No | Lower sorts first. | |
| entityType | No |
dashboard_summaryRead-onlyIdempotentInspect
KPI summary: contact count, open and won deals with totals, messages sent/received, plus a 30-day series. pipeline: true for open deals per stage (count and value).
| Name | Required | Description | Default |
|---|---|---|---|
| pipeline | No | Per-stage open deals instead. |
deals_listRead-onlyIdempotentInspect
List deals with stage, value, contact and company, or pass id to fetch one deal with its notes and tasks.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Deal id. Returns that one deal. | |
| limit | No | ||
| offset | No | ||
| search | No | Matches title, contact and company name. | |
| deleted | No | List recently deleted deals instead (to restore). | |
| stageId | No | From deal_stages_list. | |
| companyId | No | ||
| contactId | No |
deals_manageDestructiveInspect
Change deals. create (title and stageId from deal_stages_list), update (stageId moves it; omitted fields unchanged), delete (soft; confirm first), restore (ids from deals_list deleted). Values are in cents.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| ids | No | restore: the deleted records to bring back. | |
| notes | No | ||
| title | No | ||
| action | Yes | ||
| closeAt | No | Expected close date, YYYY-MM-DD or ISO 8601. | |
| stageId | No | ||
| companyId | No | ||
| contactId | No | ||
| deletedAt | No | restore: undo one delete, everything it removed (its deleted_at from the deleted list). | |
| valueCents | No | In the account's default currency (deals have no currency of their own). |
deal_stages_listARead-onlyIdempotentInspect
List pipeline stages in order (id, name, colour, position). Call before creating or moving a deal.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a read-only, idempotent, non-destructive, closed-world operation, so the safety profile is covered. The description adds genuinely new behavioral context: results come back in order and the shape of each record. It omits whether results are paginated or scoped per pipeline, which is a minor gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the core action first and the usage cue second. Nothing could be removed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description usefully documents the returned fields and their ordering. It is complete for calling the tool, though it does not say whether the list is global or pipeline-scoped.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema imposes no semantic burden and the baseline is 4. The description's field list compensates for the absent output schema rather than adding parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List pipeline stages') and enumerates the returned fields (id, name, colour, position), which cleanly separates it from sibling deal_stages_create/deal_stages_update and from deals_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit timing guidance ('Call before creating or moving a deal'), which tells the agent when this tool is relevant. It does not name alternatives or state when not to use it, so it falls short of a full when/when-not/alternatives treatment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deal_stages_manageDestructiveInspect
Pipeline stages. create (isWon / isLost mark the end stages), update (rename / recolour by id, or order: every stage id left to right), delete (deals in it need reassignTo; never the last stage; confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Stage to rename/recolour. | |
| name | No | ||
| color | No | Hex, e.g. "#0EA5E9". | |
| isWon | No | ||
| order | No | All stage ids in the new order. A partial list leaves the rest unplaced. | |
| action | Yes | ||
| isLost | No | ||
| position | No | Zero-based order. | |
| reassignTo | No | delete: the stage its deals move to. |
documents_manageDestructiveInspect
Documents sent for signing. list (status/contactId), get (id: signers + history), templates (saved forms and their signer roles), send (a template; emails each signer, confirm first), remind (email whoever is due to sign; confirm first), void (cancel a waiting one for good). Statuses: sent = waiting, completed = signed by all, declined, voided.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | get / remind / void: the document id. | |
| title | No | send: defaults to the template name. | |
| action | Yes | ||
| reason | No | void: why (kept in the history). | |
| status | No | list: sent | completed | declined | voided | |
| message | No | send: shown in the email; defaults to the template's. | |
| ordered | No | send: sign one after another in role order (the user last). | |
| signers | No | send, several roles: { role, contactId } or { role, name, email }. | |
| signerId | No | remind: just this signer. | |
| contactId | No | list: documents this contact was sent. send: who signs (one signer role). | |
| templateId | No | send: the template. With one signer role pass contactId; with several pass signers. A role marked is_sender is the user and fills itself. Contacts need an email. |
email_readRead-onlyIdempotentInspect
Read email. threads (the inbox list, filter by folder / search / account), thread (threadKey: its messages; messageId: one full body), accounts (the mailboxes and send-as addresses email_send can use). Reading does not mark anything read.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 25, max 100. | |
| action | Yes | ||
| folder | No | Default: all. | |
| search | No | Matches subject, sender and message text. | |
| account | No | Mailbox id from email_accounts_list. Default: all. | |
| messageId | No | Fetches that message's body (slower; only when the snippet is not enough). | |
| threadKey | No | The `thread_id` from email_list_threads. |
email_sendAInspect
Send a real email from the user's connected mailbox (default: the oldest one). Give bodyHtml and/or bodyText. Pass contactId so merge tags resolve and the email threads to that contact. At most 50 recipients (to+cc+bcc); a list is a campaign. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | Yes | Address or comma-separated list. | |
| bcc | No | ||
| subject | Yes | ||
| bodyHtml | No | ||
| bodyText | No | ||
| fromName | No | ||
| accountId | No | Sending mailbox, from email_accounts_list. | |
| contactId | No | ||
| fromEmail | No | Send-as alias registered on that mailbox; others are refused (INVALID_FROM). | |
| trackOpens | No | Adds an open-tracking pixel (approximate). | |
| scheduledSendAt | No | Future ISO 8601 time to send at. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly=false, idempotent=false, openWorld=true, destructive=false), and the description adds value beyond them: the default mailbox is the oldest account, the 50-recipient ceiling across to+cc+bcc, merge-tag/threading behavior, and the confirm-first expectation. It does not spell out auth/permission requirements or what a failure returns, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four tight sentences, front-loaded with the core action and scoped by mailbox, followed by body, contactId, recipient-limit, and confirmation guidance. Dense and purposeful, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 12 params at 42% coverage, the description carries a lot but covers the key behavioral facts: default mailbox, threading/merge tags, recipient ceiling, and confirmation. Minor gaps remain (fromName intent, scheduling semantics), but the agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (42%) and 12 params exist, so the description must compensate. It clarifies that bodyHtml and bodyText are alternatives and explains the contactId effect, but leaves fromName, cc/bcc/subject, and several others unaddressed, so it only partially fills the gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send a real email from the user's connected mailbox') and the 'real' qualifier plus the mailbox scope clearly separates it from sibling senders like sms_send, invoices_send, and quotes_send. An agent can identify the action without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete usage conditions: supply bodyHtml and/or bodyText, pass contactId for merge tags and threading, and 'Confirm with the user first'. It sets context but does not name alternative tools or state when not to use it, so it falls short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
email_thread_updateIdempotentInspect
Mark an email conversation read or unread, or move it to inbox, sent or archive.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | move: where it goes ("inbox" also un-archives). | |
| isRead | No | mark: true = read, false = unread. | |
| threadKey | Yes | The `thread_id` from the thread list. |
forms_manageDestructiveInspect
Lead-capture forms with a public link; each submission creates or updates a contact. action: list | templates | get (id) | create (name?, templateId?) | update (id + fields to change) | delete (id; the link stops working, confirm first) | submissions (id; latest 200).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Form id. | |
| name | No | ||
| tags | No | Tag names put on each new lead (max 10). Replaces the list. | |
| intro | No | ||
| style | No | Appearance: { button_color, background_color, text_color: "#rrggbb", font: system|serif|rounded|mono }. {} resets to the default look. Replaces the whole style. | |
| title | No | ||
| action | Yes | ||
| fields | No | [{ key, label, type: text|email|phone|textarea|select|address, required?, options? (select) }]. Keys name, first_name, last_name, email, phone fill the contact. Replaces the list. | |
| createTask | No | Also make a follow-up task per submission. | |
| templateId | No | For create, from action templates. Default: a simple contact form. | |
| submitLabel | No | ||
| successMessage | No |
inbound_webhooks_manageADestructiveInspect
Inbound webhooks: URLs other services POST to so Groundbase creates contacts, deals, tasks etc. action list | get | create | update | delete. create returns the full URL with its token ONCE (tell the user; it cannot be shown again). delete stops the URL accepting posts immediately; confirm first.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | For get/update/delete. | |
| name | No | Required on create. | |
| action | Yes | ||
| isActive | No | Update only; false pauses receiving. | |
| description | No | ||
| ipAllowlist | No | CIDRs. Empty = any IP. | |
| mappingJson | No | For mappingMode "mapped": { "actions": [{ "event": "contact.find_or_create" (or another native event), "fields": { "<groundbase_field>": "<path.in.payload>" }, "static": { "<groundbase_field>": <literal> } }] }. Paths are dotted with optional indices ("lead.contact[0].email"); missing paths are omitted. | |
| mappingMode | No | Default native. | |
| signingSecret | No | Optional HMAC secret (create only); senders send X-Groundbase-Signature. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and non-idempotent, but the description adds material context beyond them: the signing/token URL is returned only once and cannot be reshown, and delete immediately stops the endpoint from accepting posts. These are non-obvious behavioral traits an agent must communicate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded: identity/scope first, then the action list, then critical caveats. Nearly every clause earns its place, though the multi-clause second half could be slightly tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 9-param tool with nested mapping objects and no output schema, the description covers the highest-risk behaviors (one-time token, destructive delete). It leaves ipAllowlist/mapping semantics to the well-documented schema, which is reasonable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 78%, near the high-coverage baseline, and the nested mappingJson/mappingMode fields are already documented in the schema. The description contributes no additional parameter meaning beyond restating the action set, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Inbound webhooks: URLs other services POST to so Groundbase creates contacts, deals, tasks') and enumerates the operations. It also implicitly distinguishes itself from the sibling outbound_webhooks_manage by naming the inbound direction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Per-action guidance is present ('create returns the token ONCE', 'delete ... confirm first'), which helps the agent act correctly. However, there is no explicit when-to-use/when-not guidance versus alternatives such as outbound_webhooks_manage; usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
invoice_items_manageDestructiveInspect
Saved invoice items (services / products). list (with price per currency), save (create, or edit by id; prices are decimal strings), delete (invoices keep their lines).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Edit this item. Omit to create. | |
| name | No | Required to create. | |
| action | Yes | ||
| prices | No | Chosen prices per currency, e.g. { "CAD": "150.00" }; others convert from base. | |
| unitLabel | No | e.g. "hour". | |
| unitPrice | No | In base currency, with its decimal places ("200.00"; JPY "15000"). | |
| description | No | ||
| baseCurrency | No | Create only. ISO 4217, default USD. | |
| defaultTaxRate | No | Percent, e.g. "17.5". |
invoice_payments_manageDestructiveInspect
record (a payment taken outside Stripe; emails a receipt, confirm first) or reverse (paymentId; undoes a recorded payment). Card refunds are done in the app.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | ||
| action | Yes | ||
| amount | No | Decimal string in the invoice currency. | |
| method | No | ||
| sendVia | No | ||
| invoiceId | No | ||
| paymentId | No | ||
| reference | No | Cheque number or transfer reference. | |
| receivedAt | No | ISO date. Default now. | |
| sendReceipt | No | Default true. |
invoice_settingsIdempotentInspect
Invoice settings: business details on invoices and receipts, payment instructions, numbering. get, or set (omitted fields unchanged; nextNumber only moves forward).
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| nextNumber | No | ||
| businessName | No | ||
| defaultNotes | No | ||
| numberPrefix | No | e.g. "INV-", max 16 chars. | |
| businessEmail | No | ||
| businessPhone | No | ||
| businessTaxId | No | ||
| numberPadding | No | Min digits 1-12. | |
| businessAddress | No | ||
| defaultCurrency | No | ||
| defaultTermsDays | No | ||
| defaultTermsText | No | ||
| paymentInstructions | No | How to pay (bank details, link). |
invoices_listRead-onlyIdempotentInspect
List invoices (filter by customer, status, text; outstanding totals per currency), or id for one with lines, charges and amount paid. With id: payments (ledger), creditNotes, or recurring (its repeat schedule).
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Matches number and customer. | |
| id | No | Invoice id. Returns that one invoice. | |
| limit | No | Default 100. | |
| offset | No | ||
| status | No | draft | issued | partially_paid | paid | void | |
| payments | No | With id: return the payment ledger (incl. reversed payments). | |
| companyId | No | ||
| contactId | No | ||
| recurring | No | With id: its repeat schedule (null if none). | |
| creditNotes | No | With id: its credit notes. | |
| outstanding | No | Only invoices with money still owed. |
invoices_manageDestructiveInspect
Invoices. save_draft (create, or edit by id), issue (numbers it; final), send (emails it; confirm), void, public_link (a pay link; revoke), credit_note (amount + reason; final), send_credit_note / void_credit_note (creditNoteId), recurring (frequency + nextRunDate, autoSend emails each; stop). Confirm anything final or sent.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Edit this draft. Omit to create. | |
| to | No | Default: profile billing email, then the contact's email. | |
| stop | No | recurring: end the schedule. | |
| lines | No | Line items: itemId (saved item, priced in this currency) or name + unitPrice for a one-off. Amounts are decimal strings. | |
| notes | No | ||
| terms | No | ||
| action | Yes | ||
| amount | No | credit_note: before tax, e.g. "50.00". | |
| reason | No | credit_note: printed on it. | |
| revoke | No | public_link: turn the link off. | |
| charges | No | Charges below the subtotal (shipping, rush fee); a negative amount for a deposit or discount. | |
| dueDate | No | YYYY-MM-DD. Default from profile terms. | |
| endDate | No | recurring: YYYY-MM-DD, or omit for no end. | |
| message | No | A note above the invoice in the email. | |
| sendVia | No | Default: their own mailbox, then Resend, then Groundbase's address. | |
| subject | No | Default: the invoice settings subject. | |
| taxRate | No | credit_note: percent, e.g. "13". | |
| autoSend | No | recurring: email each copy to the customer. Confirm with the user. | |
| currency | No | ISO 4217. Defaults from the billing profile. | |
| companyId | No | ||
| contactId | No | Create: one of contactId/companyId. | |
| frequency | No | ||
| issueDate | No | YYYY-MM-DD. Default today. | |
| nextRunDate | No | recurring: YYYY-MM-DD, today or later. | |
| confirm_paid | No | Void even though payments or credit notes are recorded on it. Only after the user has confirmed. Default false. | |
| creditNoteId | No |
meetings_bookInspect
Book a contact into a meeting type. slots: open times (from/to YYYY-MM-DD optional). book: startAt (ISO) + contactId, or name with email/phone. Prefer an open slot; if the user asks, any future time works, outside hours or notice. Emails them a confirmation (texts if set up); confirm with the user first. A clash returns booked:false + conflicts; retry with allowOverlap only if the user agrees.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | slots: last date, inclusive. | |
| from | No | slots: first date, YYYY-MM-DD in the meeting type's timezone. | |
| name | No | book, no contactId: who it is with (a contact is found or made). | |
| No | |||
| phone | No | ||
| action | Yes | ||
| startAt | No | book: ISO 8601. Any future time: the user may override the meeting type's hours, notice and booking window. | |
| contactId | No | book: the contact. Their email/phone are used. | |
| allowOverlap | No | book: over something already on the calendar. | |
| meetingTypeId | Yes | From meeting_types_list. |
meeting_types_listARead-onlyIdempotentInspect
List booking meeting types (the public links people book through): name, slug, duration, availability, questions. Also says whether Google Calendar is connected, since its busy times are kept free.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered. The description adds value by enumerating what the listing contains (name, slug, duration, availability, questions) and disclosing the Google Calendar connection status and why (busy times kept free).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, zero waste, purpose front-loaded before the secondary Calendar detail. Each clause carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden, and it does so by listing the key fields. It stops short of describing pagination or ordering, but for a parameterless read tool this is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so per the baseline there is nothing to document; schema coverage is 100% and empty. Full credit baseline applies minus nothing of note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (List) plus resource (booking meeting types) and a clarifying gloss ('the public links people book through'). This clearly separates it from siblings meeting_types_create/update/delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The read-oriented role is implied by 'List', but there is no explicit statement of when to call this versus meeting_types_create/update/delete or other listing tools. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
meeting_types_manageDestructiveInspect
Booking meeting types (the public links). create (name, slug, and any of the fields update takes), update (changing slug breaks links already shared), delete (the link stops working; bookings stay; confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | ||
| slug | No | ||
| action | Yes | ||
| isActive | No | false hides it from booking. | |
| location | No | ||
| bufferMin | No | Minutes kept free after each booking. | |
| description | No | ||
| durationMin | No | Minutes. Default 30. | |
| availability | No | ||
| locationType | No | ||
| maxAdvanceDays | No | ||
| minNoticeHours | No | ||
| intakeQuestions | No | ||
| reminderSmsHours | No |
notes_listARead-onlyIdempotentInspect
List the notes on a contact, company or deal (pass exactly one of contactId / companyId / dealId).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default 50. | |
| dealId | No | ||
| offset | No | ||
| companyId | No | ||
| contactId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds the mutual-exclusivity rule but says nothing about pagination behavior or result shape, so it adds only modest context beyond structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the key constraint in parentheses, front-loaded after the verb+resource. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter list tool with no output schema and 0 required parameters, the description covers the critical selection rule but omits pagination defaults/limits interaction and expected return content. Adequate but with visible gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at only 20%, the description carries real weight by clarifying that the three ID parameters are mutually exclusive and one is required — a constraint the schema does not express. It leaves limit/offset semantics to the schema, so it compensates without being complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (notes) along with the three entity types they attach to. It doesn't explicitly name sibling tools, but the CRUD siblings (notes_create/update/delete) make the scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage constraint: pass exactly one of contactId/companyId/dealId. That is clear invocation guidance, though it doesn't state when to prefer this over other read tools or mention prerequisites/permissions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notes_manageDestructiveInspect
Notes on a contact, company or deal. create (body, plus contactId / companyId / dealId), update, delete (confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| body | No | ||
| action | Yes | ||
| dealId | No | ||
| companyId | No | ||
| contactId | No |
outbound_webhooks_manageADestructiveInspect
Outbound webhooks: Groundbase POSTs to a URL when subscribed events fire. action list | get | create | update | delete. create needs name, url, events and returns the signing secret ONCE (tell the user). create, or a new url, sends CRM data (names, emails, phones) there and emails the owner: confirm the url with the user first. delete stops deliveries and abandons retries; confirm first.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | For get/update/delete. | |
| url | No | Public http(s) URL (use https: the payload is CRM data). Required on create. | |
| name | No | Required on create. | |
| action | Yes | ||
| events | No | Event names, or ["*"] for all: contact|company.created/updated/deleted, deal.created/updated/deleted/stage_changed/won/lost, task.created/updated/completed/deleted, note.created, tag.applied/removed, sms.sent/received/delivered/failed, call.completed, voicemail.received, email.sent/received, invoice.issued/paid/voided, payment.recorded, quote.issued/accepted/declined, form.submitted, meeting.booked/rescheduled/cancelled. Slack and Discord webhook URLs get a readable message; others get signed JSON. | |
| isActive | No | Update only; false pauses delivery. | |
| description | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the annotations: it discloses that create returns the signing secret ONCE, that create/new URL sends CRM data (names, emails, phones) externally, that the owner gets emailed, and that delete stops deliveries and abandons retries. These are critical operational details not captured in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded and highly structured: it opens with the core mechanism, then action list, then critical behavioral warnings in order of importance. Every sentence adds distinct value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description compensates by explaining what create returns (signing secret ONCE) and what delete does (stops deliveries, abandons retries). It covers the full CRUD lifecycle, external side effects, confirmation requirements, and security implications—complete for a mutation tool with destructive capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 71%, but the description adds critical meaning: it explains that create returns the signing secret once, emphasizes confirming the URL with the user, and notes that URL should be https because payload is CRM data. It contextualizes the events parameter's role and the create/update schema requirements.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource combination: Groundbase POSTs to a URL when subscribed events fire, with actions clearly enumerated. It distinguishes itself from the sibling inbound_webhooks_manage by specifying outbound direction and the POST-to-URL mechanism.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear action routing (list | get | create | update | delete) and specifies that create requires name, url, and events. It includes critical confirmation guidance ('confirm the url with the user first' and 'confirm first' for delete) but doesn't explicitly state when NOT to use this tool for certain scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
phone_statusRead-onlyIdempotentInspect
The user's phone numbers (id, number, label, which is the default for texts and calls) and their Twilio balance as Twilio reports it (quote it; do not judge it).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
quotes_listARead-onlyIdempotentInspect
List quotes with counts per status and open value per currency, or pass id for one quote with lines, totals, deposit and acceptance details.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Quote id. Returns that one quote. | |
| status | No | draft | open | accepted | declined | void | expired (open but past valid-until) | |
| companyId | No | ||
| contactId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), so the description's main contribution is return-shape context: counts per status, open value per currency, and single-quote lines/totals/deposit/acceptance details. It does not mention pagination, permissions, or rate limits, but it adds useful behavioral detail beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted words, presenting list mode first and the id-based detail mode second. Every phrase contributes to either behavior or invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list/detail tool with no output schema, the description does supply return values for both modes and annotations cover safety. However, it omits any explanation of companyId/contactId filtering, and it provides no pagination or scope expectations, so an agent lacks some context needed to use the filtering parameters confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%; id and status are documented in the schema, while companyId and contactId have no descriptions anywhere. The description reinforces the id mode and adds return detail, but it never explains companyId/contactId filtering, leaving a substantial semantic gap for two of four parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific verb 'List' and resource 'quotes', and distinguishes two modes: aggregate listing and single-quote retrieval by id. It is clearly a read/list operation amid quote-mutating siblings such as quotes_send and quotes_void.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for two invocation modes: omit id for status/count/value aggregation, or pass id for one quote with line-level detail. It does not explicitly name when to avoid this tool or point to an alternative, but no sibling provides a competing quote-list capability.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
quotes_manageDestructiveInspect
Quotes. save_draft (create, or edit by id), issue (numbers it), send (emails it with an accept link; confirm), record_outcome (accepted / declined after a conversation), convert (accepted → draft invoice), void, public_link (the accept link; revoke).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Edit this draft. Omit to create. | |
| to | No | Default: billing email, then the contact's email. | |
| lines | No | Line items: itemId (saved item, priced in this currency) or name + unitPrice for a one-off. Amounts are decimal strings. | |
| notes | No | ||
| terms | No | What the customer agrees to by accepting. | |
| action | Yes | ||
| reason | No | Declined: optional reason. | |
| revoke | No | public_link: turn the link off. | |
| charges | No | Charges below the subtotal (shipping, rush fee); a negative amount for a deposit or discount. | |
| message | No | Covering note; same tokens. | |
| outcome | No | ||
| sendVia | No | ||
| subject | No | Tokens {number} {business} {customer} {amount} {due}. | |
| currency | No | ISO 4217. Defaults from the billing profile. | |
| companyId | No | ||
| contactId | No | Create: one of contactId/companyId. | |
| issueDate | No | YYYY-MM-DD. Default today. | |
| validUntil | No | YYYY-MM-DD. Default issue date + 30 days. | |
| depositAmount | No | e.g. "500.00". Empty string removes. | |
| acceptedByName | No | Accepted: who said yes, e.g. "Dana (by phone)". | |
| depositPercent | No | e.g. "25". Empty string removes. |
resend_manageADestructiveInspect
The BYO Resend connection for email campaigns. Actions: status; enable_tracking (installs the delivery/open/click webhook); domains (verification state; check before choosing from_email); disconnect (wipes credentials); test_send (a real email to to). Confirm disconnect and the test_send address first. Connecting happens only in the app (Settings > Email), never by pasting a key here.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | test_send recipient. | |
| html | No | ||
| text | No | ||
| action | Yes | ||
| subject | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (destructiveHint=true, openWorldHint=true, non-idempotent). The description adds value beyond that: disconnect 'wipes credentials,' enable_tracking installs a webhook, test_send sends a real email, and the confirmation warning for destructive actions. A genuine addition over the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Tight and front-loaded: the identity sentence leads, actions are enumerated compactly, then safety/confirmation notes. Every clause carries non-redundant information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the multi-action tool well: which action does what, destructive-action confirmation, and the app-only connection constraint. Without an output schema, it should describe return shape for status/domains/test_send, which it does not, leaving a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 20%, so the description must partially compensate. It names 'to' for test_send and the from_email concept, and clarifies that action selects among five named behaviors, but html, text, and subject are undocumented anywhere. Baseline 3 with a partial gap remaining.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States what the tool is (BYO Resend connection management) and enumerates all five actions with parenthetical detail (enable_tracking installs webhooks, domains shows verification state). This clearly distinguishes it from siblings like email_send or sending_settings, but the top-level purpose is framed as a noun phrase rather than a single verb+resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit procedural guidance: check domains before choosing from_email, confirm disconnect and the test_send address first, and connecting happens only in-app never by pasting a key. Strong when/why context. No explicit exclusions against, e.g., email_send for sending actual campaign mail, so it falls short of 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
saved_views_listARead-onlyIdempotentInspect
List saved views (named filters over contacts, companies, deals or tasks).
| Name | Required | Description | Default |
|---|---|---|---|
| entityType | No | Only views for this record type. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is fully covered. The description adds useful domain context by defining saved views as named filters, but says nothing about return shape, ordering, or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One efficient sentence with the resource and clarifying definition front-loaded; nothing is wasted, though the definition could be slightly more informative for the same length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with one optional parameter, full schema coverage, and annotations covering safety, the description supplies what an agent needs. No output schema exists, so return values need not be described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a single optional enum parameter that the schema fully documents. The description's enumeration of 'contacts, companies, deals or tasks' mirrors the enum rather than adding new semantics, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (saved views), and the parenthetical defines what a saved view is and which entity types they cover. It is clearly distinguishable from saved_views_create and saved_views_delete, though it does not explicitly name those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the agent can infer this is the read tool for saved views, but there is no explicit when-to-use guidance, no mention of prerequisites, and no routing to alternative tools such as listing contacts or deals directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
saved_views_manageDestructiveInspect
Saved views (named filters). create (copy filterJson's shape from saved_views_list), update (rename or change the filter), delete (the records stay).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | ||
| action | Yes | ||
| entityType | No | ||
| filterJson | No | JSON-encoded filter. |
sending_settingsAInspect
Daily cap on campaign EMAILS (not SMS) per day in the account timezone. get: cap, sent_today, remaining_today, domain_caps. set: daily_email_send_cap (null = none, 0 = stop today), account-wide or, with domain, for one domain inside it. Over-cap recipients wait for later days. Use to warm a new domain (~20/day).
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| domain | No | set: bare hostname, e.g. 'example.com'. Omit for the account-wide cap. | |
| daily_email_send_cap | No | set: non-negative integer or null. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give the generic safety profile (readOnlyHint=false, destructiveHint=false), so the description carries most of the load. It discloses non-obvious behavior: null=none, 0=stop today, that over-cap recipients wait for later days, and that the cap applies in the account timezone. It doesn't explain reversibility or auth/permission requirements, but the added context is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is dense but well front-loaded, opening with the resource, then get semantics, then set semantics, then usage. Most sentences earn their place, though the get/set token lists are tightly packed and could be marginally cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description helpfully enumerates what get returns, and it covers behavior and value semantics for all three parameters. Given no output schema exists it is nearly complete; only auth/permission context and the read/write split of the mixed get/set action are left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the description meaningfully extends it: it clarifies the two get/set actions, that 'domain' scopes to one domain vs account-wide, and the null/0 semantics of daily_email_send_cap. It also documents the get return values (cap, sent_today, remaining_today, domain_caps), which the schema does not cover.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource (daily cap on campaign EMAILS) and explicitly disambiguates it from the sibling SMS tools with '(not SMS)'. It also spells out both get and set behaviors, so an agent can tell exactly what this manages without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete use case ('Use to warm a new domain (~20/day)') and implicitly routes email-cap concerns here rather than to sms_send/sms_optouts. However, it doesn't state explicit when-not conditions or the exact prerequisite for setting a domain cap beyond the parameter description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sms_listRead-onlyIdempotentInspect
Read the text conversation with a phone or contactId (oldest first, both directions; matched: false if none), or pass scheduled: true to list texts queued to send.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Conversation only. Default 50. | |
| phone | No | The other party's number, any format. | |
| contactId | No | Or the contact (their primary number is used). | |
| scheduled | No | List pending scheduled texts instead. |
sms_manageDestructiveInspect
cancel_scheduled (a queued text, by id from sms_list scheduled), delete_thread (a whole conversation by phone or contactId; nothing is sent; confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| phone | No | ||
| action | Yes | ||
| contactId | No |
sms_sendAInspect
Send a text now, or later with scheduledAt. Sends a real message, billed per segment on the user's own Twilio account; confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| toPhone | Yes | Recipient, E.164 (+1...). | |
| contactId | No | Links the message to this contact's thread. | |
| fromNumber | No | Sending number, E.164. Defaults to the primary. | |
| scheduledAt | No | Future ISO 8601 time. Omit to send now. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic write/openWorld/non-idempotent profile; the description adds material behavior the annotations do not: it sends a real message, is cost-bearing ('billed per segment on the user's own Twilio account'), and requires user confirmation. These are exactly the traits an agent needs before invoking a non-idempotent outbound send.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, front-loaded with the action and its scheduling variant, then the cost/confirmation caveat. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent outbound send with annotations covering the safety profile and no output schema, the description covers cost, timing, and the confirmation requirement. It stops short of noting delivery-failure or opt-out handling, which would complete the picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 80%, with toPhone, contactId, fromNumber, and scheduledAt all documented in the schema. The description only reinforces the scheduledAt meaning, adding little beyond what structured fields provide, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send a text') and adds the scheduling dimension ('now, or later with scheduledAt'). It is clearly distinguishable from sms_list and sms_cancel_scheduled by its resource and action, though it does not explicitly name those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage directive: 'confirm with the user first,' which tells the agent this is a user-approval-gated action. It also clarifies the now-vs-later condition via scheduledAt, but states no when-not-to-use or explicit alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suppressions_manageDestructiveInspect
Who must not be messaged. channel email (unsubscribed / bounced addresses) or sms (numbers that texted STOP); action list, add (emails[] / phones[]) or remove (re-consents one; only with their permission). Confirm adds and removes with the user.
| Name | Required | Description | Default |
|---|---|---|---|
| No | |||
| limit | No | For list. Default 100, max 500. | |
| phone | No | For 'remove', or a single 'add'. | |
| action | Yes | ||
| emails | No | For add: up to 5000. | |
| phones | No | For 'add': up to 500 numbers, any format. | |
| search | No | For list: matches the address or contact name. | |
| source | No | Label for 'add'. Default 'imported'; 'stop_keyword' is reserved. | |
| channel | Yes |
tags_listBRead-onlyIdempotentInspect
List the user's tags with their ids.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide a complete safety profile (readOnlyHint, idempotentHint, destructiveHint=false, openWorldHint=false), so the description does not need to restate safety. It adds only that results are scoped to the user's tags and include ids, which is modest context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action and return content with no wasted words. It is appropriately sized for a simple list operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only list tool with no output schema, the description covers the core action and says ids are returned. However, it omits return shape details such as ordering, pagination, or whether additional tag metadata is included, and it does not distinguish this from merge_tags_list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero input parameters, so there are no parameter semantics to document. The description's mention of 'ids' refers to returned tag identifiers rather than inputs, and the baseline for a parameterless tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), resource ('tags'), and scope ('user's tags'), and adds that ids are included. It clearly separates the tool from create/update/delete/apply tag operations, but does not differentiate it from the sibling merge_tags_list tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no explicit when-to-use guidance, no conditions or exclusions, and does not point to alternatives such as merge_tags_list. Usage is only implied by the verb 'List'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tags_manageDestructiveInspect
Tags. create, update (rename / recolour), delete (removes it from everyone; confirm first), apply (tagId to contactIds; remove: true takes it off). Applying a tag can start workflows listening for it.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | ||
| color | No | Hex, e.g. "#B91C1C". | |
| tagId | No | ||
| action | Yes | ||
| remove | No | Remove the tag instead of adding it. | |
| contactIds | No |
tasks_listRead-onlyIdempotentInspect
List tasks, events and meetings (default: open items of every kind), or pass id to fetch one. Google Calendar events, when connected, are included as kind event. In the apps these are on the Calendar page. color_id is the Google Calendar colour: 1 Lavender, 2 Sage, 3 Grape, 4 Flamingo, 5 Banana, 6 Tangerine, 7 Peacock, 8 Graphite, 9 Blueberry, 10 Basil, 11 Tomato; null is the default.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Task id. Returns that one item. | |
| to | No | ISO 8601; due on/before. | |
| from | No | ISO 8601; due on/after. | |
| kind | No | ||
| limit | No | ||
| dealId | No | ||
| offset | No | ||
| status | No | ||
| contactId | No |
tasks_manageDestructiveInspect
Tasks, events and meetings (the Calendar page in the apps). create (a meeting texts the contact only with textContact: true; ask first), update (status "done" completes; contactId/companyId/dealId relink; moving a meeting re-sends its texts), delete (confirm; repeating tasks need scope; remove_from_google only if the user says).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| kind | No | Default task. | |
| color | No | Calendar colour, the same palette as Google Calendar; syncs both ways. "default" = the colour of its kind. | |
| dueAt | No | ISO 8601, for tasks. | |
| endAt | No | ISO 8601. | |
| notes | No | ||
| scope | No | Repeating tasks: "occurrence" deletes this date only, "series" the whole series. A series' first task takes "series" only (to skip its date, change the start date). | |
| title | No | ||
| action | Yes | ||
| dealId | No | ||
| status | No | ||
| startAt | No | ISO 8601, for events/meetings. | |
| location | No | ||
| companyId | No | ||
| contactId | No | ||
| recurrence | No | Repeats relative to dueAt. Tasks only. | |
| textContact | No | Meetings: text the contact a confirmation and reminders. Default false. | |
| remove_from_google | No | Default false. True also removes it from Google Calendar: the event, or for scope "occurrence" just that date. Only after the user confirms. |
templates_listARead-onlyIdempotentInspect
List SMS and/or email templates (name, body, subject), or pass id to fetch one.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Template id. Returns that one template. | |
| type | No | Omit for both. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the returned field set (name, body, subject), which is genuinely useful, but says nothing about pagination, limits, or ordering for a list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the list behavior and appends the fetch-by-id variant. No filler, no repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the returned fields, and the safety profile is carried by annotations. Minor gaps remain around list size, ordering, and pagination for a tool whose primary job is enumeration.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented with the same semantics ('Returns that one template', 'Omit for both'). The description largely restates the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (SMS/email templates), names the fields returned, and covers the single-fetch mode in the same sentence. An agent can distinguish this from templates_create/update/delete without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives in-tool guidance (pass `id` to fetch one; type enum 'omit for both') but no routing guidance relative to templates_create, templates_update, or templates_delete. Usage is implied by the verb rather than stated as when/when-not.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
templates_manageDestructiveInspect
Saved message templates (type sms or email; email needs a subject). create, update, delete (confirm first). Merge tags: custom_fields_list with mergeTags.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| body | No | ||
| name | No | ||
| type | No | ||
| action | Yes | ||
| subject | No | Email only; required there. |
time_listARead-onlyIdempotentInspect
List time entries (newest first) plus the running timer and per-customer totals (default last 30 days). status "unbilled" = billable, stopped, not on a live invoice.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO 8601, exclusive. | |
| from | No | ISO 8601, inclusive. | |
| limit | No | Default 50, max 500. | |
| dealId | No | Also fills in the deal's contact and company. | |
| status | No | ||
| companyId | No | ||
| contactId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), but the description adds real behavioral context beyond them: newest-first ordering, aggregate outputs (running timer, per-customer totals), the 30-day default span, and a definition of the 'unbilled' status. It omits pagination behavior and the limit interaction with results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with what is returned and how it is ordered, followed by the non-obvious status semantics. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description must describe returns, and it does (entries, running timer, totals). Default window and ordering are covered; only pagination/limit behavior and the role of the ID filters remain missing for a 7-param read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 57%, with three ID filters (dealId, companyId, contactId) and limit undocumented in both places. The description compensates partly by explaining the 'unbilled' enum value and implying the default last-30-days semantics for from/to, but leaves the remaining filters unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (List) and resource (time entries) with scoping detail: newest-first ordering, inclusion of the running timer and per-customer totals, and a default 30-day window. It does not explicitly contrast itself with siblings like time_log or time_update, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied (a read/list tool for time entries) and a sensible default window is given, but there is no explicit when-to-use guidance or naming of alternatives such as time_log, time_update, or time_timer_start/stop. An agent must infer the routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
time_manageDestructiveInspect
Time tracking. start (the timer, for a contact / company / deal; stops any running one), stop, log (time after the fact), update (edit an entry), delete, bill (entryIds onto a draft invoice), unbill (take one back off).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| rate | No | Hourly, decimal string. | |
| action | Yes | ||
| dealId | No | Also fills in the deal's contact and company. | |
| delete | No | ||
| endedAt | No | ISO 8601. | |
| billable | No | Default true. | |
| currency | No | Default: invoicing currency. | |
| duration | No | ||
| entryIds | No | bill: from time_list (status unbilled). | |
| companyId | No | ||
| contactId | No | ||
| invoiceId | No | bill: a draft invoice. | |
| startedAt | No | ISO 8601. | |
| description | No |
voicemail_drops_dropAInspect
Play a drop onto someone's voicemail via a real Twilio call (hangs up if a person answers), billed at Twilio voice rates on the user's account. US and Canadian numbers only. Give contactId or toPhone. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| dropId | Yes | A drop with has_audio. | |
| toPhone | No | E.164, when there is no contact. | |
| contactId | No | Uses the contact's primary phone. | |
| fromNumberId | No | Twilio number id. Default: first active number. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only declare the generic safety profile (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false). The description adds behavior the annotations cannot convey: the call hangs up if a human answers, it bills at Twilio voice rates on the user's account, it is geo-restricted to US/Canada, and the user must confirm first.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action and its key side effect (hang-up on human answer), followed by cost/geo constraints and invocation guidance. Nothing is padded or repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent, world-affecting outbound action with no output schema, the description covers the mechanism, the human-answer behavior, the billing consequence, the geo boundary, and the confirmation requirement. Nothing material an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by clarifying that contactId and toPhone are the two mutually alternative recipient paths ('Give contactId or toPhone'), which the schema lists as independent properties without stating the either/or relationship.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Play a drop onto someone's voicemail via a real Twilio call') and immediately distinguishes this tool from the CRUD siblings voicemail_drops_create/update/list/delete by describing the actual action rather than a record operation. An agent can tell what it does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete invocation guidance ('Give contactId or toPhone') and an explicit procedural requirement ('Confirm with the user first'), plus a hard eligibility constraint (US and Canadian numbers only). It stops short of naming a specific alternative tool or a when-not-to-use case, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voicemail_drops_listARead-onlyIdempotentInspect
List voicemail drops: name, has_audio (only drops with audio can be dropped), duration_ms, source, script_text.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. With no output schema, the description usefully enumerates the fields the agent will receive (name, has_audio, duration_ms, source, script_text) and flags the domain constraint that only drops with audio can be used by voicemail_drops_drop. It omits ordering, pagination, and volume behavior, keeping this below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence, verb-front-loaded, with every element carrying information and no filler. The parenthetical aside about has_audio slightly interrupts the field enumeration but adds genuine value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter list tool with no output schema, the description supplies the essential return field set, which is the main gap it needed to fill. However it says nothing about result volume, ordering, or whether results are paginated, which an agent calling a list endpoint would benefit from knowing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The field list in the description refers to returned data rather than inputs, which is appropriate for a parameterless lister.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (voicemail drops), and is easily distinguished from the sibling mutations voicemail_drops_create/delete/drop/update. It does not explicitly say it returns all drops in the account or how it relates to the other voicemail tools, so it stops just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of prerequisites, and no references to alternative tools such as voicemail_drops_drop despite that tool being directly related ('only drops with audio can be dropped'). The agent must infer the role of this tool from its name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
voicemail_drops_manageDestructiveInspect
Voicemail drops. create (name; with script its audio is made in Emma's voice, billed per character: confirm the script), update (rename, or a new script regenerates the audio, billed), delete (confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | Default "Untitled drop". | |
| action | Yes | ||
| script | No | Up to 2000 chars (~2 min). Inline tags like [warm], [chuckles] work. |
workflows_listARead-onlyIdempotentInspect
List workflows (trigger, step count, active state, last run). Pass id for one workflow's full definition, or id with runs: true for its run history (newest first, with per-step results explaining skips and failures).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Workflow id. | |
| runs | No | With id: return run history instead. | |
| limit | No | Runs to return. Default 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: run history is newest-first and includes per-step results explaining skips and failures. It stops short of describing pagination or limits, but adds meaningful return-context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both dense with useful routing information, with the base list behavior front-loaded before the conditional modes. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with full schema coverage and no output schema, this description covers the primary modes, ordering, and content of results well. Minor gap: it never mentions the `limit`/pagination behavior, which the agent must infer from the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage the baseline is 3, but the description goes further by explaining the interaction between `id` and `runs: true` and the ordering/content of run output, which the schema only states tersely ('With id: return run history instead'). It does not mention the `limit` parameter, leaving that entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('List workflows') and enumerates the returned fields (trigger, step count, active state, last run). It clearly distinguishes the three usage modes (all workflows, one full definition, run history) so an agent can identify the tool unambiguously among siblings like workflows_create/delete/run_now.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit conditional instructions: pass `id` for a single workflow's definition and `id` plus `runs: true` for run history. It does not state when *not* to use it or name alternatives, but the mode-selection guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
workflows_manageDestructiveInspect
Automations. create (a trigger and steps; active by default and then acts by itself, so confirm), update (isActive false pauses), delete (confirm first).
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | ||
| name | No | ||
| steps | No | Ordered steps, each { id?, type, config: {...} }. Types and config: send_sms { to?, body }; send_email { to?, subject, body_html?, body_text? } (blank to = the run's contact); add_to_campaign { campaign_id } (ongoing, sending campaigns only); apply_tag / remove_tag { tag_name }; create_note { body }; create_task { title, description?, due_at?, due_in_days?, kind?, location?, contact_id? }; fire_webhook { url, method?, headers?, body? }; update_field { field, value } (first_name, last_name, email, phone, position, city, source, notes, primary_phone, company_id); set_custom_field { field_key, value } ("cf." prefix optional); delay { delay_seconds, stop_if?: { reply?, meeting?, optout? } } (stop_if ends the run if the contact did that during the wait; top-level waits over 60s); branch { condition, then: [steps], else: [steps] }. Record-targeting steps also take entity_type/entity_id. Strings support {{first_name}}, {{trigger.event}}, {{steps.<id>.output.<key>}}; give steps an explicit id to keep those references stable. On 400 INVALID_WORKFLOW, fix what the message lists rather than retrying. | |
| action | Yes | ||
| isActive | No | Default true. | |
| condition | No | Skip the run (status skipped) unless true. { all|any: [{ field, op, value }] }. Fields: entity.<column>, cf.<field_key>, trigger.event|entity_type|entity_id, trigger.payload.<key> (not payload.<key>). Ops: equals, not_equals, contains, not_contains, starts_with, ends_with, is_set, is_not_empty, is_empty, includes_tag, greater_than, greater_or_equal, less_than, less_or_equal, older_than_days, newer_than_days. entity.last_contacted_at older_than_days N includes contacts never contacted (last_contacted_at empty). | |
| description | No | ||
| triggerType | No | ||
| triggerEvent | No | Event name, or inbound webhook id. | |
| triggerConfig | No | Scheduled only: { recurrence: one_time|hourly|daily|weekly, run_at?, time_of_day?, days_of_week?, minute_of_hour?, timezone?, audience?: { tags: [1-5 names] } }. With audience it runs once per contact carrying any tag (max 500, else the fire fails); without, once with no contact. |
workflows_run_nowAInspect
Run a workflow now on one existing record, bypassing its trigger. Its steps really execute (texts, emails, webhooks), so confirm with the user.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| entityId | Yes | ||
| entityType | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag it as a non-read-only, non-idempotent, open-world action, and the description adds critical undisclosed impact: steps really execute real-world texts, emails, and webhooks. The confirm-with-user warning is exactly the behavioral context an agent needs beyond the structured hints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and immediately followed by the safety-relevant consequence. Zero wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with annotations and no output schema, the description covers the action and its real-world side effects well. The main gap is parameter clarification, but overall an agent has enough to invoke it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the load, but it only implies 'one existing record' without clarifying that 'id' is the workflow id or that entityType/entityId designate the target record. It leaves the three required params largely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Run) and resource (workflow) with clear scope: on one existing record, bypassing its trigger. This distinctly separates it from the sibling workflows_create/list/update tools, which manage workflow definitions rather than executing one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Conveys the trigger context (running now bypasses it) and instructs the agent to confirm with the user first, which is real usage guidance. It stops short of naming explicit alternatives or when-not-to-use conditions, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
forms_manage1 field changed- added
Input schema / properties / styleAdded value: +{ + "description": "Appearance: { button_color, background_color, text_color: \"#rrggbb\", font: system|serif|rounded|mono }. {} resets to the default look. Replaces the whole style.", + "properties": { + "background_color": { + "type": "string" + }, + "button_color": { + "type": "string" + }, + "font": { + "enum": [ + "system", + "serif", + "rounded", + "mono" + ], + "type": "string" + }, + "text_color": { + "type": "string" + } + }, + "type": "object" +}
1 tool update
- Changed
tasks_manage1 field changed- added
Input schema / properties / colorAdded value: +{ + "description": "Calendar colour, the same palette as Google Calendar; syncs both ways. \"default\" = the colour of its kind.", + "enum": [ + "Lavender", + "Sage", + "Grape", + "Flamingo", + "Banana", + "Tangerine", + "Peacock", + "Graphite", + "Blueberry", + "Basil", + "Tomato", + "default" + ], + "type": "string" +}
105 tool updates
- Removed
addresses_create - Removed
addresses_delete - Removed
addresses_list - Added
addresses_manage - Removed
addresses_update - Removed
billing_profiles_list - Added
billing_profiles_manage - Removed
billing_profiles_save - Removed
companies_create - Removed
companies_delete - Changed
companies_list1 field changed- added
Input schema / properties / deletedAdded value: +{ + "description": "List recently deleted companies instead (to restore).", + "type": "boolean" +}
- Added
companies_manage - Removed
companies_update - Removed
contacts_create - Removed
contacts_delete - Changed
contacts_list6 fields changed- added
Input schema / properties / companyIdAdded value: +{ + "description": "Only contacts at this company.", + "type": "string" +} - added
Input schema / properties / deletedAdded value: +{ + "description": "List recently deleted contacts instead.", + "type": "boolean" +} - added
Input schema / properties / duplicatesAdded value: +{ + "description": "List groups of live contacts sharing an email or phone instead.", + "type": "boolean" +} - added
Input schema / properties / sortAdded value: +{ + "description": "recent = last contacted. Default name.", + "enum": [ + "name", + "created", + "updated", + "recent" + ], + "type": "string" +} - added
Input schema / properties / tagAdded value: +{ + "description": "Only contacts with this tag (name or id).", + "type": "string" +} - added
Input schema / properties / unsubscribedAdded value: +{ + "description": "Opted out of any channel / email / texts, or none (for an audience).", + "enum": [ + "any", + "email", + "sms", + "none" + ], + "type": "string" +}
- Added
contacts_manage - Removed
contacts_update - Removed
custom_fields_create - Removed
custom_fields_delete - Changed
custom_fields_list1 field changed- added
Input schema / properties / mergeTagsAdded value: +{ + "description": "List merge tags instead.", + "type": "boolean" +}
- Added
custom_fields_manage - Removed
custom_fields_set_value - Removed
custom_fields_update - Changed
dashboard_summary1 field changed- added
Input schema / properties / pipelineAdded value: +{ + "description": "Per-stage open deals instead.", + "type": "boolean" +}
- Removed
deal_stages_create - Added
deal_stages_manage - Removed
deal_stages_update - Removed
deals_create - Removed
deals_delete - Changed
deals_list1 field changed- added
Input schema / properties / deletedAdded value: +{ + "description": "List recently deleted deals instead (to restore).", + "type": "boolean" +}
- Added
deals_manage - Removed
deals_update - Removed
email_accounts_list - Removed
email_get_thread - Removed
email_list_threads - Added
email_read - Removed
email_suppressions_manage - Added
email_thread_update - Removed
invoice_items_list - Added
invoice_items_manage - Removed
invoice_items_save - Added
invoice_payments_manage - Removed
invoice_payments_record - Removed
invoice_payments_reverse - Added
invoice_settings - Removed
invoice_settings_get - Removed
invoice_settings_update - Removed
invoices_issue - Changed
invoices_list7 fields changed- added
Input schema / properties / companyIdAdded value: +{ + "type": "string" +} - added
Input schema / properties / contactIdAdded value: +{ + "type": "string" +} - added
Input schema / properties / creditNotesAdded value: +{ + "description": "With id: its credit notes.", + "type": "boolean" +} - added
Input schema / properties / limitAdded value: +{ + "description": "Default 100.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / qAdded value: +{ + "description": "Matches number and customer.", + "type": "string" +} - added
Input schema / properties / recurringAdded value: +{ + "description": "With id: its repeat schedule (null if none).", + "type": "boolean" +}
- Added
invoices_manage - Removed
invoices_save_draft - Removed
invoices_send - Removed
invoices_void - Removed
meeting_types_create - Removed
meeting_types_delete - Added
meeting_types_manage - Removed
meeting_types_update - Removed
merge_tags_list - Removed
notes_create - Removed
notes_delete - Added
notes_manage - Removed
notes_update - Added
phone_status - Removed
quotes_convert - Removed
quotes_issue - Added
quotes_manage - Removed
quotes_record_outcome - Removed
quotes_save_draft - Removed
quotes_send - Removed
quotes_void - Removed
saved_views_create - Removed
saved_views_delete - Added
saved_views_manage - Removed
sms_cancel_scheduled - Changed
sms_list1 field changed- added
Input schema / properties / contactIdAdded value: +{ + "description": "Or the contact (their primary number is used).", + "type": "string" +}
- Added
sms_manage - Removed
sms_optouts - Added
suppressions_manage - Removed
tags_apply - Removed
tags_create - Removed
tags_delete - Added
tags_manage - Removed
tags_update - Removed
tasks_create - Removed
tasks_delete - Added
tasks_manage - Removed
tasks_update - Removed
templates_create - Removed
templates_delete - Added
templates_manage - Removed
templates_update - Removed
time_log - Added
time_manage - Removed
time_timer - Removed
time_update - Removed
twilio_balance_get - Removed
voicemail_drops_create - Removed
voicemail_drops_delete - Added
voicemail_drops_manage - Removed
voicemail_drops_update - Removed
workflows_create - Removed
workflows_delete - Added
workflows_manage - Removed
workflows_update
4 tool updates
- Added
meetings_book - Added
time_timer - Removed
time_timer_start - Removed
time_timer_stop
1 tool update
- Added
documents_manage
2 tool updates
- Changed
workflows_create1 field changed- changed
Input schema / properties / condition / descriptionPrevious value: -"Skip the run (status skipped) unless true. { all|any: [{ field, op, value }] }. Fields: entity.<column>, cf.<field_key>, trigger.event|entity_type|entity_id, trigger.payload.<key> (not payload.<key>). Ops: equals, not_equals, contains, not_contains, starts_with, ends_with, is_set, is_not_empty, is_empty, includes_tag, greater_than, greater_or_equal, less_than, less_or_equal, older_than_days, newer_than_days."New value: +"Skip the run (status skipped) unless true. { all|any: [{ field, op, value }] }. Fields: entity.<column>, cf.<field_key>, trigger.event|entity_type|entity_id, trigger.payload.<key> (not payload.<key>). Ops: equals, not_equals, contains, not_contains, starts_with, ends_with, is_set, is_not_empty, is_empty, includes_tag, greater_than, greater_or_equal, less_than, less_or_equal, older_than_days, newer_than_days. entity.last_contacted_at older_than_days N includes contacts never contacted (last_contacted_at empty)."
- Changed
workflows_update1 field changed- added
Input schema / properties / condition / descriptionAdded value: +"Skip the run (status skipped) unless true. { all|any: [{ field, op, value }] }. Fields: entity.<column>, cf.<field_key>, trigger.event|entity_type|entity_id, trigger.payload.<key> (not payload.<key>). Ops: equals, not_equals, contains, not_contains, starts_with, ends_with, is_set, is_not_empty, is_empty, includes_tag, greater_than, greater_or_equal, less_than, less_or_equal, older_than_days, newer_than_days. entity.last_contacted_at older_than_days N includes contacts never contacted (last_contacted_at empty)."
1 tool update
- Changed
tasks_delete2 fields changed- added
Input schema / properties / remove_from_googleAdded value: +{ + "description": "Default false. True also removes it from Google Calendar: the event, or for scope \"occurrence\" just that date. Only after the user confirms.", + "type": "boolean" +} - added
Input schema / properties / scopeAdded value: +{ + "description": "Repeating tasks: \"occurrence\" deletes this date only, \"series\" the whole series. A series' first task takes \"series\" only (to skip its date, change the start date).", + "enum": [ + "occurrence", + "series" + ], + "type": "string" +}
13 tool updates
- Changed
addresses_create1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
addresses_update1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
contacts_create1 field changed- added
Input schema / requiredAdded value: +[ + "firstName" +]
- Changed
deals_create3 fields changed- changed
Input schema / properties / closeAt / descriptionPrevious value: -"Expected close date, ISO 8601."New value: +"Expected close date, YYYY-MM-DD or ISO 8601." - removed
Input schema / properties / currencyRemoved value: -{ - "description": "ISO 4217. Defaults to the user's currency.", - "type": "string" -} - added
Input schema / properties / valueCents / descriptionAdded value: +"In the account's default currency (deals have no currency of their own)."
- Changed
deals_list2 fields changed- added
Input schema / properties / companyIdAdded value: +{ + "type": "string" +} - added
Input schema / properties / contactIdAdded value: +{ + "type": "string" +}
- Changed
deals_update3 fields changed- added
Input schema / properties / closeAt / descriptionAdded value: +"YYYY-MM-DD or ISO 8601; null clears it." - changed
Input schema / properties / closeAt / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Input schema / properties / currencyRemoved value: -{ - "type": "string" -}
- Changed
email_get_thread1 field changed- added
Input schema / properties / threadKey / descriptionAdded value: +"The `thread_id` from email_list_threads."
- Changed
email_list_threads1 field changed- changed
Input schema / properties / search / descriptionPrevious value: -"Matches subject, participant address and snippet."New value: +"Matches subject, sender and message text."
- Changed
email_suppressions_manage1 field changed- added
Input schema / properties / emails / maxItemsAdded value: +5000
- Changed
invoices_void1 field changed- added
Input schema / properties / confirm_paidAdded value: +{ + "description": "Void even though payments or credit notes are recorded on it. Only after the user has confirmed. Default false.", + "type": "boolean" +}
- Changed
outbound_webhooks_manage2 fields changed- changed
Input schema / properties / events / descriptionPrevious value: -"Event names, or [\"*\"] for all: contact|company.created/updated/deleted, deal.created/updated/deleted/stage_changed/won/lost, task.created/updated/completed/deleted, note.created, tag.applied/removed, sms.sent/received/delivered/failed, call.completed, voicemail.received, email.sent, invoice.issued/paid/voided, payment.recorded. Slack and Discord webhook URLs get a readable message; others get signed JSON."New value: +"Event names, or [\"*\"] for all: contact|company.created/updated/deleted, deal.created/updated/deleted/stage_changed/won/lost, task.created/updated/completed/deleted, note.created, tag.applied/removed, sms.sent/received/delivered/failed, call.completed, voicemail.received, email.sent/received, invoice.issued/paid/voided, payment.recorded, quote.issued/accepted/declined, form.submitted, meeting.booked/rescheduled/cancelled. Slack and Discord webhook URLs get a readable message; others get signed JSON." - changed
Input schema / properties / url / descriptionPrevious value: -"HTTPS. Required on create."New value: +"Public http(s) URL (use https: the payload is CRM data). Required on create."
- Changed
sms_optouts1 field changed- added
Input schema / properties / phones / maxItemsAdded value: +500
- Changed
workflows_run_now1 field changed- removed
Input schema / properties / payloadRemoved value: -{ - "description": "Extra trigger payload.", - "type": "object" -}
3 tool updates
- Changed
campaigns_manage1 field changed- added
Input schema / properties / contact_ids / maxItemsAdded value: +500
- Changed
tags_apply1 field changed- added
Input schema / properties / contactIds / maxItemsAdded value: +500
- Changed
tasks_create1 field changed- added
Input schema / properties / textContactAdded value: +{ + "description": "Meetings: text the contact a confirmation and reminders. Default false.", + "type": "boolean" +}
1 tool update
- Removed
frontdesk_settings
1 tool update
- Changed
campaigns_manage5 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "create", - "update", - "delete", - "duplicate", - "test_send", - "send_now", - "schedule", - "pause", - "resume", - "stop", - "add_recipients", - "preview_audience" -]New value: +[ + "list", + "get", + "create", + "update", + "delete", + "duplicate", + "test_send", + "send_now", + "schedule", + "pause", + "resume", + "stop", + "add_recipients", + "preview_audience", + "newsletter_templates" +] - changed
Input schema / properties / content / descriptionPrevious value: -"Single send. Email: { subject, preheader?, from_name?, from_email?, reply_to?, blocks: [{ type, props }] }; block types text {html}, header {html, level 1-3}, image {src, alt, width}, button {text, url, bgColor?}, divider {color?}, spacer {height}. from_email must be on a domain verified in Resend (resend_manage domains) or it fails per recipient at send time. reply_to should be a mailbox connected in Groundbase, or drip reply-exit cannot see replies. SMS: { body, media_urls? }. Merge tags like {{first_name}}, {{cf.<key>}} work in any string."New value: +"Single send. Email: { subject, preheader?, from_name?, from_email?, reply_to?, blocks: [{ type, props }] }; block types text {html}, header {html, level 1-3}, image {src, alt, width}, button {text, url, bgColor?}, divider {color?}, spacer {height}. from_email must be on a domain verified in Resend (resend_manage domains) or it fails per recipient at send time. reply_to should be a mailbox connected in Groundbase, or drip reply-exit cannot see replies. SMS: { body, media_urls? }. Merge tags like {{first_name}}, {{cf.<key>}} work in any string. Newsletter: content.kind 'newsletter' (one email, sent once). Extra blocks: section_header {title}; agent_card {photoUrl, name, title, phone, email, website, brokerage, note}; listing_card {imageUrl, status, price, address, beds, baths, sqft, url, buttonText}; market_stats {title, stats:[{label,value,change}], footnote}; quote {quote, author, role, avatarUrl}; footer {businessName, businessAddress, tagline, unsubText}. It will not send until the footer has a real business name and mailing address and no [bracketed] or $— placeholder is left anywhere; the refusal names the first one." - added
Input schema / properties / kindAdded value: +{ + "description": "list filter: newsletters, or everything else.", + "enum": [ + "newsletter", + "campaign" + ], + "type": "string" +} - added
Input schema / properties / roleAdded value: +{ + "description": "newsletter_templates: another industry's set (e.g. real estate, mortgage, insurance). Default: the user's own.", + "type": "string" +} - added
Input schema / properties / template_idAdded value: +{ + "description": "create: start a newsletter from this template (newsletter_templates). name defaults to the template name.", + "type": "string" +}
3 tool updates
- Added
email_suppressions_manage - Added
forms_manage - Changed
meeting_types_update1 field changed- changed
Input schema / properties / availability / descriptionPrevious value: -"{ days: [0-6, 0=Sunday], start: \"HH:MM\", end: \"HH:MM\", timezone?: IANA }."New value: +"{ days: [0-6, 0=Sunday], start: \"HH:MM\", end: \"HH:MM\", timezone?: IANA, overrides?: [{ date: \"YYYY-MM-DD\", start?, end? }] }. An override with no hours closes that date; with hours, replaces them that date. Send the whole object."
1 tool update
- Changed
workflows_create1 field changed- changed
Input schema / properties / triggerConfig / descriptionPrevious value: -"Scheduled only: { recurrence: one_time|hourly|daily|weekly, run_at?, time_of_day?, days_of_week?, minute_of_hour?, timezone? }."New value: +"Scheduled only: { recurrence: one_time|hourly|daily|weekly, run_at?, time_of_day?, days_of_week?, minute_of_hour?, timezone?, audience?: { tags: [1-5 names] } }. With audience it runs once per contact carrying any tag (max 500, else the fire fails); without, once with no contact."
1 tool update
- Changed
campaigns_manage1 field changed- added
Input schema / properties / audienceAdded value: +{ + "description": "duplicate: copy goes only to people the (sent, email) campaign reached who did not open it.", + "enum": [ + "non_openers" + ], + "type": "string" +}
120 tool updates
- Changed
activity_list3 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Scope to one company." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Scope to one contact's activity." - removed
Input schema / properties / dealId / descriptionRemoved value: -"Scope to one deal."
- Changed
addresses_create5 fields changed- changed
Input schema / properties / is_primary / descriptionPrevious value: -"Make this the primary address. The primary is what the contact screen shows first and what a CSV export writes. Setting it demotes the previous primary."New value: +"Make this the primary address (demotes the old one)." - changed
Input schema / properties / label / descriptionPrevious value: -"Short label, e.g. 'home', 'office', 'site'. Free text."New value: +"e.g. 'home', 'office'." - removed
Input schema / properties / notes / descriptionRemoved value: -"Anything else — access codes, \"rear entrance\"." - removed
Input schema / properties / postal_code / descriptionRemoved value: -"Postal or ZIP code." - removed
Input schema / properties / street / descriptionRemoved value: -"Street address line."
- Changed
addresses_delete1 field changed- removed
Input schema / properties / addressId / descriptionRemoved value: -"From addresses_list."
- Changed
addresses_list2 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"The company to read addresses for." - removed
Input schema / properties / contactId / descriptionRemoved value: -"The contact to read addresses for."
- Changed
addresses_update6 fields changed- removed
Input schema / properties / addressId / descriptionRemoved value: -"From addresses_list." - changed
Input schema / properties / is_primary / descriptionPrevious value: -"Make this the primary address. The primary is what the contact screen shows first and what a CSV export writes. Setting it demotes the previous primary."New value: +"Make this the primary address (demotes the old one)." - changed
Input schema / properties / label / descriptionPrevious value: -"Short label, e.g. 'home', 'office', 'site'. Free text."New value: +"e.g. 'home', 'office'." - removed
Input schema / properties / notes / descriptionRemoved value: -"Anything else — access codes, \"rear entrance\"." - removed
Input schema / properties / postal_code / descriptionRemoved value: -"Postal or ZIP code." - removed
Input schema / properties / street / descriptionRemoved value: -"Street address line."
- Removed
billing_profiles_create - Removed
billing_profiles_get - Changed
billing_profiles_list2 fields changed- added
Input schema / properties / companyIdAdded value: +{ + "type": "string" +} - added
Input schema / properties / contactIdAdded value: +{ + "type": "string" +}
- Added
billing_profiles_save - Removed
billing_profiles_update - Removed
calls_get - Changed
calls_list3 fields changed- removed
Input schema / properties / contactId / descriptionRemoved value: -"Limit to calls with this contact." - added
Input schema / properties / idAdded value: +{ + "description": "Call id. Returns that one call.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max records. Default 100, max 500."New value: +"Default 100, max 500."
- Changed
campaigns_analytics4 fields changed- removed
Input schema / properties / id / descriptionRemoved value: -"Campaign UUID." - added
Input schema / properties / limitAdded value: +{ + "description": "Recipients: default 100.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / recipientsAdded value: +{ + "description": "Return per-recipient status rows.", + "type": "boolean" +} - added
Input schema / properties / statusAdded value: +{ + "description": "Recipients filter.", + "enum": [ + "queued", + "sent", + "delivered", + "opened", + "clicked", + "bounced", + "unsubscribed", + "replied", + "failed" + ], + "type": "string" +}
- Removed
campaigns_list_recipients - Changed
campaigns_manage18 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"'list' returns user's campaigns. 'get' returns one by id. 'create' makes a draft (requires name + channel). 'update' patches a draft. 'delete' soft-deletes. 'duplicate' clones as a draft. 'test_send' fires one message to `to` without queuing recipients. 'send_now' resolves the audience and queues all recipients for dispatch. 'schedule' sets scheduled_at. 'pause' freezes. 'resume' un-pauses. 'stop' ends an ONGOING campaign (queued people dropped, sent ones kept). 'add_recipients' names contacts on a campaign by id: on a draft, scheduled or paused one they join the audience; on an ongoing campaign that is sending they are queued now, at the first message, under the campaign's rules." - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "create", - "update", - "delete", - "duplicate", - "test_send", - "send_now", - "schedule", - "pause", - "resume", - "stop", - "add_recipients" -]New value: +[ + "list", + "get", + "create", + "update", + "delete", + "duplicate", + "test_send", + "send_now", + "schedule", + "pause", + "resume", + "stop", + "add_recipients", + "preview_audience" +] - changed
Input schema / properties / audience_filter / descriptionPrevious value: -"For create/update. `audience_filter` shape: { all: [rules], any?: [rules] }. Rules are {type, ...}. Supported in v1: { type: \"all_contacts\" } — every contact with a valid channel address; { type: \"tag\", op: \"has\" | \"has_not\", value: \"<tag_name>\" } — tag membership filter. Multiple all[] rules AND together; any[] rules OR together. Behavior queries (opened campaign X / clicked X) and custom-field queries arrive in a follow-up."New value: +"{ all: [rules], any?: [rules] }. Rules: { type: \"all_contacts\" } or { type: \"tag\", op: \"has\"|\"has_not\", value: \"<tag name>\" }. all[] ANDs, any[] ORs." - changed
Input schema / properties / contact_ids / descriptionPrevious value: -"For add_recipients: contact ids, at most 500."New value: +"add_recipients: up to 500." - changed
Input schema / properties / content / descriptionPrevious value: -"For create/update, single-send. `content` for email = { subject, preheader?, from_name?, from_email?, reply_to?, blocks: [...] }. `from_email` may be any address on ANY domain verified in the connected Resend account — call resend_manage(action='domains') first to see which are verified. An unverified domain is not rejected here; it fails later, at send time, per recipient. `reply_to` sets where replies land — use it when replies should go somewhere other than from_email. IMPORTANT for drip campaigns: exit_on:{reply} can only fire for replies Groundbase can SEE, which means an address on a mailbox connected under Settings -> Email. Point reply_to at an unconnected address and the user still gets their replies, but reply-exit stays blind and the drip keeps sending to people who answered. Settable per step as well as per campaign. Each block is { type, props }. Block types: text (props.html: HTML), header (props.html: text, props.level: 1|2|3), image (props.src: url, props.alt, props.width), button (props.text, props.url, props.bgColor?), divider (props.color?), spacer (props.height: px). `content` for SMS = { body: text, media_urls?: [urls] }. Merge tags inside any string field: {{first_name}}, {{last_name}}, {{full_name}}, {{email}}, {{phone}}, {{company_name}}, {{cf.<custom_field_key>}}. Unknown tags render empty."New value: +"Single send. Email: { subject, preheader?, from_name?, from_email?, reply_to?, blocks: [{ type, props }] }; block types text {html}, header {html, level 1-3}, image {src, alt, width}, button {text, url, bgColor?}, divider {color?}, spacer {height}. from_email must be on a domain verified in Resend (resend_manage domains) or it fails per recipient at send time. reply_to should be a mailbox connected in Groundbase, or drip reply-exit cannot see replies. SMS: { body, media_urls? }. Merge tags like {{first_name}}, {{cf.<key>}} work in any string." - changed
Input schema / properties / enrolment_mode / descriptionPrevious value: -"For create/update. 'once' (default) settles its audience when it starts and finishes when the last message goes. 'ongoing' stays sending until action='stop' and takes new entrants at any time: the audience filter is re-run every five minutes, add_recipients works while it sends, and a workflow add_to_campaign step can enrol someone. Cannot be changed to 'once' while sending — stop it instead."New value: +"'once' (default) fixes its audience at start. 'ongoing' keeps sending until stop and takes new entrants (filter re-run every 5 min, add_recipients, workflow add_to_campaign)." - changed
Input schema / properties / id / descriptionPrevious value: -"Campaign UUID — required for everything except list+create."New value: +"Campaign id; needed for all but list, create, preview_audience." - changed
Input schema / properties / q / descriptionPrevious value: -"Free-text name search for action=list."New value: +"list: name search." - changed
Input schema / properties / scheduled_at / descriptionPrevious value: -"Unix seconds for schedule/create."New value: +"Unix seconds." - changed
Input schema / properties / sending_window / descriptionPrevious value: -"For create/update. `sending_window` restricts when this campaign may send: { days: [0-6, 0=Sunday], start_hour: 0-23, end_hour: 1-24, timezone?: IANA or 'auto' }. end_hour is exclusive and must exceed start_hour. 'auto' (the default) means the account owner's timezone. A step falling due outside the window WAITS — the recipient stays queued and sends at the next open hour. Nothing fails or is skipped. Omit or pass null for no restriction."New value: +"{ days: [0-6, 0=Sunday], start_hour: 0-23, end_hour: 1-24 (exclusive), timezone?: IANA or 'auto' (account tz) }. Sends due outside the window wait for the next open hour. null = no restriction." - changed
Input schema / properties / status / descriptionPrevious value: -"Filter for action=list."New value: +"list filter." - changed
Input schema / properties / steps / descriptionPrevious value: -"For create/update when send_mode='drip'. `steps` authors a DRIP campaign (requires send_mode='drip'). Array of { delay_seconds, content_json, exit_on?, channel? } in order. `content_json` is the canonical key; `content` is accepted as an alias. Until 2026-08-30 this doc said `content` while the dispatcher read only `content_json`, so steps authored from this description silently sent step 0 every time. Step 0 fires when the campaign starts; every later step fires delay_seconds after THAT recipient's actual previous send, so a step held back by a sending window or the daily cap still spaces correctly. Each step's `content` uses the same block format as the single-send `content` param. `exit_on` is { reply?, open?, click?, meeting? } — when true and the contact has done that since the previous step, the rest of the drip is skipped for them. `channel` overrides the campaign channel for that step alone (mixed email/SMS drips); it also decides whether the step counts against the daily EMAIL cap."New value: +"Drip steps (send_mode 'drip'): [{ delay_seconds, content_json, exit_on?, channel? }]. Step 0 sends at start; each later step sends delay_seconds after that recipient's previous actual send. exit_on { reply?, open?, click?, meeting? } skips the rest for a contact who did that. channel overrides the campaign channel for the step." - removed
Input schema / properties / steps / items / properties / channel / descriptionRemoved value: -"Overrides the campaign channel for this step only." - changed
Input schema / properties / steps / items / properties / content / descriptionPrevious value: -"Alias for content_json, accepted for compatibility."New value: +"Alias of content_json." - changed
Input schema / properties / steps / items / properties / content_json / descriptionPrevious value: -"Message for this step. Same shape as the top-level content param. Canonical key."New value: +"Same shape as content." - removed
Input schema / properties / steps / items / properties / delay_seconds / descriptionRemoved value: -"Seconds after the previous step's actual send. Step 0 should be 0." - removed
Input schema / properties / steps / items / properties / exit_on / descriptionRemoved value: -"Skip the rest of the drip for a contact who has replied/opened/clicked, or booked a meeting." - changed
Input schema / properties / to / descriptionPrevious value: -"For action='test_send' — recipient email or phone."New value: +"test_send recipient."
- Removed
campaigns_preview_audience - Changed
companies_create2 fields changed- removed
Input schema / properties / name / descriptionRemoved value: -"Company name. Required." - changed
Input schema / properties / website / descriptionPrevious value: -"https:// URL."New value: +"Include https://."
- Removed
companies_get - Changed
companies_list4 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Company id. Returns that one company.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (default 50)."New value: +"Default 50." - removed
Input schema / properties / offset / descriptionRemoved value: -"Pagination offset (default 0)." - changed
Input schema / properties / search / descriptionPrevious value: -"Free-text search across company name + website."New value: +"Matches name and website."
- Changed
contacts_create4 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Existing company UUID, if linking." - removed
Input schema / properties / notes / descriptionRemoved value: -"Free-text notes to attach on creation." - changed
Input schema / properties / phone / descriptionPrevious value: -"Primary phone. Will be normalized to E.164."New value: +"Normalised to E.164." - changed
Input schema / properties / tags / descriptionPrevious value: -"Tag names; created on the fly if missing."New value: +"Tag names; missing ones are created."
- Removed
contacts_get - Changed
contacts_list4 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Contact id. Returns that one contact; other filters ignored.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max results (1-1000, default 50)."New value: +"Default 50." - removed
Input schema / properties / offset / descriptionRemoved value: -"Pagination offset, default 0." - changed
Input schema / properties / search / descriptionPrevious value: -"Free-text search across name, email, phone."New value: +"Matches name, email, phone."
- Changed
contacts_update1 field changed- removed
Input schema / properties / id / descriptionRemoved value: -"Contact UUID."
- Changed
custom_fields_create5 fields changed- removed
Input schema / properties / entityType / descriptionRemoved value: -"Which entity gets this custom field." - changed
Input schema / properties / fieldKey / descriptionPrevious value: -"Optional — explicit identifier (snake_case, ≤60 chars). Defaults to a slug of `name`."New value: +"snake_case, max 60 chars." - changed
Input schema / properties / name / descriptionPrevious value: -"Human label, e.g. \"Loan amount\" or \"Referral source\"."New value: +"Label, e.g. \"Loan amount\"." - changed
Input schema / properties / options / descriptionPrevious value: -"For type=select only: the list of allowed values, e.g. [\"Hot\", \"Warm\", \"Cold\"]."New value: +"Required for type select." - removed
Input schema / properties / type / descriptionRemoved value: -"Field type. `select` requires the `options` array."
- Changed
custom_fields_delete1 field changed- removed
Input schema / properties / id / descriptionRemoved value: -"Custom field UUID."
- Changed
custom_fields_list1 field changed- changed
Input schema / properties / entityType / descriptionPrevious value: -"Optional — filter to fields on one entity type. Omit for all."New value: +"Omit for all."
- Changed
custom_fields_set_value4 fields changed- removed
Input schema / properties / entityId / descriptionRemoved value: -"UUID of the contact/company/deal." - removed
Input schema / properties / entityType / descriptionRemoved value: -"Which entity the value is being set on." - changed
Input schema / properties / fieldKey / descriptionPrevious value: -"Custom field identifier (e.g. \"loan_amount\")."New value: +"e.g. \"loan_amount\"." - removed
Input schema / properties / value / descriptionRemoved value: -"New value. Null clears the field."
- Changed
custom_fields_update4 fields changed- removed
Input schema / properties / id / descriptionRemoved value: -"Custom field UUID. Get from custom_fields_list." - removed
Input schema / properties / name / descriptionRemoved value: -"New human label." - changed
Input schema / properties / options / descriptionPrevious value: -"For type=select fields only: replace the allowed-values list."New value: +"Select fields: replaces the list." - changed
Input schema / properties / position / descriptionPrevious value: -"Order in the field list (lower = first)."New value: +"Lower sorts first."
- Changed
deal_stages_create5 fields changed- changed
Input schema / properties / color / descriptionPrevious value: -"Hex colour like \"#0EA5E9\". Optional."New value: +"Hex, e.g. \"#0EA5E9\"." - removed
Input schema / properties / isLost / descriptionRemoved value: -"Marks this the lost stage." - removed
Input schema / properties / isWon / descriptionRemoved value: -"Marks this the won/closed stage." - removed
Input schema / properties / name / descriptionRemoved value: -"Stage name, e.g. \"Quote sent\"." - changed
Input schema / properties / position / descriptionPrevious value: -"Zero-based order. Omit to append."New value: +"Zero-based order."
- Removed
deal_stages_reorder - Changed
deal_stages_update5 fields changed- changed
Input schema / properties / color / descriptionPrevious value: -"New hex colour."New value: +"Hex colour." - changed
Input schema / properties / id / descriptionPrevious value: -"Stage id from deal_stages_list."New value: +"Stage to rename/recolour." - removed
Input schema / properties / name / descriptionRemoved value: -"New name." - added
Input schema / properties / orderAdded value: +{ + "description": "All stage ids in the new order. A partial list leaves the rest unplaced.", + "items": { + "type": "string" + }, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "id" -]
- Changed
deals_create5 fields changed- changed
Input schema / properties / closeAt / descriptionPrevious value: -"ISO 8601 expected close date."New value: +"Expected close date, ISO 8601." - changed
Input schema / properties / currency / descriptionPrevious value: -"ISO 4217 e.g. \"USD\", \"CAD\". Defaults to user's currency."New value: +"ISO 4217. Defaults to the user's currency." - removed
Input schema / properties / stageId / descriptionRemoved value: -"Pipeline stage UUID (see deal_stages.list)." - removed
Input schema / properties / title / descriptionRemoved value: -"Short deal name e.g. \"Acme Q3 renewal\"." - removed
Input schema / properties / valueCents / descriptionRemoved value: -"Amount in cents."
- Removed
deals_get - Changed
deals_list3 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Deal id. Returns that one deal.", + "type": "string" +} - changed
Input schema / properties / search / descriptionPrevious value: -"Free-text search across title, contact name, company name."New value: +"Matches title, contact and company name." - changed
Input schema / properties / stageId / descriptionPrevious value: -"Filter to a specific stage UUID (see deal_stages.list)."New value: +"From deal_stages_list."
- Removed
deals_move_stage - Removed
email_get_message_body - Changed
email_get_thread3 fields changed- added
Input schema / properties / messageIdAdded value: +{ + "description": "Fetches that message's body (slower; only when the snippet is not enough).", + "type": "string" +} - removed
Input schema / properties / threadKey / descriptionRemoved value: -"From email_list_threads." - removed
Input schema / requiredRemoved value: -[ - "threadKey" -]
- Changed
email_list_threads4 fields changed- changed
Input schema / properties / account / descriptionPrevious value: -"Limit to one connected account id. Omit for all."New value: +"Mailbox id from email_accounts_list. Default: all." - changed
Input schema / properties / folder / descriptionPrevious value: -"Which folder to list. Defaults to everything."New value: +"Default: all." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max threads to return. Default 25."New value: +"Default 25, max 100." - changed
Input schema / properties / search / descriptionPrevious value: -"Match against subject, participant address and snippet."New value: +"Matches subject, participant address and snippet."
- Changed
email_send12 fields changed- changed
Input schema / properties / accountId / descriptionPrevious value: -"Optional mailbox UUID from email_accounts_list. Defaults to the oldest connected mailbox."New value: +"Sending mailbox, from email_accounts_list." - removed
Input schema / properties / bcc / descriptionRemoved value: -"BCC list (comma-separated)." - removed
Input schema / properties / bodyHtml / descriptionRemoved value: -"HTML body (preferred). Supports merge tags." - removed
Input schema / properties / bodyText / descriptionRemoved value: -"Plain-text body. Sent alongside HTML if both given." - removed
Input schema / properties / cc / descriptionRemoved value: -"CC list (comma-separated)." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Optional contact UUID. When set, merge tags resolve and the thread attaches to the contact. It does not pick the mailbox." - changed
Input schema / properties / fromEmail / descriptionPrevious value: -"Optional Send-as alias to send from, e.g. \"adam@example.com\". Must be the mailbox's own address or an alias registered on it under Settings → Email; anything else is refused with INVALID_FROM. Does not pick the mailbox — pair with accountId when there is more than one."New value: +"Send-as alias registered on that mailbox; others are refused (INVALID_FROM)." - removed
Input schema / properties / fromName / descriptionRemoved value: -"Optional display name for the From header. Defaults to the alias's or mailbox's saved name." - changed
Input schema / properties / scheduledSendAt / descriptionPrevious value: -"Optional future ISO 8601 timestamp. When set the message is queued and dispatched by the per-minute cron at that time."New value: +"Future ISO 8601 time to send at." - removed
Input schema / properties / subject / descriptionRemoved value: -"Subject line. Supports merge tags when contactId is provided." - changed
Input schema / properties / to / descriptionPrevious value: -"Recipient email or comma-separated list."New value: +"Address or comma-separated list." - changed
Input schema / properties / trackOpens / descriptionPrevious value: -"When true, inject a 1x1 open-tracking pixel. Signal is approximate (Gmail proxies + Apple Mail Privacy interfere)."New value: +"Adds an open-tracking pixel (approximate)."
- Removed
email_templates_create - Removed
email_templates_delete - Removed
email_templates_get - Removed
email_templates_list - Removed
email_templates_update - Changed
frontdesk_settings2 fields changed- changed
Input schema / properties / hours / descriptionPrevious value: -"For action='set_hours'. { days: { \"0\"…\"6\": [[\"HH:MM\",\"HH:MM\"], …] } } or null."New value: +"{ days: { \"0\"-\"6\" (0=Sunday): [[\"09:00\",\"17:00\"], ...] } } in account timezone, or null to clear." - changed
Input schema / properties / override / descriptionPrevious value: -"For action='set_override'. { mode: 'emma'|'me', until: ISO } or null."New value: +"{ mode: 'emma' (take everything) | 'me' (ring me first), until: ISO }, or null to clear."
- Changed
inbound_webhooks_manage9 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"Which operation to run." - removed
Input schema / properties / description / descriptionRemoved value: -"Optional longer-form context." - changed
Input schema / properties / id / descriptionPrevious value: -"Inbound webhook UUID. Required for get/update/delete."New value: +"For get/update/delete." - changed
Input schema / properties / ipAllowlist / descriptionPrevious value: -"Optional CIDR list. Empty = any IP."New value: +"CIDRs. Empty = any IP." - changed
Input schema / properties / isActive / descriptionPrevious value: -"Pause receiving by setting to false (update only)."New value: +"Update only; false pauses receiving." - changed
Input schema / properties / mappingJson / descriptionPrevious value: -"Required when mappingMode=\"mapped\". Translates an arbitrary inbound payload into native Groundbase actions. Shape: { \"actions\": [{ \"event\": \"contact.find_or_create\" | \"contact.create\" | \"contact.update\" | \"company.find_or_create\" | \"company.create\" | \"deal.create\" | \"note.create\" | \"task.create\" | \"tag.apply\" | \"tag.remove\", \"fields\": { \"<groundbase_field>\": \"<jsonpath.in.payload>\", ... }, \"static\": { \"<groundbase_field>\": <literal>, ... } }] }. Paths are dot-separated with optional bracketed array indices (e.g. \"lead.contact[0].email\" or equivalently \"lead.contact.0.email\"). Missing paths resolve to undefined and are omitted. Example for a Facebook Lead Ads webhook: { \"actions\": [{ \"event\": \"contact.find_or_create\", \"fields\": { \"first_name\": \"name.first\", \"email\": \"email\", \"phone\": \"phone\" }, \"static\": { \"source\": \"fb-lead-ads\", \"tags\": [\"lead\"] } }] }."New value: +"For mappingMode \"mapped\": { \"actions\": [{ \"event\": \"contact.find_or_create\" (or another native event), \"fields\": { \"<groundbase_field>\": \"<path.in.payload>\" }, \"static\": { \"<groundbase_field>\": <literal> } }] }. Paths are dotted with optional indices (\"lead.contact[0].email\"); missing paths are omitted." - changed
Input schema / properties / mappingMode / descriptionPrevious value: -"Default \"native\" on create."New value: +"Default native." - changed
Input schema / properties / name / descriptionPrevious value: -"Display name. Required on create."New value: +"Required on create." - changed
Input schema / properties / signingSecret / descriptionPrevious value: -"Optional HMAC secret (create only). Senders include X-Groundbase-Signature."New value: +"Optional HMAC secret (create only); senders send X-Groundbase-Signature."
- Removed
invoice_items_create - Added
invoice_items_save - Removed
invoice_items_update - Removed
invoice_payments_list - Changed
invoice_payments_record6 fields changed- changed
Input schema / properties / amount / descriptionPrevious value: -"Decimal string in the invoice currency, e.g. \"1600.00\"."New value: +"Decimal string in the invoice currency." - removed
Input schema / properties / method / descriptionRemoved value: -"bank_transfer | card | cash | cheque | other" - changed
Input schema / properties / receivedAt / descriptionPrevious value: -"ISO date or datetime. Defaults to now."New value: +"ISO date. Default now." - changed
Input schema / properties / reference / descriptionPrevious value: -"Cheque number, transfer reference, or payment id."New value: +"Cheque number or transfer reference." - changed
Input schema / properties / sendReceipt / descriptionPrevious value: -"Default true. Set false for cash handed over in person where a receipt was already given."New value: +"Default true." - removed
Input schema / properties / sendVia / descriptionRemoved value: -"Force a transport: smtp or resend. Defaults to the user's SMTP account when connected."
- Changed
invoice_settings_update5 fields changed- removed
Input schema / properties / defaultCurrency / descriptionRemoved value: -"ISO 4217." - removed
Input schema / properties / nextNumber / descriptionRemoved value: -"Forward only. Useful when moving from another system mid-sequence." - changed
Input schema / properties / numberPadding / descriptionPrevious value: -"Minimum digits, 1-12. 4 gives INV-0007."New value: +"Min digits 1-12." - changed
Input schema / properties / numberPrefix / descriptionPrevious value: -"e.g. \"INV-\". Up to 16 characters."New value: +"e.g. \"INV-\", max 16 chars." - changed
Input schema / properties / paymentInstructions / descriptionPrevious value: -"Free text. Line breaks are kept."New value: +"How to pay (bank details, link)."
- Removed
invoices_create_draft - Removed
invoices_get - Changed
invoices_list2 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Invoice id. Returns that one invoice.", + "type": "string" +} - added
Input schema / properties / paymentsAdded value: +{ + "description": "With id: return the payment ledger (incl. reversed payments).", + "type": "boolean" +}
- Added
invoices_save_draft - Changed
invoices_send2 fields changed- changed
Input schema / properties / sendVia / descriptionPrevious value: -"Which connected sender to use. Defaults to SMTP when both exist."New value: +"Default smtp when both exist." - changed
Input schema / properties / to / descriptionPrevious value: -"Override the recipient. Defaults to the billing email on their profile, then the contact' email."New value: +"Default: profile billing email, then the contact's email."
- Removed
invoices_update_draft - Changed
meeting_types_create5 fields changed- changed
Input schema / properties / bufferMin / descriptionPrevious value: -"Gap to leave after each booking, in minutes."New value: +"Minutes kept free after each booking." - removed
Input schema / properties / description / descriptionRemoved value: -"Optional blurb on the booking page." - changed
Input schema / properties / durationMin / descriptionPrevious value: -"Length in minutes. Default 30."New value: +"Minutes. Default 30." - removed
Input schema / properties / name / descriptionRemoved value: -"Shown to the person booking, e.g. \"Intro call\"." - removed
Input schema / properties / slug / descriptionRemoved value: -"URL segment, lowercase and hyphenated."
- Added
meeting_types_delete - Added
meeting_types_update - Changed
notes_create1 field changed- removed
Input schema / properties / body / descriptionRemoved value: -"Note text."
- Changed
notes_list4 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Limit to one company." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Limit to one contact." - removed
Input schema / properties / dealId / descriptionRemoved value: -"Limit to one deal." - removed
Input schema / properties / offset / descriptionRemoved value: -"Default 0."
- Changed
outbound_webhooks_manage7 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"Which operation to run." - removed
Input schema / properties / description / descriptionRemoved value: -"Optional longer-form context." - changed
Input schema / properties / events / descriptionPrevious value: -"List of event names. Pass [\"*\"] for all events. Required on create."New value: +"Event names, or [\"*\"] for all: contact|company.created/updated/deleted, deal.created/updated/deleted/stage_changed/won/lost, task.created/updated/completed/deleted, note.created, tag.applied/removed, sms.sent/received/delivered/failed, call.completed, voicemail.received, email.sent, invoice.issued/paid/voided, payment.recorded. Slack and Discord webhook URLs get a readable message; others get signed JSON." - changed
Input schema / properties / id / descriptionPrevious value: -"Subscription UUID. Required for get/update/delete."New value: +"For get/update/delete." - changed
Input schema / properties / isActive / descriptionPrevious value: -"Pause delivery by setting to false (update only)."New value: +"Update only; false pauses delivery." - changed
Input schema / properties / name / descriptionPrevious value: -"Short human-readable identifier, e.g. \"Slack #wins channel\". Required on create."New value: +"Required on create." - changed
Input schema / properties / url / descriptionPrevious value: -"HTTPS URL Groundbase will POST to. Required on create."New value: +"HTTPS. Required on create."
- Removed
quotes_accept - Removed
quotes_create_draft - Removed
quotes_decline - Removed
quotes_get - Changed
quotes_list4 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Only quotes for this company." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Only quotes for this contact." - added
Input schema / properties / idAdded value: +{ + "description": "Quote id. Returns that one quote.", + "type": "string" +} - changed
Input schema / properties / status / descriptionPrevious value: -"draft | open | accepted | declined | void | expired"New value: +"draft | open | accepted | declined | void | expired (open but past valid-until)"
- Added
quotes_record_outcome - Added
quotes_save_draft - Changed
quotes_send3 fields changed- changed
Input schema / properties / message / descriptionPrevious value: -"A covering note above the quote. Same tokens."New value: +"Covering note; same tokens." - changed
Input schema / properties / subject / descriptionPrevious value: -"Override the subject. Tokens {number} {business} {customer} {amount} {due} are filled in."New value: +"Tokens {number} {business} {customer} {amount} {due}." - changed
Input schema / properties / to / descriptionPrevious value: -"Override the recipient. Defaults to the billing email, then the contact's email."New value: +"Default: billing email, then the contact's email."
- Removed
quotes_update_draft - Changed
resend_manage1 field changed- changed
Input schema / properties / to / descriptionPrevious value: -"For action='test_send' — recipient email."New value: +"test_send recipient."
- Changed
saved_views_create3 fields changed- removed
Input schema / properties / entityType / descriptionRemoved value: -"Which record type this view filters." - changed
Input schema / properties / filterJson / descriptionPrevious value: -"Filter definition, JSON-encoded."New value: +"JSON-encoded filter." - removed
Input schema / properties / name / descriptionRemoved value: -"What the user will see in the sidebar."
- Added
saved_views_delete - Changed
sending_settings3 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"'get' to read, 'set' to write." - changed
Input schema / properties / daily_email_send_cap / descriptionPrevious value: -"For action='set'. Non-negative integer, or null to remove the cap entirely."New value: +"set: non-negative integer or null." - changed
Input schema / properties / domain / descriptionPrevious value: -"For action='set'. Bare hostname, e.g. 'example.com'. Caps only mail sent from that domain, inside the account-wide cap. Omit to set the account-wide cap, which totals every domain and is the only cap on a domain without its own."New value: +"set: bare hostname, e.g. 'example.com'. Omit for the account-wide cap."
- Changed
sms_cancel_scheduled1 field changed- removed
Input schema / properties / id / descriptionRemoved value: -"sms_messages row UUID."
- Added
sms_list - Removed
sms_list_scheduled - Removed
sms_list_thread - Changed
sms_optouts3 fields changed- changed
Input schema / properties / phone / descriptionPrevious value: -"For action='remove', or a single 'add'."New value: +"For 'remove', or a single 'add'." - changed
Input schema / properties / phones / descriptionPrevious value: -"For action='add' — one or more numbers, any format. Max 500."New value: +"For 'add': up to 500 numbers, any format." - changed
Input schema / properties / source / descriptionPrevious value: -"Optional label for action='add'. Defaults to 'imported'. 'stop_keyword' is reserved for the inbound webhook so the two can be told apart."New value: +"Label for 'add'. Default 'imported'; 'stop_keyword' is reserved."
- Added
sms_send - Removed
sms_send_now - Removed
sms_send_scheduled - Removed
sms_templates_create - Removed
sms_templates_delete - Removed
sms_templates_get - Removed
sms_templates_list - Removed
sms_templates_update - Changed
tags_apply3 fields changed- removed
Input schema / properties / contactIds / descriptionRemoved value: -"Contact UUIDs." - added
Input schema / properties / removeAdded value: +{ + "description": "Remove the tag instead of adding it.", + "type": "boolean" +} - removed
Input schema / properties / tagId / descriptionRemoved value: -"Tag UUID."
- Changed
tags_create1 field changed- changed
Input schema / properties / color / descriptionPrevious value: -"Hex color, e.g. \"#B91C1C\". Optional."New value: +"Hex, e.g. \"#B91C1C\"."
- Removed
tags_remove - Removed
tasks_complete - Changed
tasks_create6 fields changed- changed
Input schema / properties / dueAt / descriptionPrevious value: -"ISO 8601 — when the task is due (for kind=task)."New value: +"ISO 8601, for tasks." - changed
Input schema / properties / endAt / descriptionPrevious value: -"ISO 8601 — end time (for event/meeting)."New value: +"ISO 8601." - changed
Input schema / properties / kind / descriptionPrevious value: -"Default: task."New value: +"Default task." - removed
Input schema / properties / location / descriptionRemoved value: -"For meetings." - changed
Input schema / properties / recurrence / descriptionPrevious value: -"Repeat rule for kind=task. One of: daily, weekly, monthly, yearly, weekdays. Repeats relative to dueAt — e.g. dueAt on a Monday with \"weekly\" repeats every Monday. RRULE strings are NOT supported. Omit for a one-off task."New value: +"Repeats relative to dueAt. Tasks only." - changed
Input schema / properties / startAt / descriptionPrevious value: -"ISO 8601 — start time (for event/meeting)."New value: +"ISO 8601, for events/meetings."
- Removed
tasks_get - Changed
tasks_list5 fields changed- removed
Input schema / properties / contactId / descriptionRemoved value: -"Limit to a single contact's tasks." - removed
Input schema / properties / dealId / descriptionRemoved value: -"Limit to a single deal." - changed
Input schema / properties / from / descriptionPrevious value: -"ISO 8601 — only items due on/after this date."New value: +"ISO 8601; due on/after." - added
Input schema / properties / idAdded value: +{ + "description": "Task id. Returns that one item.", + "type": "string" +} - changed
Input schema / properties / to / descriptionPrevious value: -"ISO 8601 — only items due on/before this date."New value: +"ISO 8601; due on/before."
- Changed
tasks_update1 field changed- removed
Input schema / properties / recurrence / descriptionRemoved value: -"Repeat rule. One of: daily, weekly, monthly, yearly, weekdays. Pass an empty string to make a recurring task one-off again. RRULE strings are NOT supported."
- Added
templates_create - Added
templates_delete - Added
templates_list - Added
templates_update - Changed
time_list5 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Company UUID the time is for." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Contact UUID the time is for." - changed
Input schema / properties / dealId / descriptionPrevious value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company." - changed
Input schema / properties / limit / descriptionPrevious value: -"Max entries. Default 50, max 500."New value: +"Default 50, max 500." - removed
Input schema / properties / status / descriptionRemoved value: -"Optional filter."
- Changed
time_log9 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Company UUID the time is for." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Contact UUID the time is for." - removed
Input schema / properties / currency / descriptionRemoved value: -"ISO code for the rate." - changed
Input schema / properties / dealId / descriptionPrevious value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company." - removed
Input schema / properties / description / descriptionRemoved value: -"What the work was." - removed
Input schema / properties / duration / descriptionRemoved value: -"\"1:30\", \"90m\", \"1.5h\", or hours as a number." - changed
Input schema / properties / endedAt / descriptionPrevious value: -"ISO 8601 end. Optional."New value: +"ISO 8601." - changed
Input schema / properties / rate / descriptionPrevious value: -"Hourly rate as a decimal. Optional; inherited if omitted."New value: +"Hourly; inherited if omitted." - changed
Input schema / properties / startedAt / descriptionPrevious value: -"ISO 8601 start. Optional."New value: +"ISO 8601."
- Changed
time_timer_start6 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Company UUID the time is for." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Contact UUID the time is for." - changed
Input schema / properties / currency / descriptionPrevious value: -"ISO code for the rate. Defaults to the user's invoicing currency."New value: +"Default: invoicing currency." - changed
Input schema / properties / dealId / descriptionPrevious value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company." - removed
Input schema / properties / description / descriptionRemoved value: -"What the work is." - changed
Input schema / properties / rate / descriptionPrevious value: -"Hourly rate as a decimal, e.g. \"85\". Optional."New value: +"Hourly, decimal string."
- Changed
time_update8 fields changed- removed
Input schema / properties / companyId / descriptionRemoved value: -"Company UUID the time is for." - removed
Input schema / properties / contactId / descriptionRemoved value: -"Contact UUID the time is for." - changed
Input schema / properties / dealId / descriptionPrevious value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company." - removed
Input schema / properties / delete / descriptionRemoved value: -"Delete the entry." - removed
Input schema / properties / duration / descriptionRemoved value: -"New duration." - removed
Input schema / properties / id / descriptionRemoved value: -"Time entry id." - changed
Input schema / properties / rate / descriptionPrevious value: -"New hourly rate; empty string clears it."New value: +"Empty string clears." - removed
Input schema / properties / startedAt / descriptionRemoved value: -"New ISO 8601 start."
- Changed
voicemail_drops_create1 field changed- changed
Input schema / properties / name / descriptionPrevious value: -"Display name (e.g. \"Quick intro\", \"Follow-up after demo\"). Defaults to \"Untitled drop\" if blank."New value: +"Default \"Untitled drop\"."
- Added
voicemail_drops_delete - Changed
voicemail_drops_drop4 fields changed- changed
Input schema / properties / contactId / descriptionPrevious value: -"Optional contact UUID. Worker pulls the contact's primary phone."New value: +"Uses the contact's primary phone." - changed
Input schema / properties / dropId / descriptionPrevious value: -"UUID of the voicemail drop to play. From voicemail_drops_list."New value: +"A drop with has_audio." - changed
Input schema / properties / fromNumberId / descriptionPrevious value: -"Optional — specific Twilio number UUID to dial FROM. Defaults to user's first active number."New value: +"Twilio number id. Default: first active number." - changed
Input schema / properties / toPhone / descriptionPrevious value: -"Optional explicit phone in E.164 (+1...). Use when there's no contact in the CRM."New value: +"E.164, when there is no contact."
- Removed
voicemail_drops_generate_emma - Added
voicemail_drops_update - Changed
workflows_create7 fields changed- changed
Input schema / properties / condition / descriptionPrevious value: -"Optional workflow-level filter — if present, the workflow is skipped (status=skipped) when this evaluates false. Shape: { all|any: [{ field, op, value }] } — `all` requires every clause, `any` requires one. Field paths: entity.<column> (entity.email, entity.source, entity.tags), cf.<field_key> for a custom field, trigger.event / trigger.entity_type / trigger.entity_id, and trigger.payload.<key> for what the event carried (e.g. trigger.payload.tag_name on tag.applied) — NOT payload.<key>, which never resolves; the server refuses it on save. Text ops: equals, not_equals, contains, not_contains, starts_with, ends_with. Presence ops: is_set, is_not_empty, is_empty, includes_tag. Numeric/date ops: greater_than, greater_or_equal, less_than, less_or_equal (numeric when both sides parse as numbers, else lexicographic, which sorts ISO timestamps correctly), plus older_than_days and newer_than_days which take a day count and compare against a date field such as entity.last_contacted_at."New value: +"Skip the run (status skipped) unless true. { all|any: [{ field, op, value }] }. Fields: entity.<column>, cf.<field_key>, trigger.event|entity_type|entity_id, trigger.payload.<key> (not payload.<key>). Ops: equals, not_equals, contains, not_contains, starts_with, ends_with, is_set, is_not_empty, is_empty, includes_tag, greater_than, greater_or_equal, less_than, less_or_equal, older_than_days, newer_than_days." - changed
Input schema / properties / isActive / descriptionPrevious value: -"Defaults to true (workflow starts active)."New value: +"Default true." - removed
Input schema / properties / name / descriptionRemoved value: -"Display name (required)." - changed
Input schema / properties / steps / descriptionPrevious value: -"Ordered list of steps. Each step is { type, config: { ...props } } — the per-type props below go INSIDE `config`, e.g. { \"type\": \"create_note\", \"config\": { \"body\": \"hi\" } } (flat props on the step are also accepted). The server validates on save and answers 400 INVALID_WORKFLOW listing every problem — unknown step type or operator, unknown trigger event, a schedule that would never fire, a bad timezone, a missing required prop, a webhook url on a private host — so read the message and fix the definition rather than retrying. Step types: `send_sms` { to?, body }; `send_email` { to?, subject, body_html?, body_text?, contact_id? } — blank to means the run's contact (on a deal, task or note, its contact); `add_to_campaign` { campaign_id } — puts the run's contact into an ONGOING campaign (enrolment_mode=ongoing, status sending) at its first step, under the campaign's rules; fails on a one-time or not-sending campaign; `apply_tag` { tag_name, entity_id?, entity_type? }; `remove_tag` { tag_name, entity_id?, entity_type? }; `create_note` { body, entity_type?, entity_id? }; `create_task` { title, description?, due_at?, due_in_days?, kind?, location?, contact_id? }; `fire_webhook` { url, method?, headers?, body? }; `update_field` { entity_type?, entity_id?, field, value } — restricted to a safe allow-list of native columns (first_name, last_name, email, phone, position, city, source, notes, primary_phone, company_id); `set_custom_field` { entity_type?, entity_id?, field_key, value } — writes to a custom field defined in Settings → Custom fields. field_key accepts \"loan_amount\" or \"cf.loan_amount\" (the cf. prefix is optional); `delay` { delay_seconds, stop_if? } — stop_if { reply?, meeting?, optout? } ends the run instead of continuing when, by the time the wait is over, the contact has replied (text or email), booked a meeting, or opted out since the run started. Only on a top-level wait longer than 60 seconds; `branch` { condition: { all|any: [{ field, op, value }] }, then: [Step], else: [Step] }. Templates supported in string fields: {{first_name}}, {{trigger.event}}, {{steps.<id>.output.<key>}}. Step ids auto-generated as s_<8hex> if omitted; pass an explicit \"id\" to make {{steps.X.output.Y}} references stable across edits."New value: +"Ordered steps, each { id?, type, config: {...} }. Types and config: send_sms { to?, body }; send_email { to?, subject, body_html?, body_text? } (blank to = the run's contact); add_to_campaign { campaign_id } (ongoing, sending campaigns only); apply_tag / remove_tag { tag_name }; create_note { body }; create_task { title, description?, due_at?, due_in_days?, kind?, location?, contact_id? }; fire_webhook { url, method?, headers?, body? }; update_field { field, value } (first_name, last_name, email, phone, position, city, source, notes, primary_phone, company_id); set_custom_field { field_key, value } (\"cf.\" prefix optional); delay { delay_seconds, stop_if?: { reply?, meeting?, optout? } } (stop_if ends the run if the contact did that during the wait; top-level waits over 60s); branch { condition, then: [steps], else: [steps] }. Record-targeting steps also take entity_type/entity_id. Strings support {{first_name}}, {{trigger.event}}, {{steps.<id>.output.<key>}}; give steps an explicit id to keep those references stable. On 400 INVALID_WORKFLOW, fix what the message lists rather than retrying." - changed
Input schema / properties / triggerConfig / descriptionPrevious value: -"For scheduled triggers, the schedule shape. Otherwise null."New value: +"Scheduled only: { recurrence: one_time|hourly|daily|weekly, run_at?, time_of_day?, days_of_week?, minute_of_hour?, timezone? }." - changed
Input schema / properties / triggerEvent / descriptionPrevious value: -"For entity_event: the event name (e.g. \"contact.created\"). For inbound_webhook: the inbound webhook id."New value: +"Event name, or inbound webhook id." - removed
Input schema / properties / triggerType / descriptionRemoved value: -"Required."
- Changed
workflows_delete1 field changed- removed
Input schema / properties / id / descriptionRemoved value: -"Workflow UUID."
- Removed
workflows_get - Changed
workflows_list3 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Workflow id.", + "type": "string" +} - added
Input schema / properties / limitAdded value: +{ + "description": "Runs to return. Default 20.", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / runsAdded value: +{ + "description": "With id: return run history instead.", + "type": "boolean" +}
- Removed
workflows_pause - Removed
workflows_resume - Changed
workflows_run_now4 fields changed- removed
Input schema / properties / entityId / descriptionRemoved value: -"UUID of the entity." - removed
Input schema / properties / entityType / descriptionRemoved value: -"What entity to run the workflow against." - removed
Input schema / properties / id / descriptionRemoved value: -"Workflow UUID." - changed
Input schema / properties / payload / descriptionPrevious value: -"Optional extra payload data merged into the trigger context (alongside the loaded entity)."New value: +"Extra trigger payload."
- Removed
workflows_runs - Changed
workflows_update3 fields changed- removed
Input schema / properties / id / descriptionRemoved value: -"Workflow UUID." - added
Input schema / properties / isActiveAdded value: +{ + "type": "boolean" +} - removed
Input schema / properties / triggerType / descriptionRemoved value: -"Required to switch a workflow between trigger families. See workflows_create for details on each type."
2 tool updates
- Removed
billing_profile_create - Removed
billing_profile_get
2 tool updates
- Changed
companies_create4 fields changed- added
Input schema / properties / cityAdded value: +{ + "type": "string" +} - added
Input schema / properties / countryAdded value: +{ + "type": "string" +} - removed
Input schema / properties / sizeRemoved value: -{ - "description": "Free-form e.g. \"1-10\", \"Enterprise\".", - "type": "string" -} - added
Input schema / properties / stateAdded value: +{ + "description": "State or province.", + "type": "string" +}
- Changed
companies_update4 fields changed- added
Input schema / properties / cityAdded value: +{ + "type": "string" +} - added
Input schema / properties / countryAdded value: +{ + "type": "string" +} - removed
Input schema / properties / sizeRemoved value: -{ - "type": "string" -} - added
Input schema / properties / stateAdded value: +{ + "type": "string" +}
10 tool updates
- Added
quotes_accept - Added
quotes_convert - Added
quotes_create_draft - Added
quotes_decline - Added
quotes_get - Added
quotes_issue - Added
quotes_list - Added
quotes_send - Added
quotes_update_draft - Added
quotes_void
Publisher details
- Operator
- Groundbase
- Operator website
- https://groundbasecrm.com
- Vendor relationship
- First-party
- Documentation
- https://groundbasecrm.com/mcp
- Trust center
- Not applicable
- Restrictions
- Requires a Groundbase account. $9/mo flat, 14-day free trial. OAuth or API key.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.1611 npm1MIT
- AlicenseCqualityBmaintenanceCompetitor Monitor AI - MCP server providing AI-powered tools and automation by MEOK AI Labs117 npm54 PyPIMIT
- AlicenseAqualityCmaintenanceRevnuvo Company Intelligence tells AI agents what changed at a company, with evidence. It observes company websites, technologies, and DNS over time and returns timestamped, confidence-aware changes, signals, and monitoring.9MIT

industrylens-mcpofficial
AlicenseNot gradedqualityBmaintenanceBrowse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.