Skip to main content
Glama

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.

Ownership verified
Status
Healthy
Uptime
97.5% over 23 days
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-06-18
URL

TDQS

B3.4/5.0

Scored across 104 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count1/5

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.

Completeness5/5

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 tools
activity_listA
Read-onlyIdempotent
Inspect

Recent activity, newest first: texts, calls, emails, notes, deal stage changes, task completions. Optionally scoped to one contact, company or deal.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 50.
dealIdNo
companyIdNo
contactIdNo

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityNo
labelNoe.g. 'home', 'office'.
notesNo
actionYes
streetNo
countryNo
provinceNoState, province or region.
addressIdNo
companyIdNo
contactIdNo
is_primaryNoMake this the primary address (demotes the old one).
postal_codeNo
billing_profiles_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoEdit this profile. Omit to create.
notesNo
taxIdNo
actionYes
currencyNoISO 4217.
companyIdNo
contactIdNo
billingEmailNoWhere invoices and receipts go, if not the contact's own address.
billingAddressNo
paymentTermsDaysNo0 = due on receipt.
calls_listA
Read-onlyIdempotent
Inspect

List call history (direction, duration, voicemail transcripts), or pass id to fetch one call with its recording details.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoCall id. Returns that one call.
limitNoDefault 100, max 500.
contactIdNo
voicemailOnlyNoOnly calls that left a voicemail.

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_analyticsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
limitNoRecipients: default 100.
statusNoRecipients filter.
recipientsNoReturn per-recipient status rows.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_manageA
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNolist: name search.
idNoCampaign id; needed for all but list, create, preview_audience.
toNotest_send recipient.
kindNolist filter: newsletters, or everything else.
nameNo
roleNonewsletter_templates: another industry's set (e.g. real estate, mortgage, insurance). Default: the user's own.
limitNo
stepsNoDrip 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.
actionYes
statusNolist filter.
channelNo
contentNoSingle 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.
audienceNoduplicate: copy goes only to people the (sent, email) campaign reached who did not open it.
send_modeNo
contact_idsNoadd_recipients: up to 500.
template_idNocreate: start a newsletter from this template (newsletter_templates). name defaults to the template name.
scheduled_atNoUnix seconds.
enrolment_modeNo'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_windowNo{ 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_filterNo{ all: [rules], any?: [rules] }. Rules: { type: "all_contacts" } or { type: "tag", op: "has"|"has_not", value: "<tag name>" }. all[] ANDs, any[] ORs.

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_list
Read-onlyIdempotent
Inspect

Search companies, or pass id to fetch one in full (employees, deals, addresses, custom fields).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoCompany id. Returns that one company.
limitNoDefault 50.
offsetNo
searchNoMatches name and website.
deletedNoList recently deleted companies instead (to restore).
companies_manage
Destructive
Inspect

Change companies. create (name required; tags by name), update (omitted fields unchanged), delete (soft; confirm first), restore (ids from companies_list deleted).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
idsNorestore: the deleted records to bring back.
cityNo
nameNo
tagsNo
notesNo
stateNoState or province.
actionYes
countryNo
websiteNoInclude https://.
industryNo
deletedAtNorestore: undo one delete, everything it removed (its deleted_at from the deleted list).
contacts_list
Read-onlyIdempotent
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoContact id. Returns that one contact; other filters ignored.
tagNoOnly contacts with this tag (name or id).
sortNorecent = last contacted. Default name.
limitNoDefault 50.
offsetNo
searchNoMatches name, email, phone.
deletedNoList recently deleted contacts instead.
companyIdNoOnly contacts at this company.
duplicatesNoList groups of live contacts sharing an email or phone instead.
unsubscribedNoOpted out of any channel / email / texts, or none (for an audience).
contacts_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
idsNorestore: the deleted records to bring back.
setNobulk_update: { city?, source?, position?, companyId? }.
tagsNoTag names; missing ones are created.
emailNo
notesNo
phoneNoNormalised to E.164.
actionYes
keepIdNomerge: the contact that stays.
lastNameNo
mergeIdsNomerge: the duplicates folded into it.
positionNoJob title.
companyIdNo
deletedAtNorestore: undo one delete, everything it removed (its deleted_at from the deleted list).
firstNameNo
customFieldNobulk_update: { key (field id or key), value }.
custom_fields_list
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
mergeTagsNoList merge tags instead.
entityTypeNoOmit for all.
custom_fields_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNoLabel, e.g. "Loan amount".
typeNo
valueNo
actionYes
optionsNoRequired for type select.
entityIdNo
fieldKeyNosnake_case, max 60 chars.
positionNoLower sorts first.
entityTypeNo
dashboard_summary
Read-onlyIdempotent
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pipelineNoPer-stage open deals instead.
deals_list
Read-onlyIdempotent
Inspect

List deals with stage, value, contact and company, or pass id to fetch one deal with its notes and tasks.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoDeal id. Returns that one deal.
limitNo
offsetNo
searchNoMatches title, contact and company name.
deletedNoList recently deleted deals instead (to restore).
stageIdNoFrom deal_stages_list.
companyIdNo
contactIdNo
deals_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
idsNorestore: the deleted records to bring back.
notesNo
titleNo
actionYes
closeAtNoExpected close date, YYYY-MM-DD or ISO 8601.
stageIdNo
companyIdNo
contactIdNo
deletedAtNorestore: undo one delete, everything it removed (its deleted_at from the deleted list).
valueCentsNoIn the account's default currency (deals have no currency of their own).
deal_stages_listA
Read-onlyIdempotent
Inspect

