Skip to main content
Glama
dragosh29

Plannr MCP Server

by dragosh29

Plannr MCP server

An MCP server that lets Claude, ChatGPT and other MCP clients work with a financial adviser's Plannr CRM: clients, households, reviews due, tasks, cases, plans and notes, and (when enabled) creating tasks and notes. It is built from Plannr's public documentation: the OpenAPI 3.0.3 spec "Plannr API Documentation" at apidocs.plannrcrm.com/source.json and the API guide at api-how-to.plannrcrm.com (authentication, required headers, pagination, rate limits).

Once it's connected, an adviser or administrator can ask things like:

  • "Whose annual review is due in the next month, and who is their adviser?"

  • "What's open for the Evans family: tasks, cases and plans?"

  • "Which of Sam Evans's pensions are under advice, and with which providers?"

  • "What did we last discuss with Sam? Show me the call notes since September."

  • With writes enabled: "Create a high-priority task to call Sam about drawdown on Friday, and log a meeting note on his record."

Tools

Tool

What it does

API calls

list_logins

The logins of the user behind the token: the account each acts as (UUID, name, type, role) and the firm. Shows which account the server acts for: PLANNR_ACCOUNT_UUID, or the one chosen from the same logins response by the rule below, or a note that none could be chosen.

GET /api/v1/logins

search_clients

Accounts (clients by default) by name, role, prospect flag, status, tags, assigned adviser or household, with sort.

GET /api/v1/account

list_reviews_due

Clients whose next review date falls in a window (today to +30 days by default), soonest first.

GET /api/v1/account with filter[next_review_date]=>=FROM,<=TO and sort=next_review_date

get_client

One account: adviser, administrator, paraplanner, owners, groups, tags, households, service level, review and agreement dates, custom field names.

GET /api/v1/account/{uuid}

list_households

Circles (households) with members by name, portal access and engagement rating.

GET /api/v1/circles

get_household

One circle with members, groups and last portal login.

GET /api/v1/circles/{uuid}

list_tasks

Tasks by client, assignee, related plan or case, priority, due-date range, open only, name, status, with sort; each with its author and who completed it.

GET /api/v1/task with include=author,completed_by

get_task

One task with its description, workflow and custom field names.

GET /api/v1/task/{uuid}

list_task_statuses

The firm's task statuses in board order (needed by create_task).

GET /api/v1/task-status

list_cases

Cases by client, household, employee, progress, review or completion dates, status or type, with participants by name. Sorting by value is not offered.

GET /api/v1/cases

get_case

One case with its linked plans and custom field names.

GET /api/v1/cases/{uuid}

list_plans

Plans by client, household, type, abstract type, status, provider, name or under-advice flag: type, provider, status, owners, review date. Sorting by value is not offered.

GET /api/v1/plans

get_plan

One plan with seller, sub-accounts by name and custom field names.

GET /api/v1/plans/{uuid}

list_client_notes

A client's notes, including notes on their plans, cases, tasks and risks, newest first, by type, date range, text or what they are attached to.

GET /api/v1/client/{client_uuid}/all-notes

create_task

Creates a task on a client, employee, case or plan. Only registered when writes are enabled.

POST /api/v1/task

add_note

Adds a call, note, meeting or email note to an account, household, case, plan or task, not visible to clients unless asked. Only registered when writes are enabled.

POST /api/v1/note

Not covered on purpose: everything else in an 875-operation API, including contact details and addresses endpoints, documents and files, fact finds, valuations, holdings, transactions, charges and fees, bank feeds, messages, webhooks, and every update and delete. Searching clients by email, phone number, National Insurance number or date of birth (all documented filters) is not offered either.

Related MCP server: CRM MCP Server

Setup

Requires Node 18 or later.

npm install
npm run build

You need a personal access token: in Plannr, go to Settings > Account Details and scroll to Personal Access Tokens. The guide recommends these for personal use and for agencies working on behalf of a Plannr customer. Plannr's OAuth2 authorization code flow (for apps used by many firms; client credentials are issued by emailing integrations@plannrcrm.com) is out of scope for this local version; see Going to production.

Most endpoints need the account to act for in an X-PLANNR-ACCOUNT-UUID header. Set PLANNR_ACCOUNT_UUID to the account.uuid of your employee login (the list_logins tool shows them). If it is not set, the server calls GET /api/v1/logins once and uses the response's preferred_account_uuid if there is one, otherwise your only employee login; if you have several employee logins it refuses and lists them so you can choose.

Claude Desktop: add this to claude_desktop_config.json:

{
  "mcpServers": {
    "plannr": {
      "command": "node",
      "args": ["/absolute/path/to/plannr-mcp/dist/index.js"],
      "env": { "PLANNR_ACCESS_TOKEN": "your-personal-access-token", "PLANNR_ACCOUNT_UUID": "your-employee-account-uuid" }
    }
  }
}

Claude Code:

claude mcp add plannr -e PLANNR_ACCESS_TOKEN=your-personal-access-token -e PLANNR_ACCOUNT_UUID=your-employee-account-uuid -- node /absolute/path/to/plannr-mcp/dist/index.js

Variable

Required

Meaning

PLANNR_ACCESS_TOKEN

yes

Your personal access token, sent as Authorization: Bearer …. A value pasted with its Bearer prefix is accepted.

PLANNR_ACCOUNT_UUID

no

The account to act for, sent as X-PLANNR-ACCOUNT-UUID. Resolved from GET /api/v1/logins when not set (see above).

PLANNR_ALLOW_WRITES

no

true to register create_task and add_note. Off by default.

PLANNR_BASE_URL

no

Defaults to https://api.plannrcrm.com. Used by the tests.

PLANNR_TOOL_BUDGET_S

no

Time budget per tool call in seconds (default 45; see Safety defaults). Lowered by the tests.

Every request carries Accept: application/json and Content-Type: application/json, which the guide lists as required, and every request except GET /api/v1/logins carries X-PLANNR-ACCOUNT-UUID.

Safety defaults

  • Read-only unless PLANNR_ALLOW_WRITES=true. Read tools carry the MCP readOnlyHint annotation; the two write tools are marked not read-only, not destructive and not idempotent. There is no update or delete tool.

  • Clients and everyone else are identified by UUID and name by default. Only with include_contact_details=true does a tool return email addresses (of accounts, logins, members, assignees, authors and participants), the primary email and phone number, custom field values (only their names are shown by default, because a firm can record income, health or anything else in them), third-party references (platform and provider references) and policy, proposal, linked-policy and sub-account policy numbers.

  • Never read from the records: money fields (plan values, valuations, case values, benefit amounts; see Status), bank details, National Insurance numbers, dates of birth and addresses. Every output is built field by field from a list of known fields, so a field of that kind is not copied even if a response carries it (the test suite serves records with date_of_birth, ni_number, bank_accounts, an address, an income and money objects and checks none of them comes back, with or without include_contact_details). The endpoints that hold contact details, addresses, documents and bank data are never called (the suite asserts the exact set of endpoints used). Sorting by value, which the API documents for cases and plans, is not offered, because the order would reveal the relative values the server otherwise withholds. No file is ever downloaded.

  • Free text (client, household, task, case, plan and sub-account names; tag, group, status, type, provider, service level, workflow and custom field names; firm names; task descriptions; note contents; the error messages Plannr returns) is redacted by pattern. Always, with or without include_contact_details: a sort code with an account number, a sort code or account number introduced as such ("sort code", "acct", "account no."), a GB IBAN ([bank details redacted]), a 13 to 19 digit number that passes the Luhn check ([card number redacted]), a National Insurance number in the QQ 12 34 56 C shape ([NI number redacted]) and a date written after "DOB", "born", "date of birth" or "birthday" ([date of birth redacted]). By default, and not with include_contact_details: email addresses ([email redacted]), phone-number-like sequences ([phone redacted]) and UK postcodes ([postcode redacted]). Custom field values, returned only on request, go through the always-on part.

  • These are heuristics. The phone match covers international numbers written with + or 00 (including +44 (0)7700 …), UK numbers with a bracketed area code, and UK-style 0… numbers of 9 to 11 digits with spaces, dots or hyphens between groups; other digit strings starting with 0 are redacted too, and so is any other 13 to 19 digit string that happens to pass the Luhn check (about one in ten), while UUIDs and timestamps are left alone. A bare date of birth, a bare six- or eight-digit number, a street address, an amount such as "salary £85,000" and a health detail are not caught and are returned as written, as is the rest of a note, since calling the notes tool is itself the request for notes. HTML tags in notes (such as the <span> of an @mention) are stripped.

  • IDs are checked before any call: every ID must be a UUID. Dates must be real calendar dates in YYYY-MM-DD form, a review window must not end before it starts, and a tag, status, provider or plan name may not contain a comma (the API takes these as comma-separated lists).

  • Rate limits: Plannr documents 500 requests per minute per user, an X-Ratelimit-Remaining header on every response and a 429 when the limit is exceeded, with the advice to back off; it does not mention Retry-After. Requests are spaced 150 ms apart (at most 400 a minute). A 429 is retried at most twice, waiting for Retry-After when present (in seconds or as an HTTP-date) and 2 s then 4 s when absent. Each wait is capped at 10 seconds; if Plannr asks for a longer wait the call gives up at once and says how long. Because one tool call can make several requests (the account lookup, then up to 10 pages of a list), every tool call also has a 45 s time budget (PLANNR_TOOL_BUDGET_S), under the MCP SDK's default 60 s request timeout: a retry wait that would end past it is not started and no further page is requested, the call fails at once saying so, and nothing is sent to Plannr after the client has given up. The server does not read X-Ratelimit-Remaining.

  • 502, 503 and 504 are retried the same way for GET only; when all three attempts fail the error says the service may be unavailable, without the gateway's page. POST /api/v1/task and POST /api/v1/note are never retried after a gateway error, because the task or note may already exist; the error says to check list_tasks or list_client_notes first.

  • A 200 whose body is not JSON (a proxy or login page in the way) is reported as an error naming PLANNR_BASE_URL, described by content type and size without quoting it. From error responses only Plannr's documented message and errors fields are passed on, redacted as above, and the access token is scrubbed from every message.

  • Pagination follows the links.next URL Plannr returns. The server never builds a page number itself, re-adds any of its own filters the link leaves out, and refuses to follow a link to another host or another endpoint.

  • A rejected token (401) produces a message that says which variable to fix and where tokens are created; a 403 names the account in use and points to PLANNR_ACCOUNT_UUID and list_logins; a 422 is passed on with Plannr's field errors.

Tests

npm test

The test suite:

  1. Validates every fixture record against the component schemas in Plannr's published OpenAPI spec (LoginResource, AccountResource, CircleResource, TaskStatusResource, TaskResource, IndexTaskResource, CasesResource, Plans_PlanResource, NoteResource) with Ajv and ajv-formats. Because the schemas set no additionalProperties: false and mark almost nothing as required, every fixture is also walked key by key (following $ref, allOf and items) and a key the schema does not declare fails the check. Negative controls check that a schema still rejects wrong types and that the walk reports undeclared keys at any depth. The spec is downloaded from apidocs.plannrcrm.com/source.json to spec.json on the first run.

  2. Starts a local mock of the API that serves those fixtures with the documented filters (every filter the server sends is applied, except filter[is_prospect] and filter[status] on /api/v1/account, since AccountResource declares neither a prospect flag nor a status; their pass-through is still asserted), the include-only relationships of the task index (author and completed_by only when included), per_page and the Links/Meta envelope the guide describes (on /api/v1/task the next link carries only the page number, elsewhere it keeps the query), Bearer auth with the spec's 401 body, a 403 for a missing or unknown X-PLANNR-ACCOUNT-UUID, 404s, 422s in the Plannr_ValidationError shape, an X-Ratelimit-Remaining header, a one-off 429 with Retry-After on GET /api/v1/task-status, and injected failures or replacement records on any endpoint (including a 429 on every other request, so that each page of a list is refused once). The mock's list, detail, created-task and error responses are validated against the response schemas the spec gives for each operation.

  3. Starts the built server and drives it over stdio with the official MCP client: 31 checks covering tools/list and annotations, every read tool, pagination across two pages to the point where links.next is null (and a max_results cut reported as incomplete), a next link without the filters (they are re-added) and requests on one call spaced at least 140 ms apart, every documented filter each tool offers passed through exactly, the reviews-due operator filter, redaction of emails, phone numbers, custom field values, references and policy numbers by default and their return on request, contact details typed into client, household, tag, group, service level and custom field names and descriptions redacted, a fact-find note whose NI number, date of birth, bank details and card number are redacted in both modes and its postcode by default only, planted records served in place of every read (and of the created task and note, and of a 422) with those details and contact details in every free-text field and undeclared date_of_birth, ni_number, bank_accounts, address, income and money fields, none of which comes back, HTML stripped from notes, no money fields in plan and case output, a detail answer and a created task or note wrapped in {"data": …} unwrapped, the POST /api/v1/task and POST /api/v1/note bodies validated against the spec's request schemas (StoreTaskRequest, StoreNoteRequest), a 422 passed on with field errors, an empty 204 on a note handled, writes absent with PLANNR_ALLOW_WRITES unset and set to false, bad UUIDs, dates, reversed review windows and comma-containing names rejected before any request, the 404 message, the 429 retry waiting for Retry-After in the seconds and HTTP-date forms and 2 s then 4 s without it, giving up after three attempts and at once above the cap, a 429 on POST /api/v1/note retried once, a 429 on the first GET /api/v1/logins with two calls at once resolving the account once, the per-call time budget (lowered to 3 s) stopping a list whose pages each get a 429 with a clean error and no later request, a 502 retried for GET, a GET failing three times with 503 reported without the HTML, a 502 on POST /api/v1/task and a 503 on POST /api/v1/note not retried, a non-JSON 200 reported as an error, next links to another host or another endpoint refused, an error message passed on with its email, phone number and the token redacted, the account resolved from /api/v1/logins (the only employee login, preferred_account_uuid, and a refusal listing the choices when ambiguous), list_logins showing the account it acts for with PLANNR_ACCOUNT_UUID unset (or that none was chosen), the 401 message for a wrong token (pasted with a Bearer prefix, not doubled), the 403 message for a wrong account, and that every request used the Bearer token, the required headers, a documented method and path and only query parameters that operation documents (apart from the page number taken from Plannr's next link), with the exact set of 15 endpoints used.

Status

This is a working prototype. It has not yet been run against the live API, because it was built without a Plannr account (no public trial or sandbox was found; personal access tokens come from customers' own accounts). Everything below is taken from the published documentation and should be confirmed on a real account:

  • Pagination. The spec documents only per_page (default 15, max 500) and declares only data in its list responses; the guide describes a Links block with four page links and a Meta block (per page, total, current and last page) in a screenshot. The key names used here (links.first/last/prev/next, meta.current_page/last_page/per_page/total) are the Laravel convention that description matches. Whether links.next keeps the filters is not documented; both cases are handled. Whether per_page=100 is accepted everywhere this server uses it.

  • Get-by-UUID and create responses. The spec types them as the resource itself; if the live API wraps them in {"data": …} they are unwrapped.

  • POST /api/v1/note: the spec documents no success response (only 401 and 422). The mock answers 201 with a NoteResource; the tool also accepts an empty answer.

  • The account header: what status a missing or wrong X-PLANNR-ACCOUNT-UUID gets (the mock answers 403), whether GET /api/v1/account/{uuid} and the notes endpoints need it (the spec does not declare it there; the guide says every endpoint but the logins list does, so it is always sent), and where preferred_account_uuid sits in the GET /api/v1/logins response (the guide names it but it is not in the spec; the server looks at the top level and on each login).

  • Filter encoding and semantics: booleans are sent as true/false; the operator filter filter[next_review_date]=>=2026-10-01,<=2026-10-31 is sent URL-encoded; whether filter[client_uuid] on tasks includes tasks on the client's cases and plans (the mock matches tasks on the client only); whether filter[status] on accounts matches what the UI calls a client status (the AccountResource schema has no status field); which relationships the index routes return without an include (the mock returns only those included).

  • Relationship shapes: the spec types a case's participants and plans as single objects and every *_Summary relationship without property types; the fixtures follow the spec, and the server reads either an object or an array.

  • Money: the spec's money objects (value, total_benefit_amount, valuations) describe example and description as properties of amount, formatted and currency, so no real money value can pass the schema. This version therefore returns no money fields at all (amounts typed into free text are returned as written, see Safety defaults); valuations are the first thing to add once the live shape is known.

  • Dates: task due dates follow the spec's example format 2021-01-01 00:00:00; review dates are ISO 8601 with an offset. The server passes both through as given.

  • The wording of Plannr's 404 and 422 messages for these endpoints (the mock uses the forms the spec documents for other endpoints) and of a 429 body (not documented; the mock uses Laravel's "Too Many Attempts.").

  • Visibility: the spec says task lists are constrained by the user's role; the server returns whatever the token's login may see.

  • How the API reacts to requests at the spaced rate here; the documented limit is 500 a minute per user.

Going to production

This version runs locally over stdio with the user's own personal access token. For advisers to connect from claude.ai or ChatGPT without handling tokens, the next step is a remote server (Streamable HTTP) that uses the OAuth2 authorization code flow Plannr already offers, hosted by Plannr, so each user's own login and permissions apply, and then a listing in the Claude and ChatGPT connector directories. Valuations and other amounts can follow once the money shape is confirmed on a live account, and more write tools (completing tasks, updating review dates) once they can be tested on a test firm.

Licence

MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.

Available Tools

14 tools
get_caseGet caseA
Read-onlyIdempotent

One case by UUID: type, status, review and completion dates, participants by name, linked plans by name and type, custom field names. Uses GET /api/v1/cases/{uuid}.

ParametersJSON Schema
NameRequiredDescriptionDefault
case_uuidYesCase UUID
include_contact_detailsNoInclude participants' email addresses, the linked plans' policy and proposal numbers, and custom field values. Off by default.

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, openWorld, so the safety profile is covered. The description adds the API endpoint path, which is minor, and the fact that participants/plans are returned by name (not ID) – but it does not disclose behavior of include_contact_details or the sensitivity of exposing PII/emails, which is the relevant behavioral trait here.

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?

Single sentence, front-loaded with the operation and its subject fields, followed by the endpoint. No wasted words; slightly dense but efficient.

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 2-parameter read tool with full schema coverage and annotations, this is close to sufficient. The one remaining gap is guidance on when to set include_contact_details true (PII implications), which would help an agent choose 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 100%, so both parameters (case_uuid, include_contact_details) are fully documented in the schema with defaults and the PII flag explained. The description enumerates return fields but adds no parameter syntax or semantics beyond the schema, matching the baseline 3.

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 (retrieve) and resource (a single case by UUID) and enumerates the returned fields, distinguishing it from list_cases and get_client. An agent can route between this and list_cases 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?

The phrase 'One case by UUID' implies single-item lookup versus the sibling list_cases, but no explicit when-to-use or when-not-to-use guidance is stated. Usage is inferable from the name and sibling set, not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_clientGet clientA
Read-onlyIdempotent

One account (usually a client) by UUID: name, type and role, adviser, administrator and paraplanner, owners, groups, tags, households, service level, review, agreement and first-contact dates, and custom field names. Email, phone, custom field values and third-party references only with include_contact_details. Uses GET /api/v1/account/{uuid}.

ParametersJSON Schema
NameRequiredDescriptionDefault
client_uuidYesAccount UUID
include_contact_detailsNoInclude email address, primary email and phone, custom field values and third-party references. Off by default.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint/idempotentHint already declaring the safety profile, the description adds a genuinely useful behavioral fact: email, phone, custom field values and third-party references are withheld unless include_contact_details is set, which signals a privacy-gated response. It does not cover auth requirements, errors, or rate limits, so it stops short of 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?

Front-loaded with the core scope and key, followed by the field inventory and the conditional-contact caveat, then the endpoint. The field list is long but each item earns its place given there is no output schema.

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?

No output schema exists, and the description compensates by enumerating returned fields plus the conditional contact details. It omits error/not-found behavior and any permission prerequisites, but covers everything needed 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 100%, so both parameters are already documented. The description restates the include_contact_details gating and its specific fields, adding only marginal emphasis beyond the schema's own description; 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?

The description clearly identifies the resource (one account/client) and the lookup key (UUID), and enumerates the returned fields, which distinguishes it from search_clients. The retrieval verb is implied by 'One account ... by UUID' rather than stated explicitly, but an agent can still tell what it does.

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?

'By UUID' implies you must already have an identifier, which implicitly separates it from the search_clients sibling, but no alternative is named and no when-not-to-use condition is given. Usage is inferable, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_householdGet householdA
Read-onlyIdempotent

One circle (household) by UUID with its members by name, groups, portal access, engagement rating and last portal login. Uses GET /api/v1/circles/{uuid}.

ParametersJSON Schema
NameRequiredDescriptionDefault
household_uuidYesCircle UUID
include_contact_detailsNoInclude members' email addresses and third-party references. Off by default.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, and open-world, so the safety profile is covered. The description adds value by disclosing the concrete fields returned (groups, portal access, engagement rating, last portal login) and the backing endpoint, though it says nothing about auth requirements or error behavior.

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: the payload contents are front-loaded, followed by the endpoint reference. No filler or redundancy.

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 usefully compensates by enumerating the returned fields, and annotations cover the safety profile. It stops short of covering the optional contact-details toggle's effect or failure modes, but is largely sufficient for calling the tool 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 description coverage is 100% and the UUID pattern plus the include_contact_details default are fully documented in the schema. The description adds no parameter-level meaning beyond that, 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 (get) and resource (one household/circle by UUID) and enumerates exactly what the payload contains: members by name, groups, portal access, engagement rating, and last portal login. This clearly distinguishes it from the sibling list_households and from get_client/get_case.

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 phrase 'One circle (household) by UUID' implies single-record retrieval, so usage is inferable, but there is no explicit when-to-use guidance, no mention of the alternative list_households for bulk access, and no note on when to flip include_contact_details.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_planGet planA
Read-onlyIdempotent

One plan by UUID: type, provider, status, owners, seller, sub-accounts by name, review and valuation dates, custom field names. Policy numbers, linked policy numbers, third-party references and custom field values only with include_contact_details; money amounts never. Uses GET /api/v1/plans/{uuid}.

ParametersJSON Schema
NameRequiredDescriptionDefault
plan_uuidYesPlan UUID
include_contact_detailsNoInclude policy, proposal and linked policy numbers, third-party references, custom field values and owners' email addresses. Off by default.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, but the description adds substantive disclosure the annotations cannot: exact field-redaction behavior. It states that sensitive identifiers are gated behind include_contact_details and that money amounts are never returned, which materially shapes how an agent interprets 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?

Three tight sentences with no filler: what is returned, then the gating rules, then the underlying endpoint. The most decision-relevant content (field list and redaction rules) is front-loaded.

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?

There is no output schema, so the description carries the full burden of describing return content, and it does so field-by-field. With only two parameters, both covered, and the redaction behavior explained, an agent has everything needed to call this correctly.

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 both parameters are already documented, establishing a baseline of 3. The description goes beyond the schema by clarifying the names-vs-values distinction for custom fields (names always, values gated) and by adding the 'money amounts never' rule, which is not present in the schema at all.

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 ('One plan by UUID') and then enumerates the returned fields (type, provider, status, owners, seller, sub-accounts, dates, custom field names). This clearly distinguishes it from the sibling list_plans, which returns many plans, without the agent needing to open a 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?

The description gives a clear conditional rule for the optional flag: policy numbers, linked policy numbers, third-party references and custom field values appear only with include_contact_details. It does not explicitly route the agent away from this tool (e.g., 'to search plans use list_plans'), so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_taskGet taskA
Read-onlyIdempotent

One task by UUID, with its description, status, what it relates to, assignees, workflow and custom field names. Uses GET /api/v1/task/{uuid}.

ParametersJSON Schema
NameRequiredDescriptionDefault
task_uuidYesTask UUID
include_contact_detailsNoInclude email addresses, custom field values, and unredacted emails, phone numbers and postcodes in the name and description. Off by default.

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 useful detail about what is returned and the underlying endpoint, but says nothing about auth requirements, redaction behavior, or rate limits beyond what the schema's include_contact_details note already conveys.

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 primary purpose and with zero filler. 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?

With no output schema, the description usefully enumerates the returned fields, which compensates well for the missing return contract. It is nearly complete for a simple read tool, though it could note redaction behavior more explicitly.

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%, including the UUID pattern and the include_contact_details redaction semantics, so the baseline is 3. The description adds no parameter meaning beyond what the schema documents.

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 ('One task by UUID') and enumerates the returned content (description, status, relations, assignees, workflow, custom field names). This clearly distinguishes it from the sibling list_tasks by singular retrieval keyed on UUID.

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 phrase 'One task by UUID' implies the usage context (fetch a single known task vs. listing), but no explicit when-to-use/when-not or named alternative is given. Usage is only implied, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_casesList casesA
Read-onlyIdempotent

Cases (pieces of advice work such as a pension transfer or a mortgage) with type, status, review date, completion and participants by name, filtered as GET /api/v1/cases documents: by client, household, employee, progress, review or completion date range, status or type. Case values are not returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoSort field; prefix with - for descending. The API's default is name.
statusesNoCase statuses (filter[status])
completedNofilter[completed]
type_uuidsNoCase type UUIDs (filter[type])
in_progressNofilter[in_progress]
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
client_uuidsNoOnly cases for these accounts (filter[account_uuids])
review_afterNoOnly cases with a review date after this (filter[review_at_after])
review_beforeNoOnly cases with a review date before this (filter[review_at_before])
employee_uuidsNoOnly cases for these employees (filter[employee_account_uuids])
completed_afterNofilter[completed_after]
household_uuidsNoOnly cases for these circles (filter[circle_uuids])
completed_beforeNofilter[completed_before]
include_contact_detailsNoInclude participants' email addresses, and stop redacting emails, phone numbers and postcodes typed into case and participant names. Off by default.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readonly, idempotent, non-destructive behavior, so the bar is lower. The description adds genuinely useful context beyond them: 'Case values are not returned,' which warns the agent this listing omits financial data and should not be used to fetch case contents.

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 long but well-structured sentence: resource definition and returned fields are front-loaded, filter dimensions follow, and the 'case values are not returned' caveat closes it. Little waste.

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 14 optional params and no output schema, the description carries the return-value burden and does so by listing returned fields and explicitly excluding case values. Adequate; it could say more about pagination or sort defaults, which the schema already covers.

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 every parameter is already documented in the schema, including the include_contact_details redaction behavior. The description only restates the filter categories at a high level and adds no syntax or format detail beyond the schema.

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?

Names a specific verb and resource and enumerates the returned fields (type, status, review date, completion, participants by name). It is distinguishable from the singular get_case sibling, though it never names an alternative explicitly.

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 filter categories are listed, which implies when to use the tool, but there is no explicit guidance on when to prefer list_cases over get_case or how the filters compose. Usage context 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.

list_client_notesClient notesA
Read-onlyIdempotent

Notes for one client, including notes on their plans, cases, tasks and risks, newest first by default: type (call, note, meeting, email), what the note is about, author, contents. Filter by type, date range, text, or what the note is attached to. Emails, phone numbers and postcodes in the contents are redacted unless include_contact_details; bank details, card and National Insurance numbers and dates of birth always. Uses GET /api/v1/client/{client_uuid}/all-notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoNotes created up to this date (filter[date_to])
fromNoNotes created from this date (filter[date_from])
sortNoSort field; prefix with - for descending-created_at
typeNofilter[type]
containsNoOnly notes whose contents contain this text (filter[contents])
attached_toNoOnly notes on this kind of record (filter[notable_type])
client_uuidYesClient account UUID
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
include_contact_detailsNoInclude email addresses, phone numbers and postcodes in the note contents, author and account. Off by default.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive), and the description goes well beyond them by disclosing the default sort (newest first), the redaction policy, and precisely which fields are conditionally redacted (emails/phones/postcodes behind include_contact_details) versus always redacted (bank, card, NI numbers, DOB). That is exactly the kind of behavioral detail an agent needs before surfacing data.

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?

Front-loaded with what the tool returns, then filters, then the redaction caveat and endpoint. Dense but every clause earns its place; the trailing endpoint reference is mildly redundant but useful for disambiguation.

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?

With no output schema, the description carries the burden and does so: it enumerates returned fields, default ordering, filter dimensions, and privacy behavior. An agent has enough to call and interpret the result correctly.

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 earns a bump by tying include_contact_details to the redaction behavior and clarifying that some data is always redacted regardless of the flag, which the schema does not state. The remaining params are adequately documented in 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?

States a specific resource (notes) scoped to one client and enumerates what the notes cover (plans, cases, tasks, risks) plus the returned fields. An agent can distinguish this from get_client, get_case, or list_tasks 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?

The description implies usage by listing the filter dimensions (type, date range, text, attachment target), which tells the agent when the tool is applicable. However, it names no alternatives and gives no explicit when-not guidance, e.g. whether searching notes across clients is handled elsewhere.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_householdsList householdsA
Read-onlyIdempotent

Circles (households and other groups of client accounts) with their members by name, portal access and engagement rating. Filter by name or member account. Uses GET /api/v1/circles with include=accounts.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoCircle name (filter[name])
sortNoSort field; prefix with - for descending. The API's default is name.
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
member_uuidsNoOnly circles containing these accounts (filter[account_uuids])
include_contact_detailsNoInclude members' email addresses and third-party references. Off by default.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and openWorld, so the safety profile is fully covered by structured data. The description adds the underlying call (GET /api/v1/circles with include=accounts), which hints at the payload shape, but does not add rate-limit, pagination or auth context beyond that.

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 with zero filler: the first establishes what a circle is and what is returned, the second covers filtering and the API backing. Front-loaded and 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?

With no output schema, the description compensates by enumerating the returned attributes (names, portal access, engagement rating) and the include=accounts basis. Aggregate observability (pagination across the 100-per-request batching) is left to the schema's max_results note, so it is nearly but not entirely self-contained.

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 all five parameters are already documented in the schema, and the description only loosely echoes the name/member filters. Baseline 3 applies; it adds no syntax or format detail beyond the structured fields.

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 names a specific verb and resource and even resolves the domain term ('Circles (households and other groups of client accounts)'), plus states what each result contains: member names, portal access and engagement rating. It does not explicitly contrast itself with the closely named sibling get_household, so it stops 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 Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Filter by name or member account' implies when the tool is useful, but there is no explicit when-to-use, when-not-to-use, or named alternative (e.g. 'use get_household for a single circle'). 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.

list_loginsList loginsA
Read-onlyIdempotent

The logins of the user behind the access token: for each, the account it acts as (UUID, name, type such as employee or client, role) and the firm, plus the account this server acts for (PLANNR_ACCOUNT_UUID, or the one chosen from these logins). Use it to find the account UUID for PLANNR_ACCOUNT_UUID. Uses GET /api/v1/logins.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_contact_detailsNoInclude the user's and accounts' email addresses. Off by default.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the safety profile is covered. The description adds what annotations cannot: the data is scoped to the user behind the access token, the shape of each returned login, and the underlying endpoint GET /api/v1/logins. It does not mention pagination or empty-result behavior, which keeps it from 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?

Front-loaded with the resource and its contents, then the usage trigger, then the endpoint. The middle sentence is dense with parenthetical detail but every clause carries information. The trailing endpoint reference is slightly expendable but harmless.

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 takes on the burden of describing the return payload and does so thoroughly (account UUID, name, type, role, firm, PLANNR_ACCOUNT_UUID). Combined with 100% schema coverage on the lone optional param and full annotation coverage, only pagination/volume expectations are left unstated.

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% for the single parameter include_contact_details, which is fully documented in the schema itself. The description never mentions this parameter, so it adds no meaning beyond the structured field; 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?

Names the exact resource (the logins belonging to the token's user) and enumerates what each entry contains: account UUID, name, type (employee/client), role, firm, and the server's acting account. No sibling tool covers logins, so it is unambiguously distinguishable from the list_/get_ pairs for clients, tasks, plans and cases.

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?

Explicitly states a trigger: 'Use it to find the account UUID for PLANNR_ACCOUNT_UUID.' That is a concrete when-to-use. It does not name exclusions or alternatives, but there is no competing login tool among the siblings, so the absence is minor.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_plansList plansA
Read-onlyIdempotent

Plans (pensions, investments, protection, mortgages and other products) with type, provider, status, owners by name, review date and whether they are under advice, filtered as GET /api/v1/plans documents. Policy numbers only with include_contact_details; valuations and other money amounts are not returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoPlan name, partial match (filter[name])
sortNoSort field; prefix with - for descending. The API's default is name.
typesNofilter[type]
providerNoProvider name (partial) or provider UUID (filter[provider])
statusesNofilter[status]
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
client_uuidsNoOnly plans of these clients (filter[account_uuids])
under_adviceNofilter[under_advice]
abstract_typesNofilter[abstract_type]
household_uuidsNoOnly plans of these circles (filter[circle_uuids])
include_contact_detailsNoInclude policy and proposal numbers, owners' email addresses, and unredacted emails, phone numbers and postcodes in plan and owner names. Off by default.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/non-destructive, so the description's real contribution is output-shape disclosure: it tells the agent that policy numbers are only present with include_contact_details and that valuations and money amounts are never returned. That is genuinely useful context beyond the annotations, though it says nothing about pagination or total-count behavior.

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?

Two dense sentences, front-loaded with the resource and its returned fields before the caveats. Every clause carries information, though the first sentence is packed tightly enough that it reads as a list dump rather than prose.

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 11 parameters and no output schema, the description compensates by describing what the response contains and explicitly what it omits (valuations, money amounts). It lacks any note on result caps or the 100-per-request fetch behavior described only in the max_results schema entry, so it is nearly 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 description coverage is 100%, so the schema already documents every one of the 11 parameters, including the include_contact_details semantics. The description reinforces the include_contact_details gating but adds no syntax or format detail beyond the schema, which is the expected baseline.

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 names the resource ('Plans') and enumerates the returned attribute set (type, provider, status, owners, review date, under-advice flag), which makes it clearly distinguishable from the singular sibling get_plan. It never states the verb 'list' explicitly, relying on the name to carry that, but the scope 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 only implied: 'filtered as GET /api/v1/plans documents' signals this is the filtered collection endpoint, and the filter parameters make the intent obvious. There is no explicit statement of when to prefer this over get_plan or search_clients, and no mention of pagination or result-cap behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reviews_dueReviews dueA
Read-onlyIdempotent

Clients whose next review date falls between two dates (today to 30 days ahead by default), soonest first, with their adviser and previous review date. Uses GET /api/v1/account with filter[type]=client, the documented operator form filter[next_review_date]=>=FROM,<=TO and sort=next_review_date.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLast date, inclusive (default 30 days after from)
fromNoFirst date, inclusive (default today, UTC)
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
assigned_adviser_uuidsNoOnly clients of these advisers (filter[assigned_adviser_uuids])
include_contact_detailsNoInclude email addresses and primary phone numbers. Off by default.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior, so the bar is lower. The description adds useful context beyond them: ascending order by next_review_date, the default window, and which fields (adviser, previous review date) come back.

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?

Front-loaded with the core semantics in the first sentence and the window defaults. The second sentence drifts into API endpoint/filter implementation detail, which is mildly wasteful but still informative.

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 usefully names the returned fields (adviser and previous review date) and ordering. Combined with fully documented parameters and safety annotations, an agent has enough to call it correctly; only sibling routing is absent.

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 all five parameters are already documented in the schema. The description only restates the from/to window and API filter syntax, adding no new parameter-level meaning, which is the baseline 3 case.

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: clients whose next review date falls in a date window, with ordering and returned fields. It is clearly distinct from search_clients and get_client by its review-due semantics, though it never names a sibling to steer the agent away.

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 default window (today to 30 days ahead) and ordering imply the intended use case, but there is no explicit when-to-use guidance, no exclusions, and no pointer to alternatives such as search_clients for non-review queries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tasksList tasksA
Read-onlyIdempotent

Tasks on the firm, filtered as GET /api/v1/task documents: by client, assignee, related plan or case, priority, due date range, open only, name or status. Each task has its status, priority, due date, what it relates to, who it is assigned to, its author and who completed it (include=author,completed_by). What a user sees depends on their Plannr role.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoTask name (filter[name])
sortNoSort field; prefix with - for descending. The API's default is created_at.
due_afterNoOnly tasks due after this date (filter[due_after])
open_onlyNotrue: leave out tasks in the Completed and Archived columns (filter[open_tasks])
due_beforeNoOnly tasks due before this date (filter[due_before])
prioritiesNofilter[priority]
client_uuidNoOnly tasks for this client (filter[client_uuid])
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
status_uuidNoOnly tasks in this status (filter[status_uuid]); see list_task_statuses
related_typeNoOnly tasks on a plan or on a case (filter[taskable_type])
related_uuidNoOnly tasks on this plan or case (filter[taskable_uuid])
assigned_to_uuidsNoOnly tasks assigned to these accounts (filter[assigned_to_uuids])
include_contact_detailsNoInclude assignees' and authors' email addresses, and stop redacting emails, phone numbers and postcodes typed into task and client names. Off by default.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, non-destructive), so the description adds context beyond them: role-based result visibility and the fact that relationship data requires include=author,completed_by. It still does not discuss pagination limits or rate behavior beyond what the schema states.

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?

Front-loaded with purpose and filters, but the middle sentence is a long enumeration of returned fields that reads as padding. Efficient overall, slightly dense.

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?

There is no output schema, and the description compensates by listing the fields each task carries, plus the role-based visibility caveat. For a 13-parameter list tool with zero required params, this covers what an agent needs before calling.

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 the schema already documents all 13 parameters including filter mappings and defaults. The description's mention of include=author,completed_by is the only added semantic, 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 and resource ('Tasks on the firm') and enumerates the exact filter axes the tool exposes (client, assignee, related plan/case, priority, due date, open only, name, status). An agent can distinguish it from get_task (single task) and list_task_statuses 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?

Usage is only implied through the enumerated filters; there is no explicit 'use when' or 'use instead of get_task' guidance. The note that visibility depends on the user's Plannr role is context but not a when-to-use rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_task_statusesList task statusesA
Read-onlyIdempotent

The task statuses defined in the firm's settings, in board order, with which ones count as completed, archived or not started. create_task needs one of these UUIDs. Uses GET /api/v1/task-status with sort=position.

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 readOnly/idempotent/non-destructive, so safety is covered. The description adds genuinely new behavior: results come back in board position order, each status carries completion/archive/not-started classification, and it maps to GET /api/v1/task-status with sort=position.

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: the first front-loads what is returned and its ordering/classification, the second front-loads the consumption reason. No filler or restated boilerplate.

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?

There is no output schema, so the description must convey the return shape; it does so partially (ordering, classification flags, UUIDs as keys) but does not enumerate the actual field names an agent would read. Adequate for a simple lookup, with a small gap.

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 there is nothing for the description to disambiguate; the baseline for a no-param tool applies. The description correctly signals no filtering input is required or accepted.

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 names a specific resource (task statuses) and scope (the firm's settings, in board order), plus the semantics of the returned set (which count as completed, archived or not started). It is unmistakably the status-enumeration tool and cannot be confused with the list_tasks/get_task 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?

It gives an explicit downstream trigger: 'create_task needs one of these UUIDs,' which tells the agent exactly when to call it. It stops short of stating when not to call it or naming alternatives, but for a dependency-lookup tool this is strong routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_clientsSearch clientsA
Read-onlyIdempotent

Search the firm's accounts (clients by default) by name, role, prospect flag, status, tags, assigned adviser or household, with the documented filters of GET /api/v1/account. Each result has the UUID, name, type and role, assigned adviser, review dates, tags and households. Email and phone only with include_contact_details.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoPartial match against first name, last name and entity name (filter[name])
sortNoSort field; prefix with - for descending. The API's default is first_name.
tagsNoTag names or tag UUIDs (filter[tags])
typeNoAccount type (filter[type])client
rolesNoAccount roles (filter[role])
statusNoClient status, a partial name or a status UUID (filter[status])
is_prospectNoOnly prospects (true) or only non-prospects (false) (filter[is_prospect])
max_resultsNoMost records to return; lists are fetched 100 per request, up to 10 requests
household_uuidsNoOnly accounts in these households/circles (filter[circle_uuids])
assigned_adviser_uuidsNoOnly clients of these advisers (filter[assigned_adviser_uuids])
include_contact_detailsNoInclude email addresses and primary phone numbers, and stop redacting emails, phone numbers and postcodes typed into names. Off by default.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive, openWorld), and the description adds substantive context beyond them: it lists the returned fields and, importantly, discloses the privacy behavior that email/phone are only returned with include_contact_details and are otherwise redacted. It stops short of describing pagination or rate-limit behavior.

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?

Three sentences, front-loaded with purpose and scope, then return shape, then the privacy caveat. Dense but free of filler; the only slightly opaque element is the indirect reference to 'the documented filters of GET /api/v1/account'.

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 usefully enumerates the result fields and the conditional contact-detail exposure, which is exactly what an agent needs before calling. Remaining gaps (pagination behavior, result volume) are minor and partly covered by max_results in the schema.

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 the schema already documents all 11 parameters including defaults and filter mappings, which sets the baseline at 3. The description reinforces the filter set and the default client scope but adds no syntax or format detail beyond what the schema provides.

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 ('Search the firm's accounts') and immediately pins the default scope ('clients by default'), which cleanly separates it from the singular get_client sibling. It also enumerates the searchable dimensions, so an agent knows what this tool is for 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?

Usage is implied by the enumerated filter dimensions, and 'clients by default' hints that the type parameter broadens scope, but there is no explicit when-to-use or when-not-to-use guidance and no routing to siblings such as get_client for single-record lookups. The pointer to 'the documented filters of GET /api/v1/account' is a documentation reference rather than a usage rule.

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. 14 tool updatesv0.1.0
    • First observedget_case
    • First observedget_client
    • First observedget_household
    • First observedget_plan
    • First observedget_task
    • First observedlist_cases
    • First observedlist_client_notes
    • First observedlist_households
    • First observedlist_logins
    • First observedlist_plans
    • First observedlist_reviews_due
    • First observedlist_task_statuses
    • First observedlist_tasks
    • First observedsearch_clients

TDQS

A3.9/5.0

Scored across 14 tools

Disambiguation4/5

Most tools are clearly distinct list/get pairs for clients, households, tasks, cases, and plans. There is mild overlap between search_clients and list_reviews_due (both surface clients from the same account endpoint), but descriptions describe distinct purposes (general search vs review-date filtering) adequately.

Naming Consistency4/5

Strong underlying list_*/get_* verb_noun pattern across clients, households, tasks, cases, and plans. Minor deviations: search_clients uses a different verb than the otherwise dominant list_* convention, and list_reviews_due/list_client_notes are more descriptive than schematic, but overall it is readable and predictable.

Tool Count5/5

14 tools is well within the sweet spot and each maps to a distinct resource or lookup. No redundant or trivial tools pad the set.

Completeness3/5

Read coverage is thorough (list+get for nearly every entity plus lookups like task statuses and logins), but there are no write/lifecycle operations such as update_task, create_case, or delete_plan. The mention that 'create_task needs one of these UUIDs' implies mutation tools exist elsewhere but are absent here, leaving a notable gap for a CRM-style server.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to access and manage CiviCRM data, including contacts, activities, contributions, events, and memberships, with full custom field support.
    5
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables querying and managing a CRM database through natural language conversations with Claude Desktop.
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to read an Amiqus ID account—clients, onboarding records and steps, check results, templates, case status counts and webhooks—and, when writes are enabled, create records.
    9
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to read practice-management data including organization, clinicians, diaries, availability, bookings, patients, invoices, payments, staff tasks, services, and locations, and optionally create staff tasks, create bookings, and cancel bookings.
    MIT