Dezrez Rezi MCP server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Dezrez Rezi MCP serverWhat happened at 12 High Street this month? Any viewing feedback?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Dezrez Rezi MCP server
An MCP server that lets Claude, ChatGPT and other MCP clients read an estate agency's Dezrez Rezi CRM: properties and their marketing roles, property and group timelines (viewings, offers, notes, appointments), people, groups (households and companies) and offers. It is built from Dezrez's public documentation: the Rezi API Swagger 2.0 document at api.dezrez.com/swagger/docs/v1 and the developer guides in the public DezrezCoreAPI repository (OAuth2 flows, the Rezi-Api-Version header, the agencyId rule).
Once it's connected, someone at the agency can ask things like:
"What happened at 12 High Street this month? Any feedback from the viewings?"
"Which of our sales are under offer, and at what price?"
"Find the Evans family. What are they buying and renting, and how many viewings have they had?"
"List the open offers and who made them."
"Who is in the Patel group, and what did they answer about their mortgage?"
This version is read-only. There are no write tools at all: creating leads, booking viewings and recording offers need scopes and a test agency that were not available when it was built, and a write that cannot be tested against a real account should not be shipped (see Status).
Tools
Tool | What it does | API calls |
| One property: address, status, marketing roles (sale or letting, with status), certificates, special arrangements, keys (holder and check-out status), the number of alarms, custom fields, default picture link. Key and alarm codes are never returned. |
|
| Search property marketing roles by free text, on-market flag, role type and role status, with the property address, prices, summary line and owning group. Pages by |
|
| A property's timeline: viewings, offers, notes, appointments and other events, with the documented filters |
|
| One person: name, gender, group memberships, marketing preferences, custom fields, dates. Contact items, addresses, the note and identity details only on request. |
|
| Search by |
|
| The properties a person is selling, letting, buying or renting, with price, offer and viewing counts. The address is reduced to town, county and country by default (a buyer's or tenant's property is their home); the full address on request. |
|
| One group (household or company): members by name, type, status, applicant qualification answers, preferred companies, custom fields. |
|
| A group's timeline, with the property-event filters plus |
|
| Offers across the agency, paged: value, status, property, applicant and vendor groups, marketed price, response, negotiators. |
|
| One offer in full, including the vendor's response and communication, notes and documents (name, type, link). |
|
Not covered on purpose: everything else in a 1,400-operation API, including documents and their downloads, diary and appointments, valuations, progression, tenancies, accounting, and every write. GET /api/people/{id}/accounts and GET /api/people/{id}/bankReferences (bank details) are never called; the test suite asserts it.
Related MCP server: Qobrix CRM MCP Server
Setup
Requires Node 18 or later.
npm install
npm run buildYou need an OAuth2 client registered with Dezrez. Registration is by request (developer.dezrez.com/api-request or developer.registration@dezrez.com, per HowToRegister.md); Dezrez decides the flow (code, implicit, resource owner, client credentials) and the scopes. Two environments exist: LIVE (https://api.dezrez.com, token endpoint https://auth.dezrez.com/Dezrez.Core.Api/oauth/token/) and UAT (https://core-api-uat.dezrez.com, https://dezrez-core-auth-uat.dezrez.com/Dezrez.Core.Api/oauth/token/).
The server authenticates in one of two ways:
An access token you already have (
DEZREZ_ACCESS_TOKEN), obtained through whichever flow your client is registered for. Access tokens last about two hours according to the overview, so this is for testing and for hosts that refresh the token themselves. A value pasted with itsBearerprefix is accepted. With a user token (code, implicit or resource-owner flow) noagencyIdis needed; ifDEZREZ_AGENCY_IDis set it is sent anyway.Client credentials (
DEZREZ_CLIENT_IDandDEZREZ_CLIENT_SECRET): the server posts to the token endpoint asDezrezCoreAPIOverview.mddocuments (Authorization: Basic base64(clientId:clientSecret), JSON body{"grant_type":"client_credentials","scope":"..."}), caches the token until a minute before itsexpires_in(or halfway through its life, for a token shorter than two minutes; an hour whenexpires_inis absent), shares one token request between tool calls that start at the same time, and fetches a new one if the API answers 401. Dezrez documents that a client token "must" carry theagencyIdparameter on every request, soDEZREZ_AGENCY_IDis required and the server refuses to start without it.
Claude Desktop: add this to claude_desktop_config.json:
{
"mcpServers": {
"dezrez": {
"command": "node",
"args": ["/absolute/path/to/dezrez-mcp/dist/index.js"],
"env": { "DEZREZ_CLIENT_ID": "your-client-id", "DEZREZ_CLIENT_SECRET": "your-client-secret", "DEZREZ_AGENCY_ID": "1234" }
}
}
}Claude Code:
claude mcp add dezrez -e DEZREZ_CLIENT_ID=your-client-id -e DEZREZ_CLIENT_SECRET=your-client-secret -e DEZREZ_AGENCY_ID=1234 -- node /absolute/path/to/dezrez-mcp/dist/index.jsVariable | Required | Meaning |
| one of the two | An OAuth2 access token for the Rezi API, sent as |
| one of the two | The client ID and secret Dezrez issued, used for the client-credentials flow. |
| with client credentials | The agency to act for, sent as the |
| no | The scope asked for in the client-credentials request. Defaults to |
| no | Defaults to |
| no | Defaults to |
| no | Has no effect: this version has no write tools. A set value (whatever it is) is only mentioned in the start-up log. |
Every request carries Rezi-Api-Version: 1.0, which the overview says is mandatory.
Safety defaults
Read-only. Every tool carries the MCP
readOnlyHintannotation and onlyGETs the API; the onePOSTthe server makes is the OAuth2 token request.People are heavily personal in a CRM, so by default a person, group member, attendee, negotiator or applicant is identified by ID and name only. Email addresses, phone numbers, postal addresses, the free-text note on a person, identity, right-to-rent, NRL and housing-benefit details (the spec's
AdditionalInformationDataContract, including its documents), attendees' contact items on events and negotiators' emails and phones are only returned when a tool is called withinclude_contact_details=true. Custom field values whose name looks like contact data (email, phone, address, date of birth, passport, bank and the like) are withheld by default too.In free text (notes, descriptions, special arrangements, summary lines, names, group names, custom field values) email addresses are replaced with
[email redacted]and phone-number-like sequences with[phone redacted]by default. The phone match is a heuristic: it covers international numbers written with+or00(including the+44 (0)7700 …form), UK numbers with a bracketed area code such as(020) 7946 0958, and UK-style0…numbers of 9 to 11 digits with spaces, dots or hyphens between groups. Other digit strings starting with0are redacted too, while numeric IDs, timestamps and hyphenated references are left alone; the raw text is available withinclude_contact_details. The same redaction is applied to Dezrez's error messages before they are passed on.Error messages never quote a response body. From an error response only a JSON message field (
Message,ExceptionMessage,message,error,error_description) is passed on, redacted as above; a non-JSON body (a gateway page, a login page) is described by content type and size only. Every message is also scrubbed of the server's own secrets (the configured access token, each token the token endpoint issued, the client secret and theBasiccredential), so an error body that echoes the request'sAuthorizationheader showsBearer [redacted]orBasic [redacted]. A token endpoint answer withoutaccess_tokenis described by its content type, size and JSON key names, never its content. An unreachable endpoint is named by origin and path, without the query string.Never returned, even on request: bank details (
HasBankAccountsis dropped from person records and the/accountsand/bankReferencesendpoints are never called), property key codes (PropertyKeyDataContract.Code,KeySignedOutDataContract.Code) and alarm codes (PropertyAlarmDataContract, reduced to a count).Property addresses are the agency's stock and are returned by default on properties, searches, events and offers. The one exception is
get_person_roles, where a role ties a named person to a property that, for someone renting or buying, is their home: there the address is reduced to town, county and country by default (the role type is a free string in the spec, so no type is treated as exempt), and the full address comes withinclude_contact_detailsor fromget_propertyby ID. Document links (certificates, offer documents, pictures) are returned as stored, with the spec'sRequiresAuthenticationflag; the files are never fetched.IDs are checked before any call: every ID on the endpoints this server calls is an
int64path parameter (a few elsewhere in the spec are strings) and each get-by-id says "Pass 0 to be returned an empty data contract", so only positive whole numbers are accepted. Type, status and category filters must be single tokens (letters, digits,_,-).from/tomust be ISO 8601 and real calendar dates (2026-02-30 is refused, not rolled over); a date-time is sent as given and a date alone is completed to the start of that day forfrom(T00:00:00Z) and the end of it forto(T23:59:59Z), since the parameters are typeddate-time. Search fields are trimmed and a blank value counts as not given.Dezrez documents no rate limit. Requests are spaced 250 ms apart (about four per second). A 429 is retried at most twice, waiting for
Retry-After(whole or fractional seconds, or an HTTP-date; 2 s then 4 s when the header is absent or unreadable). Each wait is capped at 10 seconds so a tool call stays under the MCP client's default 60-second request timeout: if Dezrez asks for a longer wait the call gives up at once and the message says how long to wait.502, 503 and 504 are retried the same way for
GETonly; when all three attempts fail the error says the service may be unavailable and to try again in a few minutes, without the gateway's HTML. The tokenPOSTis never retried after a gateway error.A 200 whose body is not JSON (a proxy or a login page in the way) is reported as an error naming
DEZREZ_BASE_URL, never as an empty record. A 200 with anullbody is reported as not found where the spec documents it that way: every get-by-id ("null if it does not exist") and the two events endpoints ("null if the property/group does not exist"); onGET /api/Offerthe spec says "null if none exist", so there it is an empty list.A rejected token or rejected client credentials produce messages that say which variables to check; a 403 names the documented read scopes and the agency in use.
Tests
npm testThe test suite:
Validates every fixture record against the definitions in Dezrez's published Swagger 2.0 document (
PropertyDataContract,EventListDataContract,PersonDataContract,BasicPersonRoleDataContract,GroupDataContract,OfferDataContract,PropertyRoleSuggestResultDataContractand everything they embed) withajv-draft-04, the JSON Schema dialect Swagger 2.0 uses, plusajv-formatsfordate-time,int64anddouble. The document is downloaded fromapi.dezrez.com/swagger/docs/v1tospec.jsonon the first run. Because the definitions set noadditionalProperties: false, Ajv alone would accept a fixture field the spec never declares, so every fixture is also walked key by key against its definition (following$refanditems; theDatesandDescriptionsmaps take any key) and an undeclared key fails the check. One deliberate loosening: the spec types custom field values as itsObjectdefinition, which it describes as "an unspecified legacy API value", so that definition is validated as "any value", left opaque by the key walk, and the fixtures use plain strings there. Negative controls check that the schemas still reject wrong types and that the key walk reports undeclared keys at any depth.Starts a local mock of the API and of the OAuth2 token endpoint that serves those fixtures with the documented
pageSize/pageNumberpaging (PagedCollectionDataContract, pages capped at 10 to exercise paging), the documented auth (Bearertoken plusRezi-Api-Version: 1.0;Basic client:secretand a JSONgrant_type/scopebody at the token endpoint;agencyIdrequired with a client token), 401 on a bad token or bad client secret, 404 for unknown IDs, the documented200withnullfor one reserved ID, and a one-off 429 withRetry-AfteronGET /api/Offer. The mock's list, detail and paged-collection responses are validated against the response schemas the spec names for each operation.Starts the built server and drives it over stdio with the official MCP client: 22 checks covering tools/list and annotations (10 read tools, none writable,
DEZREZ_ALLOW_WRITESadding nothing), the client-credentials token request in its documented form with the token cached across calls, one token request shared by two concurrent first calls, andagencyIdon every request, every read tool, paging toTotalCountacross pages 1, 2, 3 and whole-page continuation withnext_pagecovering every event exactly once, the bare-array paging of person roles with the address reduced to the area by default and complete on request, each documented filter passed through exactly (from,to,typeandexcludedTypesas repeated keys,eventCategoryType,branchId,showCancelled,includeOnlyOriginalNotes,activeRolesOnly,propertyId,roleId,includeDrafts, the fivefindbydetailsfields, thedataContract.*search parameters), a date-onlyfrom/tocompleted to a date-time and impossible calendar dates refused, blank search fields treated as absent, redaction of contact details by default and their return on request, key and alarm codes never returned, bank fields never returned and bank endpoints never called, ID validation before any call, the 404 message, a null body reported as not found on get-by-id and on the events endpoints and as an empty list onGET /api/Offer, the 429 retry waiting forRetry-Afterin the seconds, fractional-seconds and HTTP-date forms, giving up after three attempts on a persistent 429 and at once on aRetry-Afterabove the cap, a 502 retried forGET, aGETfailing three times with 503 reported with advice and without the gateway HTML, a non-JSON 200 reported as an error described by content type and size with nothing of the body (its email, phone number and token) quoted, a non-JSON 400 body not passed on at all, error bodies that echo theAuthorizationheader (aBearertoken on a 400 and a 401, theBasiccredential at the token endpoint) scrubbed to[redacted], a token endpoint 200 withoutaccess_tokendescribed by its JSON keys or content type without the token, a revoked token fetched again once, a token response withoutexpires_instill cached, a token withexpires_inof 30 seconds reused across three calls, a 502 from the token endpoint not retried, a 400 whose message contains an email and a phone number passed on redacted, the 401 messages for a wrong access token and wrong client credentials, a token pasted with itsBearerprefix sent once, the 403 message, start-up refused without credentials, withoutDEZREZ_AGENCY_IDin the client flow, or with a username and password insideDEZREZ_BASE_URLorDEZREZ_TOKEN_URL(without repeating them), an unreachable endpoint named without its query string, and that every request used the documented headers and a documented method and path.
The spec marks no property as required on any of these definitions, so schema validation proves the types of fields that are present, not that any field is present; the checks in step 3 assert the fields the tools rely on explicitly.
Status
This is a working prototype. It has not yet been run against the live API, because it was built without a registered client, a token or an agency to test on. Everything below is taken from the published documentation and should be confirmed on a real account (UAT first):
Authentication end to end: that a client registered for the client-credentials flow gets a token with the documented request (the overview's example scope is
impersonate_web_user; the read scopes it lists areproperty_read,property_basic_read,people_read,people_basic_read,event_readanddocument_read, and which of them a reading client is actually granted is decided by Dezrez), thatexpires_inis present in the token response (the server keeps a token for an hour when it is not) and how long the tokens really last, what the API answers whenagencyIdis missing or wrong (the mock answers 400 and 403), and the body of a 401 (undocumented; the server readsMessage,ExceptionMessage,message,erroranderror_descriptionwhen present).Paging: that
pageNumberis 1-based (the server assumes it), thatTotalCountandPageSizeare filled on everyPagedCollectionDataContract, what the maximumpageSizeis (the server sends at most 100, its own cap; the spec says "Can be null" and gives no limit) and what a page past the end returns (the mock answers an emptyCollection).GET /api/people/{id}/rolesanswers a bare array with no total, so the only end condition is a page shorter than the requested size; if the live API capped pages below the requested size, that walk would stop early.The sort order of every list. The spec documents none; the mock serves timelines newest first and the server returns whatever order the API uses.
Filter semantics: whether
from/tocompare againstDateTime,StartDateorCreatedDateand are inclusive; whethertype,excludedTypes,eventCategoryType,roleTypeandroleStatustake the enum system names (the swagger types them as plain strings and lists no values; the documented examples are role typesSalesandLetting, role statusesOfferAcceptedandExchanged, and suggest typesAgencyOnlyandViewableOnly); whether thefindbydetailsmatches are exact or partial; and whetherGET /api/role/suggestneeds aqueryat all.The
EnumDataContractvalues that come back (SystemNameis what the server shows, falling back toName) and the event types that represent viewings, offers and notes in a live agency.Date formats: the spec says
date-time; the fixtures use RFC 3339 with aZandajv-formatsrequires a zone designator, so a live API emitting2026-09-01T10:00:00without one would still be passed through by the server but would fail the suite's schema check. Afrom/todate-time is sent exactly as given; a date alone is completed toT00:00:00Z(from) orT23:59:59Z(to), and whether the live API reads theZas UTC or ignores the zone is unconfirmed.Which fields the live API fills:
Keys,Alarms,SpecialArrangementsandCertificateson a property,AttendingGroups,Notes,KeySignedOutandDateson events,AdditionalInformationandCustomFieldson people,OwnerandPriceson suggest results,Response,VendorCommunicationandDocumentson offers. The team-level security described inBreaking_Change_Log.mdcan reduce a record toId,OwningTeamId,BranchId,NameandTeamAccessType; the server passes such records through as they are.Whether the documented "null if it does not exist" is what the API really answers for an unknown ID (on get-by-id and on the events endpoints), or a 404; both are handled.
The wording of Dezrez's error messages and whether any of them echo request data; the server passes on only JSON message fields, redacts contact details from them and scrubs its own secrets regardless.
How many requests per second the API tolerates; nothing is documented, so the 250 ms spacing is a guess on the polite side.
Going to production
This version runs locally over stdio with the agency's own client credentials or token. For agencies to connect from claude.ai or ChatGPT without handling credentials, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by Dezrez, that uses the code flow Dezrez already offers so each user's own token and branch context apply, and then a listing in the Claude and ChatGPT connector directories. Write tools (leads, viewings, offers) can follow once they can be tested on a UAT agency.
Licence
MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.
Available Tools
10 toolsfind_peopleFind peopleARead-onlyIdempotent
Search people by surname, postcode, email address, telephone and/or mobile number, exactly the fields GET /api/people/findbydetails accepts; at least one is required. Results are returned as get_person returns them: names by default, contact details only with include_contact_details. Note that searching by an email or number and getting a match confirms that detail exists on the account even when it is not returned.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Email address (API parameter `email`) | ||
| mobile | No | Mobile number (API parameter `mobile`) | |
| surname | No | Surname (API parameter `surname`) | |
| postcode | No | Postcode (API parameter `postcode`) | |
| telephone | No | Main telephone number (API parameter `telephone`) | |
| max_results | No | Most people to return; the API has no paging on this endpoint, so the rest are dropped and reported | |
| include_contact_details | No | Include email addresses, phone numbers, postal addresses, notes and identity details. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safe-read profile (readOnly, idempotent, non-destructive), and the description still adds real behavioral content: the at-least-one-input rule, that results mirror get_person's shape, and the non-obvious fact that a match on an email/number confirms that detail exists on the account even when not returned. Missing are auth requirements and any rate-limit expectations for an openWorld endpoint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the searchable fields and the required-input rule, then result behavior, then the caveat. Slightly dense in the final sentence but every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description steps in to describe return contents ('names by default, contact details only with include_contact_details') and the reporting behavior when max_results truncates. Coverage is solid for a 7-parameter read tool, though the practical note about what to do with a confirmed-but-not-returned detail is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns more by supplying the cross-field constraint that at least one search field is required — a rule the schema does not encode (required is empty). It also restates the contact-detail gating behavior of include_contact_details in plain terms.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('search people by surname, postcode, email...') and pins it to the exact API endpoint GET /api/people/findbydetails. Clearly distinguishable from the sibling get_person, which it references as a comparison point for result shape.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a hard precondition ('at least one is required') and implicitly frames this as the lookup-by-detail path versus get_person. It does not, however, explicitly state when to prefer get_person or how to follow up once a match is found, so no exclusions are spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_groupGet groupARead-onlyIdempotent
One group by ID: a household or company (vendors, applicants, landlords, tenants, suppliers) with its members (names by default), type, status, applicant qualification answers, preferred companies and custom fields. Members' emails, phones and addresses only with include_contact_details. Uses GET /api/group/{id}.
| Name | Required | Description | Default |
|---|---|---|---|
| group_id | Yes | Group ID (a positive whole number) | |
| include_contact_details | No | Include members' email addresses, phone numbers and postal addresses, and stop redacting emails and phone numbers from names, notes and descriptions. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-destructive, so safety is covered. The description adds real value beyond that: members' emails, phones and addresses are omitted and redacted by default, and only revealed via include_contact_details, plus a disclosure of default member representation (names only). No permission or rate-limit notes, but the redaction behavior is the key trait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences with the core identification and the returned fields front-loaded, and the conditional flag explained last. Slightly list-heavy but every clause carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by enumerating the returned payload (members, type, status, qualification answers, preferred companies, custom fields) and explaining the default redaction state — exactly what an agent needs to interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are fully documented in the schema and the baseline is 3. The description reinforces that contact details are opt-in and that names are returned by default, but 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.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('One group by ID') and goes further to define what a group is (household or company with roles like vendors/applicants/landlords), so an agent can distinguish it from get_person and get_property. The returned field inventory makes the scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (fetch a single group when you have its ID) and gives a conditional for include_contact_details, but never states when to prefer this over a sibling such as get_group_events or find_people, nor any exclusions or prerequisites. The endpoint reference is useful but not routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_group_eventsGroup eventsBRead-onlyIdempotent
The timeline of one group (household or company): viewings, offers, notes, appointments and other events, with the same filters as get_property_events plus the group-only ones: only active roles, one property, one role, and drafts. Uses GET /api/group/{id}/events.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Only events up to this date/time (API parameter `to`, ISO 8601). A date alone means the end of that day, UTC (2026-09-30 is sent as 2026-09-30T23:59:59Z). | |
| from | No | Only events from this date/time (API parameter `from`, ISO 8601). A date alone means the start of that day, UTC (2026-09-01 is sent as 2026-09-01T00:00:00Z). | |
| page | No | API page number to start from (1-based, as this server assumes; use next_page from a previous call) | |
| types | No | Only these event types, as Rezi system names (API parameter `type`, repeated). The swagger does not list the values. | |
| role_id | No | Only events on this role (API parameter `roleId`) | |
| group_id | Yes | Group ID (a positive whole number) | |
| branch_id | No | Only events in this branch (API parameter `branchId`) | |
| max_results | No | Most records to return in this call; whole API pages only, so fewer may come back with a next_page to continue from | |
| property_id | No | Only events relating to this property (API parameter `propertyId`) | |
| excluded_types | No | Every type except these (API parameter `excludedTypes`, repeated) | |
| include_drafts | No | Include draft events (API parameter `includeDrafts`) | |
| show_cancelled | No | Include cancelled events (API parameter `showCancelled`; the API's default is false) | |
| active_roles_only | No | Only events on the group's active roles (API parameter `activeRolesOnly`) | |
| event_category_type | No | Only this event category (API parameter `eventCategoryType`) | |
| include_contact_details | No | Include attendees' and negotiators' email addresses and phone numbers, and stop redacting emails and phone numbers from notes, names and descriptions. Off by default. | |
| include_only_original_notes | No | Skip note editions and return only original notes (API parameter `includeOnlyOriginalNotes`; the API's default is true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=true, so the safety profile is covered. The description adds the endpoint (GET /api/group/{id}/events) and the filter scope but does not disclose pagination behavior, rate limits, authentication needs, or result shape beyond what the schema already implies. It meets the minimum for an annotated read-only tool but adds only moderate behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence that front-loads the purpose and then lists filters, with no redundant phrasing. It is efficient, though the clause 'with the same filters as get_property_events plus the group-only ones' is somewhat compressed and could be clearer if split.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 16 parameters, no output schema, and rich annotations, the description is adequate but thin. It does not explain pagination behavior (e.g., next_page usage), does not describe the response structure, and does not clarify how the group-only filters (only active roles, one property, one role, drafts) map to the parameter names. The schema covers many of these details, but the description itself leaves gaps for an agent trying to understand the tool's full behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 16 parameters in detail, including date semantics, pagination, and filter meanings. The description only mentions filters abstractly and does not explain any parameter syntax, defaults, or interactions beyond what the schema provides. With full schema coverage, the description contributes nothing new to parameter understanding; a baseline of 3 would be too generous given the lack of added meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a timeline of events for a single group (household or company), listing concrete event types (viewings, offers, notes, appointments). It distinguishes itself from get_property_events by explicitly noting group-only filters. It falls short of a 5 only because the relationship between group_id and the returned data is not elaborated beyond 'timeline of one group.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly references get_property_events as the parallel tool and delineates the group-only filters (active roles, one property, one role, drafts), which helps an agent choose between the two. It does not state when NOT to use this tool or cover other alternatives like get_group, but the sibling routing is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_offerGet offerARead-onlyIdempotent
One offer by ID, in full: value, validity, status, the property, applicant and vendor groups with their primary members (names by default), the marketed price, the vendor's response and communication, notes, documents (name, type and link) and negotiators. Uses GET /api/Offer/{id}.
| Name | Required | Description | Default |
|---|---|---|---|
| offer_id | Yes | Offer ID (a positive whole number) | |
| include_contact_details | No | Include applicants', vendors' and negotiators' email addresses, phone numbers and postal addresses, and stop redacting emails and phone numbers from names and notes. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, idempotent, non-destructive safety profile. The description adds real behavioral context beyond that: member names are returned by default, emails/phones are redacted unless include_contact_details is set, and it names the backing endpoint GET /api/Offer/{id}.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence front-loads the core intent and then enumerates the returned fields, followed by a short endpoint note. Every clause carries information, though the field list is long.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description commendably enumerates the returned fields (value, validity, status, property, groups, price, vendor response, notes, documents, negotiators), which an agent needs to interpret results. Missing only explicit routing guidance against sibling search tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are fully documented in the schema, including the default=false for include_contact_details and its redaction semantics. The description's 'names by default' echoes that without adding format or syntax beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (get) and resource (one offer by ID) and enumerates the payload's contents in detail, making the scope unmistakable. It does not explicitly name siblings like list_offers to contrast, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'One offer by ID' implies retrieval of a single known offer, which is adequate context, but the description never states when to use this versus list_offers or search tools, and gives no prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_personGet personARead-onlyIdempotent
One person by ID: name, gender, group memberships (the households or companies they belong to), marketing preferences, custom fields and dates. Contact items (emails, phones), postal addresses, the free-text note and the identity, right-to-rent and NRL details are only returned with include_contact_details. Bank details are never returned. Uses GET /api/people/{id}.
| Name | Required | Description | Default |
|---|---|---|---|
| person_id | Yes | Person ID (a positive whole number) | |
| include_contact_details | No | Include email addresses, phone numbers, postal addresses, the note, and identity/right-to-rent/NRL details. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive). The description adds valuable conditional behavior: contact items and identity details are only returned with include_contact_details, and bank details are never returned. This is genuine behavioral disclosure beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then field inventory, then the critical include_contact_details caveat. Efficient single paragraph without waste, though the field enumeration is slightly list-like.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers what is returned, the conditional fields, hard exclusions (bank details), and the endpoint. No output schema exists, so return details in the description are necessary and present. Missing pagination/error context but complete for a GET-by-ID tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning about what include_contact_details gates (contact items, note, identity/right-to-rent/NRL), but the schema already lists these. Marginal added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: retrieve one person by ID, and details what is returned. Distinguishes itself from find_people implicitly by being singular-with-ID, but doesn't name the sibling alternative explicitly. Clear but no explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage: you call this when you have a person_id. No explicit 'use X when Y' guidance, no exclusions, and find_people isn't named as the search alternative. Contextual inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_person_rolesPerson's rolesARead-onlyIdempotent
The properties a person is selling, letting, buying or renting: each role with its type, the property ID, headline price, offer and viewing counts and the accepted offer price. A role ties a named person to a property, and for someone renting or buying that property is their home, so by default the address is reduced to town, county and country; the full address (number, street, postcode, coordinates) is returned with include_contact_details, or from get_property by ID. Uses GET /api/people/{id}/roles, which answers a plain list without a total, so paging ends at a short page.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | API page number to start from (1-based, as this server assumes; use next_page from a previous call) | |
| person_id | Yes | Person ID (a positive whole number) | |
| max_results | No | Most records to return in this call; whole API pages only, so fewer may come back with a next_page to continue from | |
| include_contact_details | No | Include the full property address of each role (number, street, building, postcode, coordinates). Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered; the description goes beyond them by disclosing that addresses are reduced to town/county/country by default and that the endpoint returns a plain list without a total, so paging terminates at a short page. That paging quirk is real behavioral context an agent could not derive from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and role contents are front-loaded, followed by the address and paging caveats. The sentences are dense and slightly overpacked, but every clause carries information rather than filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so: it names the role fields, the default vs full address, and the paging termination behavior. An agent has everything needed to call it and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description still adds meaning by explaining the default address-reduction behavior tied to include_contact_details and the pagination semantics (no total; short page ends paging) that contextualize page/max_results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('the properties a person is selling, letting, buying or renting') and enumerates the returned role fields: type, property ID, headline price, offer/viewing counts, accepted offer price. It also distinguishes itself from the get_property sibling for full-address lookups, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear condition for include_contact_details (full number/street/postcode/coordinates) and names get_property by ID as the alternative source for the full address. It does not state when to prefer this tool over get_offer/list_offers for offer data, but the primary selection context is covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_propertyGet propertyARead-onlyIdempotent
One property by ID: address, status, its marketing roles (sale or letting, with status), certificates (EPC and the like), special arrangements, keys (holder and check-out status; key codes are never returned), the number of alarms (codes never returned), custom fields and the default picture link. Note that prices and bedrooms live on events and role searches, not on the property record.
| Name | Required | Description | Default |
|---|---|---|---|
| property_id | Yes | Property ID (a positive whole number) | |
| include_contact_details | No | Include email addresses and phone numbers typed into names, notes and special arrangements, and custom field values that look like contact data. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare this as a safe, read-only, idempotent operation, but the description adds important behavioral detail: key codes and alarm codes are never returned. It also discloses that keys include holder and check-out status, and that custom fields and a default picture link are returned. This goes meaningfully beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and then lists returned fields in a compact, information-dense style. It is longer than a minimal sentence, but with no output schema the field enumeration earns its place and is organized around the property record rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that no output schema exists, the description carries the burden of explaining what comes back, and it does so thoroughly by listing address, status, roles, certificates, arrangements, keys, alarms, custom fields, and picture link. It also clarifies excluded data, so an agent has enough context to invoke it correctly alongside annotations and a fully documented input schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the required property_id and optional include_contact_details are already documented in the input schema. The description confirms retrieval by ID but does not add parameter meaning beyond what the schema provides, which matches the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: retrieving one property by ID. It enumerates the returned property record contents and explicitly distinguishes this tool from event and role-search data by noting that prices and bedrooms live elsewhere. This gives an agent enough information to identify the tool's unique scope among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It establishes context by saying this returns one property by ID and notes where prices and bedrooms actually live, which helps route the agent away from inappropriate use. However, it does not explicitly name sibling tools such as search_properties or get_property_events, nor does it state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_property_eventsProperty eventsARead-onlyIdempotent
The timeline of one property: viewings, offers, notes, appointments and other events, newest to oldest as the API returns them, with dates, status, prices, the groups and people attending (names only by default), notes and negotiators. Filter by date range, event type(s), category, branch, and whether cancelled events are included. Uses GET /api/property/{id}/events.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Only events up to this date/time (API parameter `to`, ISO 8601). A date alone means the end of that day, UTC (2026-09-30 is sent as 2026-09-30T23:59:59Z). | |
| from | No | Only events from this date/time (API parameter `from`, ISO 8601). A date alone means the start of that day, UTC (2026-09-01 is sent as 2026-09-01T00:00:00Z). | |
| page | No | API page number to start from (1-based, as this server assumes; use next_page from a previous call) | |
| types | No | Only these event types, as Rezi system names (API parameter `type`, repeated). The swagger does not list the values. | |
| branch_id | No | Only events in this branch (API parameter `branchId`) | |
| max_results | No | Most records to return in this call; whole API pages only, so fewer may come back with a next_page to continue from | |
| property_id | Yes | Property ID (a positive whole number) | |
| excluded_types | No | Every type except these (API parameter `excludedTypes`, repeated) | |
| show_cancelled | No | Include cancelled events (API parameter `showCancelled`; the API's default is false) | |
| event_category_type | No | Only this event category (API parameter `eventCategoryType`) | |
| include_contact_details | No | Include attendees' and negotiators' email addresses and phone numbers, and stop redacting emails and phone numbers from notes, names and descriptions. Off by default. | |
| include_only_original_notes | No | Skip note editions and return only original notes (API parameter `includeOnlyOriginalNotes`; the API's default is true) |
TDQS
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 real behavioral context beyond that: newest-to-oldest ordering, page-based pagination with whole-page returns and next_page continuation, contact details redacted by default, and the API's showCancelled=false default. It does not mention rate limits or auth, keeping it 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense but front-loaded paragraph: returned content first, then filtering, then the backing endpoint. No filler, though the enumeration of returned fields is long enough to be slightly heavy for a one-paragraph description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter read tool with no output schema, the description usefully describes what comes back (fields, ordering) and how pagination works, complementing the annotations. It could say more about redaction/auth prerequisites, but nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 12 parameters in detail (including defaults and the 'names only / redaction' semantics). The description's 'filter by date range, event type(s), category, branch, and cancelled' summary adds marginal value but no syntax or meaning beyond the schema, warranting the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (get/retrieve the timeline) and resource (events for one property), enumerating the event kinds (viewings, offers, notes, appointments). An agent can distinguish it from get_group_events and list_offers without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when this tool is relevant (fetching one property's event history) and lists the filter conditions, but it never names an alternative sibling or states when NOT to use it (e.g., vs get_group_events or get_property). Usage is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_offersList offersARead-onlyIdempotent
Offers on the agency's properties, in the order the API returns them, each with its value, status, the property and address, the applicant and vendor groups (names by default), the marketed price, the vendor's response and the negotiators. The endpoint has no filters; page through with page/max_results. Uses GET /api/Offer.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | API page number to start from (1-based, as this server assumes; use next_page from a previous call) | |
| max_results | No | Most records to return in this call; whole API pages only, so fewer may come back with a next_page to continue from | |
| include_contact_details | No | Include applicants', vendors' and negotiators' email addresses, phone numbers and postal addresses, and stop redacting emails and phone numbers from names and notes. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, open-world, non-destructive, so the safety profile is covered. The description adds real value beyond that: the endpoint returns records unordered ('in the order the API returns them'), supports no filtering, and redacts contact details by default. It does not discuss rate limits or response size limits, but the disclosed behavior is substantive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler; the resource description, the no-filter/pagination constraint, and the API path are each stated once. The first sentence is a long field enumeration, but every listed field 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.
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-shape burden and does so by enumerating fields and noting default redaction. Pagination, absence of filters, and the underlying endpoint are all covered, so an agent has 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.
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 meaning: pagination is the only way to traverse since there are no filters, and 'names by default' signals that contact data is withheld unless include_contact_details is enabled, reinforcing that parameter's purpose beyond its schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a precise noun phrase ('Offers on the agency's properties') and enumerates the returned fields, so the agent knows exactly what this resource is. The explicit 'no filters' note distinguishes it from filtering siblings like search_properties, and the contrast with the single-record get_offer is implicit in the plural/list framing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States plainly that 'The endpoint has no filters' and instructs to 'page through with page/max_results', which tells the agent when this is the right call versus a filtered search. It stops short of naming an alternative tool or an explicit 'use X instead when filtering' rule, so it is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_propertiesSearch propertiesARead-onlyIdempotent
Search the agency's property marketing roles (a property being sold or let) by free text such as an address fragment or postcode, optionally only those on the market, of one role type (documented examples: Sales, Letting) or in one role status (documented examples: OfferAccepted, Exchanged). Each result carries the property ID, address, the role with its status, prices, a summary line and the owning group. Uses GET /api/role/suggest; the role type and status values are system names the swagger does not enumerate.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | API page number to start from (1-based, as this server assumes; use next_page from a previous call) | |
| query | No | Free-text search (API parameter `dataContract.query`) | |
| role_type | No | Role type system name, e.g. Sales or Letting (`dataContract.roleType`) | |
| max_results | No | Most records to return in this call; whole API pages only, so fewer may come back with a next_page to continue from | |
| role_status | No | Role status system name, e.g. OfferAccepted (`dataContract.roleStatus`) | |
| is_on_market | No | Only roles currently on the market (`dataContract.isOnMarket`) | |
| suggest_type | No | The two values the spec documents for `dataContract.suggestType` | |
| include_contact_details | No | Include the owning group's members' email addresses, phone numbers and postal addresses, and stop redacting emails and phone numbers from names and summary text. Off by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a read-only, idempotent, non-destructive operation. The description adds useful behavioral context beyond annotations: the backing endpoint, the result shape, the redaction behavior of include_contact_details, and the caveat that role type/status values are system names not enumerated in swagger.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded: it begins with the core search behavior, then describes results and implementation caveats. Every sentence adds useful information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given eight optional parameters, no output schema, and rich annotations, the description is complete enough. It explains the searchable filters, the return fields, the pagination-related schema context, and the important enumeration caveat for role type/status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds meaningful parameter semantics by giving examples for role_type and role_status and warning that their system names are not enumerated by swagger, which goes beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: searching the agency's property marketing roles by free text, with optional filters. The role-oriented scope clearly separates it from property-entity siblings like get_property, but it does not explicitly name or contrast those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear usage context, such as searching by address fragment or postcode and optionally filtering by on-market status, role type, or role status. However, it does not explicitly state when to use this instead of get_property or other sibling tools, leaving routing guidance implied.
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.
10 tool updates
v0.1.0- First observed
find_people - First observed
get_group - First observed
get_group_events - First observed
get_offer - First observed
get_person - First observed
get_person_roles - First observed
get_property - First observed
get_property_events - First observed
list_offers - First observed
search_properties
TDQS
Scored across 10 tools
Each tool targets a distinct entity and action: get-by-ID vs search/list for properties, people, groups, and offers, plus separate property/group event timelines. The apparent overlap between get_property_events and get_group_events is explicitly scoped to different parent entities, so an agent can select correctly.
All names use snake_case with a consistent verb_noun pattern: get_*, search_*, find_*, list_*. Plural/singular forms follow the operation type predictably, and there is no mixed casing or vague verb usage.
10 tools is well within the ideal range and maps cleanly to the core read entities: properties, people, groups, offers, and events. Each tool covers a distinct resource or operation without redundancy.
The read-only query surface covers the main entities and their timelines, but there is no direct way to search or list groups (only get_group by ID), and no write operations if mutation is in scope. These are workable gaps via related tools, but not full lifecycle coverage.
Maintenance
Related MCP Connectors
Read-only MCP for Oria CRM: properties, contacts, deals, viewings, agents, auctions.
- HAVNOAuthapp.havnre
Read-only AI access to HAVN properties, leads, tasks, files, media, and analytics.
The HubSpot MCP Server acts as a bridge that enables AI assistants and Large Language Models to securely interact with HubSpot CRM data through natural conversation, without requiring users to understand complex API structures. It provides read-only access to standard CRM objects (contacts, companies, deals, tickets, products, invoices, and more) and their associations, secured via OAuth 2.0, allowing AI agents to perform tasks like summarizing deals, fetching company updates, and looking up record changes.
Read-only MCP server: let AI agents read your ORANO saved-video library, tasks, and memory.
Related MCP Servers
- AlicenseAqualityDmaintenanceA read-only MCP server that connects AI assistants to the OfficeRnD coworking and flex-space management platform. It enables natural language queries for community members, space bookings, billing records, and office resources.51MIT
- AlicenseAqualityAmaintenanceA read-only MCP server providing 56 tools to query Qobrix real-estate CRM data, covering listings, leads, viewings, offers, contracts, analytics, and more, with RESO Data Dictionary alignment and caching support.643Apache 2.0
- AlicenseNot gradedqualityDmaintenancePublic read-only MCP server for FoxTrove Voice, enabling LLMs to query call logs, customer records, assistant stats, and analytics via secure OAuth.MIT
- AlicenseBqualityDmaintenanceEnables querying ChurchSuite bookings, resources, ministries, and serving patterns via MCP tools, providing read-only access to church management data.16MIT