List pipeline stages in order (id, name, colour, position). Call before creating or moving a deal.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoStage to rename/recolour.
nameNo
colorNoHex, e.g. "#0EA5E9".
isWonNo
orderNoAll stage ids in the new order. A partial list leaves the rest unplaced.
actionYes
isLostNo
positionNoZero-based order.
reassignToNodelete: the stage its deals move to.
documents_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoget / remind / void: the document id.
titleNosend: defaults to the template name.
actionYes
reasonNovoid: why (kept in the history).
statusNolist: sent | completed | declined | voided
messageNosend: shown in the email; defaults to the template's.
orderedNosend: sign one after another in role order (the user last).
signersNosend, several roles: { role, contactId } or { role, name, email }.
signerIdNoremind: just this signer.
contactIdNolist: documents this contact was sent. send: who signs (one signer role).
templateIdNosend: 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_read
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 25, max 100.
actionYes
folderNoDefault: all.
searchNoMatches subject, sender and message text.
accountNoMailbox id from email_accounts_list. Default: all.
messageIdNoFetches that message's body (slower; only when the snippet is not enough).
threadKeyNoThe `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.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNo
toYesAddress or comma-separated list.
bccNo
subjectYes
bodyHtmlNo
bodyTextNo
fromNameNo
accountIdNoSending mailbox, from email_accounts_list.
contactIdNo
fromEmailNoSend-as alias registered on that mailbox; others are refused (INVALID_FROM).
trackOpensNoAdds an open-tracking pixel (approximate).
scheduledSendAtNoFuture ISO 8601 time to send at.

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_update
Idempotent
Inspect

Mark an email conversation read or unread, or move it to inbox, sent or archive.

ParametersJSON Schema
NameRequiredDescriptionDefault
folderNomove: where it goes ("inbox" also un-archives).
isReadNomark: true = read, false = unread.
threadKeyYesThe `thread_id` from the thread list.
forms_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoForm id.
nameNo
tagsNoTag names put on each new lead (max 10). Replaces the list.
introNo
styleNoAppearance: { button_color, background_color, text_color: "#rrggbb", font: system|serif|rounded|mono }. {} resets to the default look. Replaces the whole style.
titleNo
actionYes
fieldsNo[{ 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.
createTaskNoAlso make a follow-up task per submission.
templateIdNoFor create, from action templates. Default: a simple contact form.
submitLabelNo
successMessageNo
inbound_webhooks_manageA
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoFor get/update/delete.
nameNoRequired on create.
actionYes
isActiveNoUpdate only; false pauses receiving.
descriptionNo
ipAllowlistNoCIDRs. Empty = any IP.
mappingJsonNoFor 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.
mappingModeNoDefault native.
signingSecretNoOptional HMAC secret (create only); senders send X-Groundbase-Signature.

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoEdit this item. Omit to create.
nameNoRequired to create.
actionYes
pricesNoChosen prices per currency, e.g. { "CAD": "150.00" }; others convert from base.
unitLabelNoe.g. "hour".
unitPriceNoIn base currency, with its decimal places ("200.00"; JPY "15000").
descriptionNo
baseCurrencyNoCreate only. ISO 4217, default USD.
defaultTaxRateNoPercent, e.g. "17.5".
invoice_payments_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
notesNo
actionYes
amountNoDecimal string in the invoice currency.
methodNo
sendViaNo
invoiceIdNo
paymentIdNo
referenceNoCheque number or transfer reference.
receivedAtNoISO date. Default now.
sendReceiptNoDefault true.
invoice_settings
Idempotent
Inspect

Invoice settings: business details on invoices and receipts, payment instructions, numbering. get, or set (omitted fields unchanged; nextNumber only moves forward).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYes
nextNumberNo
businessNameNo
defaultNotesNo
numberPrefixNoe.g. "INV-", max 16 chars.
businessEmailNo
businessPhoneNo
businessTaxIdNo
numberPaddingNoMin digits 1-12.
businessAddressNo
defaultCurrencyNo
defaultTermsDaysNo
defaultTermsTextNo
paymentInstructionsNoHow to pay (bank details, link).
invoices_list
Read-onlyIdempotent
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoMatches number and customer.
idNoInvoice id. Returns that one invoice.
limitNoDefault 100.
offsetNo
statusNodraft | issued | partially_paid | paid | void
paymentsNoWith id: return the payment ledger (incl. reversed payments).
companyIdNo
contactIdNo
recurringNoWith id: its repeat schedule (null if none).
creditNotesNoWith id: its credit notes.
outstandingNoOnly invoices with money still owed.
invoices_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoEdit this draft. Omit to create.
toNoDefault: profile billing email, then the contact's email.
stopNorecurring: end the schedule.
linesNoLine items: itemId (saved item, priced in this currency) or name + unitPrice for a one-off. Amounts are decimal strings.
notesNo
termsNo
actionYes
amountNocredit_note: before tax, e.g. "50.00".
reasonNocredit_note: printed on it.
revokeNopublic_link: turn the link off.
chargesNoCharges below the subtotal (shipping, rush fee); a negative amount for a deposit or discount.
dueDateNoYYYY-MM-DD. Default from profile terms.
endDateNorecurring: YYYY-MM-DD, or omit for no end.
messageNoA note above the invoice in the email.
sendViaNoDefault: their own mailbox, then Resend, then Groundbase's address.
subjectNoDefault: the invoice settings subject.
taxRateNocredit_note: percent, e.g. "13".
autoSendNorecurring: email each copy to the customer. Confirm with the user.
currencyNoISO 4217. Defaults from the billing profile.
companyIdNo
contactIdNoCreate: one of contactId/companyId.
frequencyNo
issueDateNoYYYY-MM-DD. Default today.
nextRunDateNorecurring: YYYY-MM-DD, today or later.
confirm_paidNoVoid even though payments or credit notes are recorded on it. Only after the user has confirmed. Default false.
creditNoteIdNo
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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoslots: last date, inclusive.
fromNoslots: first date, YYYY-MM-DD in the meeting type's timezone.
nameNobook, no contactId: who it is with (a contact is found or made).
emailNo
phoneNo
actionYes
startAtNobook: ISO 8601. Any future time: the user may override the meeting type's hours, notice and booking window.
contactIdNobook: the contact. Their email/phone are used.
allowOverlapNobook: over something already on the calendar.
meetingTypeIdYesFrom meeting_types_list.
meeting_types_listA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNo
slugNo
actionYes
isActiveNofalse hides it from booking.
locationNo
bufferMinNoMinutes kept free after each booking.
descriptionNo
durationMinNoMinutes. Default 30.
availabilityNo
locationTypeNo
maxAdvanceDaysNo
minNoticeHoursNo
intakeQuestionsNo
reminderSmsHoursNo
notes_listA
Read-onlyIdempotent
Inspect

List the notes on a contact, company or deal (pass exactly one of contactId / companyId / dealId).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoDefault 50.
dealIdNo
offsetNo
companyIdNo
contactIdNo

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_manage
Destructive
Inspect

Notes on a contact, company or deal. create (body, plus contactId / companyId / dealId), update, delete (confirm first).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
bodyNo
actionYes
dealIdNo
companyIdNo
contactIdNo
outbound_webhooks_manageA
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoFor get/update/delete.
urlNoPublic http(s) URL (use https: the payload is CRM data). Required on create.
nameNoRequired on create.
actionYes
eventsNoEvent 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.
isActiveNoUpdate only; false pauses delivery.
descriptionNo

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_status
Read-onlyIdempotent
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

quotes_listA
Read-onlyIdempotent
Inspect

List quotes with counts per status and open value per currency, or pass id for one quote with lines, totals, deposit and acceptance details.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoQuote id. Returns that one quote.
statusNodraft | open | accepted | declined | void | expired (open but past valid-until)
companyIdNo
contactIdNo

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoEdit this draft. Omit to create.
toNoDefault: billing email, then the contact's email.
linesNoLine items: itemId (saved item, priced in this currency) or name + unitPrice for a one-off. Amounts are decimal strings.
notesNo
termsNoWhat the customer agrees to by accepting.
actionYes
reasonNoDeclined: optional reason.
revokeNopublic_link: turn the link off.
chargesNoCharges below the subtotal (shipping, rush fee); a negative amount for a deposit or discount.
messageNoCovering note; same tokens.
outcomeNo
sendViaNo
subjectNoTokens {number} {business} {customer} {amount} {due}.
currencyNoISO 4217. Defaults from the billing profile.
companyIdNo
contactIdNoCreate: one of contactId/companyId.
issueDateNoYYYY-MM-DD. Default today.
validUntilNoYYYY-MM-DD. Default issue date + 30 days.
depositAmountNoe.g. "500.00". Empty string removes.
acceptedByNameNoAccepted: who said yes, e.g. "Dana (by phone)".
depositPercentNoe.g. "25". Empty string removes.
resend_manageA
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNotest_send recipient.
htmlNo
textNo
actionYes
subjectNo

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_listA
Read-onlyIdempotent
Inspect

List saved views (named filters over contacts, companies, deals or tasks).

ParametersJSON Schema
NameRequiredDescriptionDefault
entityTypeNoOnly views for this record type.

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

Saved views (named filters). create (copy filterJson's shape from saved_views_list), update (rename or change the filter), delete (the records stay).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNo
actionYes
entityTypeNo
filterJsonNoJSON-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYes
domainNoset: bare hostname, e.g. 'example.com'. Omit for the account-wide cap.
daily_email_send_capNoset: non-negative integer or null.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_list
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoConversation only. Default 50.
phoneNoThe other party's number, any format.
contactIdNoOr the contact (their primary number is used).
scheduledNoList pending scheduled texts instead.
sms_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
phoneNo
actionYes
contactIdNo
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.

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyYes
toPhoneYesRecipient, E.164 (+1...).
contactIdNoLinks the message to this contact's thread.
fromNumberNoSending number, E.164. Defaults to the primary.
scheduledAtNoFuture ISO 8601 time. Omit to send now.

TDQS

A4.1/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailNo
limitNoFor list. Default 100, max 500.
phoneNoFor 'remove', or a single 'add'.
actionYes
emailsNoFor add: up to 5000.
phonesNoFor 'add': up to 500 numbers, any format.
searchNoFor list: matches the address or contact name.
sourceNoLabel for 'add'. Default 'imported'; 'stop_keyword' is reserved.
channelYes
tags_listB
Read-onlyIdempotent
Inspect

List the user's tags with their ids.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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_manage
Destructive
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNo
colorNoHex, e.g. "#B91C1C".
tagIdNo
actionYes
removeNoRemove the tag instead of adding it.
contactIdsNo
tasks_list
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoTask id. Returns that one item.
toNoISO 8601; due on/before.
fromNoISO 8601; due on/after.
kindNo
limitNo
dealIdNo
offsetNo
statusNo
contactIdNo
tasks_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
kindNoDefault task.
colorNoCalendar colour, the same palette as Google Calendar; syncs both ways. "default" = the colour of its kind.
dueAtNoISO 8601, for tasks.
endAtNoISO 8601.
notesNo
scopeNoRepeating 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).
titleNo
actionYes
dealIdNo
statusNo
startAtNoISO 8601, for events/meetings.
locationNo
companyIdNo
contactIdNo
recurrenceNoRepeats relative to dueAt. Tasks only.
textContactNoMeetings: text the contact a confirmation and reminders. Default false.
remove_from_googleNoDefault false. True also removes it from Google Calendar: the event, or for scope "occurrence" just that date. Only after the user confirms.
templates_listA
Read-onlyIdempotent
Inspect

List SMS and/or email templates (name, body, subject), or pass id to fetch one.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoTemplate id. Returns that one template.
typeNoOmit for both.

TDQS

A3.8/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

Saved message templates (type sms or email; email needs a subject). create, update, delete (confirm first). Merge tags: custom_fields_list with mergeTags.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
bodyNo
nameNo
typeNo
actionYes
subjectNoEmail only; required there.
time_listA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoISO 8601, exclusive.
fromNoISO 8601, inclusive.
limitNoDefault 50, max 500.
dealIdNoAlso fills in the deal's contact and company.
statusNo
companyIdNo
contactIdNo

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
rateNoHourly, decimal string.
actionYes
dealIdNoAlso fills in the deal's contact and company.
deleteNo
endedAtNoISO 8601.
billableNoDefault true.
currencyNoDefault: invoicing currency.
durationNo
entryIdsNobill: from time_list (status unbilled).
companyIdNo
contactIdNo
invoiceIdNobill: a draft invoice.
startedAtNoISO 8601.
descriptionNo
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.

ParametersJSON Schema
NameRequiredDescriptionDefault
dropIdYesA drop with has_audio.
toPhoneNoE.164, when there is no contact.
contactIdNoUses the contact's primary phone.
fromNumberIdNoTwilio number id. Default: first active number.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_listA
Read-onlyIdempotent
Inspect

List voicemail drops: name, has_audio (only drops with audio can be dropped), duration_ms, source, script_text.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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_manage
Destructive
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNoDefault "Untitled drop".
actionYes
scriptNoUp to 2000 chars (~2 min). Inline tags like [warm], [chuckles] work.
workflows_listA
Read-onlyIdempotent
Inspect

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoWorkflow id.
runsNoWith id: return run history instead.
limitNoRuns to return. Default 20.

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_manage
Destructive
Inspect

Automations. create (a trigger and steps; active by default and then acts by itself, so confirm), update (isActive false pauses), delete (confirm first).

ParametersJSON Schema
NameRequiredDescriptionDefault
idNo
nameNo
stepsNoOrdered 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.
actionYes
isActiveNoDefault true.
conditionNoSkip 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).
descriptionNo
triggerTypeNo
triggerEventNoEvent name, or inbound webhook id.
triggerConfigNoScheduled 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes
entityIdYes
entityTypeYes

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters2/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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. 1 tool update
    • Changedforms_manage1 field changed
      • addedInput schema / properties / style
        Added 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"
        +}
  2. 1 tool update
    • Changedtasks_manage1 field changed
      • addedInput schema / properties / color
        Added 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"
        +}
  3. 105 tool updates
    • Removedaddresses_create
    • Removedaddresses_delete
    • Removedaddresses_list
    • Addedaddresses_manage
    • Removedaddresses_update
    • Removedbilling_profiles_list
    • Addedbilling_profiles_manage
    • Removedbilling_profiles_save
    • Removedcompanies_create
    • Removedcompanies_delete
    • Changedcompanies_list1 field changed
      • addedInput schema / properties / deleted
        Added value: +{
        +  "description": "List recently deleted companies instead (to restore).",
        +  "type": "boolean"
        +}
    • Addedcompanies_manage
    • Removedcompanies_update
    • Removedcontacts_create
    • Removedcontacts_delete
    • Changedcontacts_list6 fields changed
      • addedInput schema / properties / companyId
        Added value: +{
        +  "description": "Only contacts at this company.",
        +  "type": "string"
        +}
      • addedInput schema / properties / deleted
        Added value: +{
        +  "description": "List recently deleted contacts instead.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / duplicates
        Added value: +{
        +  "description": "List groups of live contacts sharing an email or phone instead.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "recent = last contacted. Default name.",
        +  "enum": [
        +    "name",
        +    "created",
        +    "updated",
        +    "recent"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / tag
        Added value: +{
        +  "description": "Only contacts with this tag (name or id).",
        +  "type": "string"
        +}
      • addedInput schema / properties / unsubscribed
        Added value: +{
        +  "description": "Opted out of any channel / email / texts, or none (for an audience).",
        +  "enum": [
        +    "any",
        +    "email",
        +    "sms",
        +    "none"
        +  ],
        +  "type": "string"
        +}
    • Addedcontacts_manage
    • Removedcontacts_update
    • Removedcustom_fields_create
    • Removedcustom_fields_delete
    • Changedcustom_fields_list1 field changed
      • addedInput schema / properties / mergeTags
        Added value: +{
        +  "description": "List merge tags instead.",
        +  "type": "boolean"
        +}
    • Addedcustom_fields_manage
    • Removedcustom_fields_set_value
    • Removedcustom_fields_update
    • Changeddashboard_summary1 field changed
      • addedInput schema / properties / pipeline
        Added value: +{
        +  "description": "Per-stage open deals instead.",
        +  "type": "boolean"
        +}
    • Removeddeal_stages_create
    • Addeddeal_stages_manage
    • Removeddeal_stages_update
    • Removeddeals_create
    • Removeddeals_delete
    • Changeddeals_list1 field changed
      • addedInput schema / properties / deleted
        Added value: +{
        +  "description": "List recently deleted deals instead (to restore).",
        +  "type": "boolean"
        +}
    • Addeddeals_manage
    • Removeddeals_update
    • Removedemail_accounts_list
    • Removedemail_get_thread
    • Removedemail_list_threads
    • Addedemail_read
    • Removedemail_suppressions_manage
    • Addedemail_thread_update
    • Removedinvoice_items_list
    • Addedinvoice_items_manage
    • Removedinvoice_items_save
    • Addedinvoice_payments_manage
    • Removedinvoice_payments_record
    • Removedinvoice_payments_reverse
    • Addedinvoice_settings
    • Removedinvoice_settings_get
    • Removedinvoice_settings_update
    • Removedinvoices_issue
    • Changedinvoices_list7 fields changed
      • addedInput schema / properties / companyId
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / contactId
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / creditNotes
        Added value: +{
        +  "description": "With id: its credit notes.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Default 100.",
        +  "maximum": 500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedInput schema / properties / q
        Added value: +{
        +  "description": "Matches number and customer.",
        +  "type": "string"
        +}
      • addedInput schema / properties / recurring
        Added value: +{
        +  "description": "With id: its repeat schedule (null if none).",
        +  "type": "boolean"
        +}
    • Addedinvoices_manage
    • Removedinvoices_save_draft
    • Removedinvoices_send
    • Removedinvoices_void
    • Removedmeeting_types_create
    • Removedmeeting_types_delete
    • Addedmeeting_types_manage
    • Removedmeeting_types_update
    • Removedmerge_tags_list
    • Removednotes_create
    • Removednotes_delete
    • Addednotes_manage
    • Removednotes_update
    • Addedphone_status
    • Removedquotes_convert
    • Removedquotes_issue
    • Addedquotes_manage
    • Removedquotes_record_outcome
    • Removedquotes_save_draft
    • Removedquotes_send
    • Removedquotes_void
    • Removedsaved_views_create
    • Removedsaved_views_delete
    • Addedsaved_views_manage
    • Removedsms_cancel_scheduled
    • Changedsms_list1 field changed
      • addedInput schema / properties / contactId
        Added value: +{
        +  "description": "Or the contact (their primary number is used).",
        +  "type": "string"
        +}
    • Addedsms_manage
    • Removedsms_optouts
    • Addedsuppressions_manage
    • Removedtags_apply
    • Removedtags_create
    • Removedtags_delete
    • Addedtags_manage
    • Removedtags_update
    • Removedtasks_create
    • Removedtasks_delete
    • Addedtasks_manage
    • Removedtasks_update
    • Removedtemplates_create
    • Removedtemplates_delete
    • Addedtemplates_manage
    • Removedtemplates_update
    • Removedtime_log
    • Addedtime_manage
    • Removedtime_timer
    • Removedtime_update
    • Removedtwilio_balance_get
    • Removedvoicemail_drops_create
    • Removedvoicemail_drops_delete
    • Addedvoicemail_drops_manage
    • Removedvoicemail_drops_update
    • Removedworkflows_create
    • Removedworkflows_delete
    • Addedworkflows_manage
    • Removedworkflows_update
  4. 4 tool updates
    • Addedmeetings_book
    • Addedtime_timer
    • Removedtime_timer_start
    • Removedtime_timer_stop
  5. 1 tool update
    • Addeddocuments_manage
  6. 2 tool updates
    • Changedworkflows_create1 field changed
      • changedInput schema / properties / condition / description
        Previous 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)."
    • Changedworkflows_update1 field changed
      • addedInput schema / properties / condition / description
        Added 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)."
  7. 1 tool update
    • Changedtasks_delete2 fields changed
      • addedInput schema / properties / remove_from_google
        Added 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"
        +}
      • addedInput schema / properties / scope
        Added 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"
        +}
  8. 13 tool updates
    • Changedaddresses_create1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedaddresses_update1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedcontacts_create1 field changed
      • addedInput schema / required
        Added value: +[
        +  "firstName"
        +]
    • Changeddeals_create3 fields changed
      • changedInput schema / properties / closeAt / description
        Previous value: -"Expected close date, ISO 8601."New value: +"Expected close date, YYYY-MM-DD or ISO 8601."
      • removedInput schema / properties / currency
        Removed value: -{
        -  "description": "ISO 4217. Defaults to the user's currency.",
        -  "type": "string"
        -}
      • addedInput schema / properties / valueCents / description
        Added value: +"In the account's default currency (deals have no currency of their own)."
    • Changeddeals_list2 fields changed
      • addedInput schema / properties / companyId
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / contactId
        Added value: +{
        +  "type": "string"
        +}
    • Changeddeals_update3 fields changed
      • addedInput schema / properties / closeAt / description
        Added value: +"YYYY-MM-DD or ISO 8601; null clears it."
      • changedInput schema / properties / closeAt / type
        Previous value: -"string"New value: +[
        +  "string",
        +  "null"
        +]
      • removedInput schema / properties / currency
        Removed value: -{
        -  "type": "string"
        -}
    • Changedemail_get_thread1 field changed
      • addedInput schema / properties / threadKey / description
        Added value: +"The `thread_id` from email_list_threads."
    • Changedemail_list_threads1 field changed
      • changedInput schema / properties / search / description
        Previous value: -"Matches subject, participant address and snippet."New value: +"Matches subject, sender and message text."
    • Changedemail_suppressions_manage1 field changed
      • addedInput schema / properties / emails / maxItems
        Added value: +5000
    • Changedinvoices_void1 field changed
      • addedInput schema / properties / confirm_paid
        Added value: +{
        +  "description": "Void even though payments or credit notes are recorded on it. Only after the user has confirmed. Default false.",
        +  "type": "boolean"
        +}
    • Changedoutbound_webhooks_manage2 fields changed
      • changedInput schema / properties / events / description
        Previous 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."
      • changedInput schema / properties / url / description
        Previous value: -"HTTPS. Required on create."New value: +"Public http(s) URL (use https: the payload is CRM data). Required on create."
    • Changedsms_optouts1 field changed
      • addedInput schema / properties / phones / maxItems
        Added value: +500
    • Changedworkflows_run_now1 field changed
      • removedInput schema / properties / payload
        Removed value: -{
        -  "description": "Extra trigger payload.",
        -  "type": "object"
        -}
  9. 3 tool updates
    • Changedcampaigns_manage1 field changed
      • addedInput schema / properties / contact_ids / maxItems
        Added value: +500
    • Changedtags_apply1 field changed
      • addedInput schema / properties / contactIds / maxItems
        Added value: +500
    • Changedtasks_create1 field changed
      • addedInput schema / properties / textContact
        Added value: +{
        +  "description": "Meetings: text the contact a confirmation and reminders. Default false.",
        +  "type": "boolean"
        +}
  10. 1 tool update
    • Removedfrontdesk_settings
  11. 1 tool update
    • Changedcampaigns_manage5 fields changed
      • changedInput schema / properties / action / enum
        Previous 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"
        +]
      • changedInput schema / properties / content / description
        Previous 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."
      • addedInput schema / properties / kind
        Added value: +{
        +  "description": "list filter: newsletters, or everything else.",
        +  "enum": [
        +    "newsletter",
        +    "campaign"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / role
        Added value: +{
        +  "description": "newsletter_templates: another industry's set (e.g. real estate, mortgage, insurance). Default: the user's own.",
        +  "type": "string"
        +}
      • addedInput schema / properties / template_id
        Added value: +{
        +  "description": "create: start a newsletter from this template (newsletter_templates). name defaults to the template name.",
        +  "type": "string"
        +}
  12. 3 tool updates
    • Addedemail_suppressions_manage
    • Addedforms_manage
    • Changedmeeting_types_update1 field changed
      • changedInput schema / properties / availability / description
        Previous 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."
  13. 1 tool update
    • Changedworkflows_create1 field changed
      • changedInput schema / properties / triggerConfig / description
        Previous 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."
  14. 1 tool update
    • Changedcampaigns_manage1 field changed
      • addedInput schema / properties / audience
        Added value: +{
        +  "description": "duplicate: copy goes only to people the (sent, email) campaign reached who did not open it.",
        +  "enum": [
        +    "non_openers"
        +  ],
        +  "type": "string"
        +}
  15. 120 tool updates
    • Changedactivity_list3 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Scope to one company."
      • removedInput schema / properties / contactId / description
        Removed value: -"Scope to one contact's activity."
      • removedInput schema / properties / dealId / description
        Removed value: -"Scope to one deal."
    • Changedaddresses_create5 fields changed
      • changedInput schema / properties / is_primary / description
        Previous 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)."
      • changedInput schema / properties / label / description
        Previous value: -"Short label, e.g. 'home', 'office', 'site'. Free text."New value: +"e.g. 'home', 'office'."
      • removedInput schema / properties / notes / description
        Removed value: -"Anything else — access codes, \"rear entrance\"."
      • removedInput schema / properties / postal_code / description
        Removed value: -"Postal or ZIP code."
      • removedInput schema / properties / street / description
        Removed value: -"Street address line."
    • Changedaddresses_delete1 field changed
      • removedInput schema / properties / addressId / description
        Removed value: -"From addresses_list."
    • Changedaddresses_list2 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"The company to read addresses for."
      • removedInput schema / properties / contactId / description
        Removed value: -"The contact to read addresses for."
    • Changedaddresses_update6 fields changed
      • removedInput schema / properties / addressId / description
        Removed value: -"From addresses_list."
      • changedInput schema / properties / is_primary / description
        Previous 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)."
      • changedInput schema / properties / label / description
        Previous value: -"Short label, e.g. 'home', 'office', 'site'. Free text."New value: +"e.g. 'home', 'office'."
      • removedInput schema / properties / notes / description
        Removed value: -"Anything else — access codes, \"rear entrance\"."
      • removedInput schema / properties / postal_code / description
        Removed value: -"Postal or ZIP code."
      • removedInput schema / properties / street / description
        Removed value: -"Street address line."
    • Removedbilling_profiles_create
    • Removedbilling_profiles_get
    • Changedbilling_profiles_list2 fields changed
      • addedInput schema / properties / companyId
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / contactId
        Added value: +{
        +  "type": "string"
        +}
    • Addedbilling_profiles_save
    • Removedbilling_profiles_update
    • Removedcalls_get
    • Changedcalls_list3 fields changed
      • removedInput schema / properties / contactId / description
        Removed value: -"Limit to calls with this contact."
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Call id. Returns that one call.",
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Max records. Default 100, max 500."New value: +"Default 100, max 500."
    • Changedcampaigns_analytics4 fields changed
      • removedInput schema / properties / id / description
        Removed value: -"Campaign UUID."
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Recipients: default 100.",
        +  "maximum": 500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / recipients
        Added value: +{
        +  "description": "Return per-recipient status rows.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / status
        Added value: +{
        +  "description": "Recipients filter.",
        +  "enum": [
        +    "queued",
        +    "sent",
        +    "delivered",
        +    "opened",
        +    "clicked",
        +    "bounced",
        +    "unsubscribed",
        +    "replied",
        +    "failed"
        +  ],
        +  "type": "string"
        +}
    • Removedcampaigns_list_recipients
    • Changedcampaigns_manage18 fields changed
      • removedInput schema / properties / action / description
        Removed 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."
      • changedInput schema / properties / action / enum
        Previous 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"
        +]
      • changedInput schema / properties / audience_filter / description
        Previous 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."
      • changedInput schema / properties / contact_ids / description
        Previous value: -"For add_recipients: contact ids, at most 500."New value: +"add_recipients: up to 500."
      • changedInput schema / properties / content / description
        Previous 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."
      • changedInput schema / properties / enrolment_mode / description
        Previous 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)."
      • changedInput schema / properties / id / description
        Previous value: -"Campaign UUID — required for everything except list+create."New value: +"Campaign id; needed for all but list, create, preview_audience."
      • changedInput schema / properties / q / description
        Previous value: -"Free-text name search for action=list."New value: +"list: name search."
      • changedInput schema / properties / scheduled_at / description
        Previous value: -"Unix seconds for schedule/create."New value: +"Unix seconds."
      • changedInput schema / properties / sending_window / description
        Previous 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."
      • changedInput schema / properties / status / description
        Previous value: -"Filter for action=list."New value: +"list filter."
      • changedInput schema / properties / steps / description
        Previous 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."
      • removedInput schema / properties / steps / items / properties / channel / description
        Removed value: -"Overrides the campaign channel for this step only."
      • changedInput schema / properties / steps / items / properties / content / description
        Previous value: -"Alias for content_json, accepted for compatibility."New value: +"Alias of content_json."
      • changedInput schema / properties / steps / items / properties / content_json / description
        Previous value: -"Message for this step. Same shape as the top-level content param. Canonical key."New value: +"Same shape as content."
      • removedInput schema / properties / steps / items / properties / delay_seconds / description
        Removed value: -"Seconds after the previous step's actual send. Step 0 should be 0."
      • removedInput schema / properties / steps / items / properties / exit_on / description
        Removed value: -"Skip the rest of the drip for a contact who has replied/opened/clicked, or booked a meeting."
      • changedInput schema / properties / to / description
        Previous value: -"For action='test_send' — recipient email or phone."New value: +"test_send recipient."
    • Removedcampaigns_preview_audience
    • Changedcompanies_create2 fields changed
      • removedInput schema / properties / name / description
        Removed value: -"Company name. Required."
      • changedInput schema / properties / website / description
        Previous value: -"https:// URL."New value: +"Include https://."
    • Removedcompanies_get
    • Changedcompanies_list4 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Company id. Returns that one company.",
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (default 50)."New value: +"Default 50."
      • removedInput schema / properties / offset / description
        Removed value: -"Pagination offset (default 0)."
      • changedInput schema / properties / search / description
        Previous value: -"Free-text search across company name + website."New value: +"Matches name and website."
    • Changedcontacts_create4 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Existing company UUID, if linking."
      • removedInput schema / properties / notes / description
        Removed value: -"Free-text notes to attach on creation."
      • changedInput schema / properties / phone / description
        Previous value: -"Primary phone. Will be normalized to E.164."New value: +"Normalised to E.164."
      • changedInput schema / properties / tags / description
        Previous value: -"Tag names; created on the fly if missing."New value: +"Tag names; missing ones are created."
    • Removedcontacts_get
    • Changedcontacts_list4 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Contact id. Returns that one contact; other filters ignored.",
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Max results (1-1000, default 50)."New value: +"Default 50."
      • removedInput schema / properties / offset / description
        Removed value: -"Pagination offset, default 0."
      • changedInput schema / properties / search / description
        Previous value: -"Free-text search across name, email, phone."New value: +"Matches name, email, phone."
    • Changedcontacts_update1 field changed
      • removedInput schema / properties / id / description
        Removed value: -"Contact UUID."
    • Changedcustom_fields_create5 fields changed
      • removedInput schema / properties / entityType / description
        Removed value: -"Which entity gets this custom field."
      • changedInput schema / properties / fieldKey / description
        Previous value: -"Optional — explicit identifier (snake_case, ≤60 chars). Defaults to a slug of `name`."New value: +"snake_case, max 60 chars."
      • changedInput schema / properties / name / description
        Previous value: -"Human label, e.g. \"Loan amount\" or \"Referral source\"."New value: +"Label, e.g. \"Loan amount\"."
      • changedInput schema / properties / options / description
        Previous value: -"For type=select only: the list of allowed values, e.g. [\"Hot\", \"Warm\", \"Cold\"]."New value: +"Required for type select."
      • removedInput schema / properties / type / description
        Removed value: -"Field type. `select` requires the `options` array."
    • Changedcustom_fields_delete1 field changed
      • removedInput schema / properties / id / description
        Removed value: -"Custom field UUID."
    • Changedcustom_fields_list1 field changed
      • changedInput schema / properties / entityType / description
        Previous value: -"Optional — filter to fields on one entity type. Omit for all."New value: +"Omit for all."
    • Changedcustom_fields_set_value4 fields changed
      • removedInput schema / properties / entityId / description
        Removed value: -"UUID of the contact/company/deal."
      • removedInput schema / properties / entityType / description
        Removed value: -"Which entity the value is being set on."
      • changedInput schema / properties / fieldKey / description
        Previous value: -"Custom field identifier (e.g. \"loan_amount\")."New value: +"e.g. \"loan_amount\"."
      • removedInput schema / properties / value / description
        Removed value: -"New value. Null clears the field."
    • Changedcustom_fields_update4 fields changed
      • removedInput schema / properties / id / description
        Removed value: -"Custom field UUID. Get from custom_fields_list."
      • removedInput schema / properties / name / description
        Removed value: -"New human label."
      • changedInput schema / properties / options / description
        Previous value: -"For type=select fields only: replace the allowed-values list."New value: +"Select fields: replaces the list."
      • changedInput schema / properties / position / description
        Previous value: -"Order in the field list (lower = first)."New value: +"Lower sorts first."
    • Changeddeal_stages_create5 fields changed
      • changedInput schema / properties / color / description
        Previous value: -"Hex colour like \"#0EA5E9\". Optional."New value: +"Hex, e.g. \"#0EA5E9\"."
      • removedInput schema / properties / isLost / description
        Removed value: -"Marks this the lost stage."
      • removedInput schema / properties / isWon / description
        Removed value: -"Marks this the won/closed stage."
      • removedInput schema / properties / name / description
        Removed value: -"Stage name, e.g. \"Quote sent\"."
      • changedInput schema / properties / position / description
        Previous value: -"Zero-based order. Omit to append."New value: +"Zero-based order."
    • Removeddeal_stages_reorder
    • Changeddeal_stages_update5 fields changed
      • changedInput schema / properties / color / description
        Previous value: -"New hex colour."New value: +"Hex colour."
      • changedInput schema / properties / id / description
        Previous value: -"Stage id from deal_stages_list."New value: +"Stage to rename/recolour."
      • removedInput schema / properties / name / description
        Removed value: -"New name."
      • addedInput schema / properties / order
        Added value: +{
        +  "description": "All stage ids in the new order. A partial list leaves the rest unplaced.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "id"
        -]
    • Changeddeals_create5 fields changed
      • changedInput schema / properties / closeAt / description
        Previous value: -"ISO 8601 expected close date."New value: +"Expected close date, ISO 8601."
      • changedInput schema / properties / currency / description
        Previous value: -"ISO 4217 e.g. \"USD\", \"CAD\". Defaults to user's currency."New value: +"ISO 4217. Defaults to the user's currency."
      • removedInput schema / properties / stageId / description
        Removed value: -"Pipeline stage UUID (see deal_stages.list)."
      • removedInput schema / properties / title / description
        Removed value: -"Short deal name e.g. \"Acme Q3 renewal\"."
      • removedInput schema / properties / valueCents / description
        Removed value: -"Amount in cents."
    • Removeddeals_get
    • Changeddeals_list3 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Deal id. Returns that one deal.",
        +  "type": "string"
        +}
      • changedInput schema / properties / search / description
        Previous value: -"Free-text search across title, contact name, company name."New value: +"Matches title, contact and company name."
      • changedInput schema / properties / stageId / description
        Previous value: -"Filter to a specific stage UUID (see deal_stages.list)."New value: +"From deal_stages_list."
    • Removeddeals_move_stage
    • Removedemail_get_message_body
    • Changedemail_get_thread3 fields changed
      • addedInput schema / properties / messageId
        Added value: +{
        +  "description": "Fetches that message's body (slower; only when the snippet is not enough).",
        +  "type": "string"
        +}
      • removedInput schema / properties / threadKey / description
        Removed value: -"From email_list_threads."
      • removedInput schema / required
        Removed value: -[
        -  "threadKey"
        -]
    • Changedemail_list_threads4 fields changed
      • changedInput schema / properties / account / description
        Previous value: -"Limit to one connected account id. Omit for all."New value: +"Mailbox id from email_accounts_list. Default: all."
      • changedInput schema / properties / folder / description
        Previous value: -"Which folder to list. Defaults to everything."New value: +"Default: all."
      • changedInput schema / properties / limit / description
        Previous value: -"Max threads to return. Default 25."New value: +"Default 25, max 100."
      • changedInput schema / properties / search / description
        Previous value: -"Match against subject, participant address and snippet."New value: +"Matches subject, participant address and snippet."
    • Changedemail_send12 fields changed
      • changedInput schema / properties / accountId / description
        Previous value: -"Optional mailbox UUID from email_accounts_list. Defaults to the oldest connected mailbox."New value: +"Sending mailbox, from email_accounts_list."
      • removedInput schema / properties / bcc / description
        Removed value: -"BCC list (comma-separated)."
      • removedInput schema / properties / bodyHtml / description
        Removed value: -"HTML body (preferred). Supports merge tags."
      • removedInput schema / properties / bodyText / description
        Removed value: -"Plain-text body. Sent alongside HTML if both given."
      • removedInput schema / properties / cc / description
        Removed value: -"CC list (comma-separated)."
      • removedInput schema / properties / contactId / description
        Removed value: -"Optional contact UUID. When set, merge tags resolve and the thread attaches to the contact. It does not pick the mailbox."
      • changedInput schema / properties / fromEmail / description
        Previous 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)."
      • removedInput schema / properties / fromName / description
        Removed value: -"Optional display name for the From header. Defaults to the alias's or mailbox's saved name."
      • changedInput schema / properties / scheduledSendAt / description
        Previous 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."
      • removedInput schema / properties / subject / description
        Removed value: -"Subject line. Supports merge tags when contactId is provided."
      • changedInput schema / properties / to / description
        Previous value: -"Recipient email or comma-separated list."New value: +"Address or comma-separated list."
      • changedInput schema / properties / trackOpens / description
        Previous 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)."
    • Removedemail_templates_create
    • Removedemail_templates_delete
    • Removedemail_templates_get
    • Removedemail_templates_list
    • Removedemail_templates_update
    • Changedfrontdesk_settings2 fields changed
      • changedInput schema / properties / hours / description
        Previous 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."
      • changedInput schema / properties / override / description
        Previous 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."
    • Changedinbound_webhooks_manage9 fields changed
      • removedInput schema / properties / action / description
        Removed value: -"Which operation to run."
      • removedInput schema / properties / description / description
        Removed value: -"Optional longer-form context."
      • changedInput schema / properties / id / description
        Previous value: -"Inbound webhook UUID. Required for get/update/delete."New value: +"For get/update/delete."
      • changedInput schema / properties / ipAllowlist / description
        Previous value: -"Optional CIDR list. Empty = any IP."New value: +"CIDRs. Empty = any IP."
      • changedInput schema / properties / isActive / description
        Previous value: -"Pause receiving by setting to false (update only)."New value: +"Update only; false pauses receiving."
      • changedInput schema / properties / mappingJson / description
        Previous 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."
      • changedInput schema / properties / mappingMode / description
        Previous value: -"Default \"native\" on create."New value: +"Default native."
      • changedInput schema / properties / name / description
        Previous value: -"Display name. Required on create."New value: +"Required on create."
      • changedInput schema / properties / signingSecret / description
        Previous value: -"Optional HMAC secret (create only). Senders include X-Groundbase-Signature."New value: +"Optional HMAC secret (create only); senders send X-Groundbase-Signature."
    • Removedinvoice_items_create
    • Addedinvoice_items_save
    • Removedinvoice_items_update
    • Removedinvoice_payments_list
    • Changedinvoice_payments_record6 fields changed
      • changedInput schema / properties / amount / description
        Previous value: -"Decimal string in the invoice currency, e.g. \"1600.00\"."New value: +"Decimal string in the invoice currency."
      • removedInput schema / properties / method / description
        Removed value: -"bank_transfer | card | cash | cheque | other"
      • changedInput schema / properties / receivedAt / description
        Previous value: -"ISO date or datetime. Defaults to now."New value: +"ISO date. Default now."
      • changedInput schema / properties / reference / description
        Previous value: -"Cheque number, transfer reference, or payment id."New value: +"Cheque number or transfer reference."
      • changedInput schema / properties / sendReceipt / description
        Previous value: -"Default true. Set false for cash handed over in person where a receipt was already given."New value: +"Default true."
      • removedInput schema / properties / sendVia / description
        Removed value: -"Force a transport: smtp or resend. Defaults to the user's SMTP account when connected."
    • Changedinvoice_settings_update5 fields changed
      • removedInput schema / properties / defaultCurrency / description
        Removed value: -"ISO 4217."
      • removedInput schema / properties / nextNumber / description
        Removed value: -"Forward only. Useful when moving from another system mid-sequence."
      • changedInput schema / properties / numberPadding / description
        Previous value: -"Minimum digits, 1-12. 4 gives INV-0007."New value: +"Min digits 1-12."
      • changedInput schema / properties / numberPrefix / description
        Previous value: -"e.g. \"INV-\". Up to 16 characters."New value: +"e.g. \"INV-\", max 16 chars."
      • changedInput schema / properties / paymentInstructions / description
        Previous value: -"Free text. Line breaks are kept."New value: +"How to pay (bank details, link)."
    • Removedinvoices_create_draft
    • Removedinvoices_get
    • Changedinvoices_list2 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Invoice id. Returns that one invoice.",
        +  "type": "string"
        +}
      • addedInput schema / properties / payments
        Added value: +{
        +  "description": "With id: return the payment ledger (incl. reversed payments).",
        +  "type": "boolean"
        +}
    • Addedinvoices_save_draft
    • Changedinvoices_send2 fields changed
      • changedInput schema / properties / sendVia / description
        Previous value: -"Which connected sender to use. Defaults to SMTP when both exist."New value: +"Default smtp when both exist."
      • changedInput schema / properties / to / description
        Previous 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."
    • Removedinvoices_update_draft
    • Changedmeeting_types_create5 fields changed
      • changedInput schema / properties / bufferMin / description
        Previous value: -"Gap to leave after each booking, in minutes."New value: +"Minutes kept free after each booking."
      • removedInput schema / properties / description / description
        Removed value: -"Optional blurb on the booking page."
      • changedInput schema / properties / durationMin / description
        Previous value: -"Length in minutes. Default 30."New value: +"Minutes. Default 30."
      • removedInput schema / properties / name / description
        Removed value: -"Shown to the person booking, e.g. \"Intro call\"."
      • removedInput schema / properties / slug / description
        Removed value: -"URL segment, lowercase and hyphenated."
    • Addedmeeting_types_delete
    • Addedmeeting_types_update
    • Changednotes_create1 field changed
      • removedInput schema / properties / body / description
        Removed value: -"Note text."
    • Changednotes_list4 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Limit to one company."
      • removedInput schema / properties / contactId / description
        Removed value: -"Limit to one contact."
      • removedInput schema / properties / dealId / description
        Removed value: -"Limit to one deal."
      • removedInput schema / properties / offset / description
        Removed value: -"Default 0."
    • Changedoutbound_webhooks_manage7 fields changed
      • removedInput schema / properties / action / description
        Removed value: -"Which operation to run."
      • removedInput schema / properties / description / description
        Removed value: -"Optional longer-form context."
      • changedInput schema / properties / events / description
        Previous 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."
      • changedInput schema / properties / id / description
        Previous value: -"Subscription UUID. Required for get/update/delete."New value: +"For get/update/delete."
      • changedInput schema / properties / isActive / description
        Previous value: -"Pause delivery by setting to false (update only)."New value: +"Update only; false pauses delivery."
      • changedInput schema / properties / name / description
        Previous value: -"Short human-readable identifier, e.g. \"Slack #wins channel\". Required on create."New value: +"Required on create."
      • changedInput schema / properties / url / description
        Previous value: -"HTTPS URL Groundbase will POST to. Required on create."New value: +"HTTPS. Required on create."
    • Removedquotes_accept
    • Removedquotes_create_draft
    • Removedquotes_decline
    • Removedquotes_get
    • Changedquotes_list4 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Only quotes for this company."
      • removedInput schema / properties / contactId / description
        Removed value: -"Only quotes for this contact."
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Quote id. Returns that one quote.",
        +  "type": "string"
        +}
      • changedInput schema / properties / status / description
        Previous value: -"draft | open | accepted | declined | void | expired"New value: +"draft | open | accepted | declined | void | expired (open but past valid-until)"
    • Addedquotes_record_outcome
    • Addedquotes_save_draft
    • Changedquotes_send3 fields changed
      • changedInput schema / properties / message / description
        Previous value: -"A covering note above the quote. Same tokens."New value: +"Covering note; same tokens."
      • changedInput schema / properties / subject / description
        Previous value: -"Override the subject. Tokens {number} {business} {customer} {amount} {due} are filled in."New value: +"Tokens {number} {business} {customer} {amount} {due}."
      • changedInput schema / properties / to / description
        Previous value: -"Override the recipient. Defaults to the billing email, then the contact's email."New value: +"Default: billing email, then the contact's email."
    • Removedquotes_update_draft
    • Changedresend_manage1 field changed
      • changedInput schema / properties / to / description
        Previous value: -"For action='test_send' — recipient email."New value: +"test_send recipient."
    • Changedsaved_views_create3 fields changed
      • removedInput schema / properties / entityType / description
        Removed value: -"Which record type this view filters."
      • changedInput schema / properties / filterJson / description
        Previous value: -"Filter definition, JSON-encoded."New value: +"JSON-encoded filter."
      • removedInput schema / properties / name / description
        Removed value: -"What the user will see in the sidebar."
    • Addedsaved_views_delete
    • Changedsending_settings3 fields changed
      • removedInput schema / properties / action / description
        Removed value: -"'get' to read, 'set' to write."
      • changedInput schema / properties / daily_email_send_cap / description
        Previous value: -"For action='set'. Non-negative integer, or null to remove the cap entirely."New value: +"set: non-negative integer or null."
      • changedInput schema / properties / domain / description
        Previous 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."
    • Changedsms_cancel_scheduled1 field changed
      • removedInput schema / properties / id / description
        Removed value: -"sms_messages row UUID."
    • Addedsms_list
    • Removedsms_list_scheduled
    • Removedsms_list_thread
    • Changedsms_optouts3 fields changed
      • changedInput schema / properties / phone / description
        Previous value: -"For action='remove', or a single 'add'."New value: +"For 'remove', or a single 'add'."
      • changedInput schema / properties / phones / description
        Previous value: -"For action='add' — one or more numbers, any format. Max 500."New value: +"For 'add': up to 500 numbers, any format."
      • changedInput schema / properties / source / description
        Previous 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."
    • Addedsms_send
    • Removedsms_send_now
    • Removedsms_send_scheduled
    • Removedsms_templates_create
    • Removedsms_templates_delete
    • Removedsms_templates_get
    • Removedsms_templates_list
    • Removedsms_templates_update
    • Changedtags_apply3 fields changed
      • removedInput schema / properties / contactIds / description
        Removed value: -"Contact UUIDs."
      • addedInput schema / properties / remove
        Added value: +{
        +  "description": "Remove the tag instead of adding it.",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / tagId / description
        Removed value: -"Tag UUID."
    • Changedtags_create1 field changed
      • changedInput schema / properties / color / description
        Previous value: -"Hex color, e.g. \"#B91C1C\". Optional."New value: +"Hex, e.g. \"#B91C1C\"."
    • Removedtags_remove
    • Removedtasks_complete
    • Changedtasks_create6 fields changed
      • changedInput schema / properties / dueAt / description
        Previous value: -"ISO 8601 — when the task is due (for kind=task)."New value: +"ISO 8601, for tasks."
      • changedInput schema / properties / endAt / description
        Previous value: -"ISO 8601 — end time (for event/meeting)."New value: +"ISO 8601."
      • changedInput schema / properties / kind / description
        Previous value: -"Default: task."New value: +"Default task."
      • removedInput schema / properties / location / description
        Removed value: -"For meetings."
      • changedInput schema / properties / recurrence / description
        Previous 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."
      • changedInput schema / properties / startAt / description
        Previous value: -"ISO 8601 — start time (for event/meeting)."New value: +"ISO 8601, for events/meetings."
    • Removedtasks_get
    • Changedtasks_list5 fields changed
      • removedInput schema / properties / contactId / description
        Removed value: -"Limit to a single contact's tasks."
      • removedInput schema / properties / dealId / description
        Removed value: -"Limit to a single deal."
      • changedInput schema / properties / from / description
        Previous value: -"ISO 8601 — only items due on/after this date."New value: +"ISO 8601; due on/after."
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Task id. Returns that one item.",
        +  "type": "string"
        +}
      • changedInput schema / properties / to / description
        Previous value: -"ISO 8601 — only items due on/before this date."New value: +"ISO 8601; due on/before."
    • Changedtasks_update1 field changed
      • removedInput schema / properties / recurrence / description
        Removed 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."
    • Addedtemplates_create
    • Addedtemplates_delete
    • Addedtemplates_list
    • Addedtemplates_update
    • Changedtime_list5 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Company UUID the time is for."
      • removedInput schema / properties / contactId / description
        Removed value: -"Contact UUID the time is for."
      • changedInput schema / properties / dealId / description
        Previous value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company."
      • changedInput schema / properties / limit / description
        Previous value: -"Max entries. Default 50, max 500."New value: +"Default 50, max 500."
      • removedInput schema / properties / status / description
        Removed value: -"Optional filter."
    • Changedtime_log9 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Company UUID the time is for."
      • removedInput schema / properties / contactId / description
        Removed value: -"Contact UUID the time is for."
      • removedInput schema / properties / currency / description
        Removed value: -"ISO code for the rate."
      • changedInput schema / properties / dealId / description
        Previous value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company."
      • removedInput schema / properties / description / description
        Removed value: -"What the work was."
      • removedInput schema / properties / duration / description
        Removed value: -"\"1:30\", \"90m\", \"1.5h\", or hours as a number."
      • changedInput schema / properties / endedAt / description
        Previous value: -"ISO 8601 end. Optional."New value: +"ISO 8601."
      • changedInput schema / properties / rate / description
        Previous value: -"Hourly rate as a decimal. Optional; inherited if omitted."New value: +"Hourly; inherited if omitted."
      • changedInput schema / properties / startedAt / description
        Previous value: -"ISO 8601 start. Optional."New value: +"ISO 8601."
    • Changedtime_timer_start6 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Company UUID the time is for."
      • removedInput schema / properties / contactId / description
        Removed value: -"Contact UUID the time is for."
      • changedInput schema / properties / currency / description
        Previous value: -"ISO code for the rate. Defaults to the user's invoicing currency."New value: +"Default: invoicing currency."
      • changedInput schema / properties / dealId / description
        Previous value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company."
      • removedInput schema / properties / description / description
        Removed value: -"What the work is."
      • changedInput schema / properties / rate / description
        Previous value: -"Hourly rate as a decimal, e.g. \"85\". Optional."New value: +"Hourly, decimal string."
    • Changedtime_update8 fields changed
      • removedInput schema / properties / companyId / description
        Removed value: -"Company UUID the time is for."
      • removedInput schema / properties / contactId / description
        Removed value: -"Contact UUID the time is for."
      • changedInput schema / properties / dealId / description
        Previous value: -"Deal UUID. Fills in the deal's contact and company automatically."New value: +"Also fills in the deal's contact and company."
      • removedInput schema / properties / delete / description
        Removed value: -"Delete the entry."
      • removedInput schema / properties / duration / description
        Removed value: -"New duration."
      • removedInput schema / properties / id / description
        Removed value: -"Time entry id."
      • changedInput schema / properties / rate / description
        Previous value: -"New hourly rate; empty string clears it."New value: +"Empty string clears."
      • removedInput schema / properties / startedAt / description
        Removed value: -"New ISO 8601 start."
    • Changedvoicemail_drops_create1 field changed
      • changedInput schema / properties / name / description
        Previous value: -"Display name (e.g. \"Quick intro\", \"Follow-up after demo\"). Defaults to \"Untitled drop\" if blank."New value: +"Default \"Untitled drop\"."
    • Addedvoicemail_drops_delete
    • Changedvoicemail_drops_drop4 fields changed
      • changedInput schema / properties / contactId / description
        Previous value: -"Optional contact UUID. Worker pulls the contact's primary phone."New value: +"Uses the contact's primary phone."
      • changedInput schema / properties / dropId / description
        Previous value: -"UUID of the voicemail drop to play. From voicemail_drops_list."New value: +"A drop with has_audio."
      • changedInput schema / properties / fromNumberId / description
        Previous 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."
      • changedInput schema / properties / toPhone / description
        Previous 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."
    • Removedvoicemail_drops_generate_emma
    • Addedvoicemail_drops_update
    • Changedworkflows_create7 fields changed
      • changedInput schema / properties / condition / description
        Previous 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."
      • changedInput schema / properties / isActive / description
        Previous value: -"Defaults to true (workflow starts active)."New value: +"Default true."
      • removedInput schema / properties / name / description
        Removed value: -"Display name (required)."
      • changedInput schema / properties / steps / description
        Previous 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."
      • changedInput schema / properties / triggerConfig / description
        Previous 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? }."
      • changedInput schema / properties / triggerEvent / description
        Previous 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."
      • removedInput schema / properties / triggerType / description
        Removed value: -"Required."
    • Changedworkflows_delete1 field changed
      • removedInput schema / properties / id / description
        Removed value: -"Workflow UUID."
    • Removedworkflows_get
    • Changedworkflows_list3 fields changed
      • addedInput schema / properties / id
        Added value: +{
        +  "description": "Workflow id.",
        +  "type": "string"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "Runs to return. Default 20.",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / runs
        Added value: +{
        +  "description": "With id: return run history instead.",
        +  "type": "boolean"
        +}
    • Removedworkflows_pause
    • Removedworkflows_resume
    • Changedworkflows_run_now4 fields changed
      • removedInput schema / properties / entityId / description
        Removed value: -"UUID of the entity."
      • removedInput schema / properties / entityType / description
        Removed value: -"What entity to run the workflow against."
      • removedInput schema / properties / id / description
        Removed value: -"Workflow UUID."
      • changedInput schema / properties / payload / description
        Previous value: -"Optional extra payload data merged into the trigger context (alongside the loaded entity)."New value: +"Extra trigger payload."
    • Removedworkflows_runs
    • Changedworkflows_update3 fields changed
      • removedInput schema / properties / id / description
        Removed value: -"Workflow UUID."
      • addedInput schema / properties / isActive
        Added value: +{
        +  "type": "boolean"
        +}
      • removedInput schema / properties / triggerType / description
        Removed value: -"Required to switch a workflow between trigger families. See workflows_create for details on each type."
  16. 2 tool updates
    • Removedbilling_profile_create
    • Removedbilling_profile_get
  17. 2 tool updates
    • Changedcompanies_create4 fields changed
      • addedInput schema / properties / city
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / country
        Added value: +{
        +  "type": "string"
        +}
      • removedInput schema / properties / size
        Removed value: -{
        -  "description": "Free-form e.g. \"1-10\", \"Enterprise\".",
        -  "type": "string"
        -}
      • addedInput schema / properties / state
        Added value: +{
        +  "description": "State or province.",
        +  "type": "string"
        +}
    • Changedcompanies_update4 fields changed
      • addedInput schema / properties / city
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / country
        Added value: +{
        +  "type": "string"
        +}
      • removedInput schema / properties / size
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / state
        Added value: +{
        +  "type": "string"
        +}
  18. 10 tool updates
    • Addedquotes_accept
    • Addedquotes_convert
    • Addedquotes_create_draft
    • Addedquotes_decline
    • Addedquotes_get
    • Addedquotes_issue
    • Addedquotes_list
    • Addedquotes_send
    • Addedquotes_update_draft
    • Addedquotes_void

Publisher details

Operator
Groundbase
Vendor relationship
First-party
Trust center
Not applicable
Restrictions
Requires a Groundbase account. $9/mo flat, 14-day free trial. OAuth or API key.

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    16
    11 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources