Qobrix CRM MCP Server
The Qobrix CRM MCP Server provides a read-only Model Context Protocol (MCP) layer connecting AI assistants (Claude.ai, Cursor, Dust.tt, etc.) to a Qobrix real-estate CRM via 64 tools for natural language interaction with listings, leads, deals, and activity data.
Browse CRM Entities: List, get, and search properties, contacts, agents, opportunities/leads, viewings, tasks, media, projects, offers, contracts, calls, meetings, and email messages. Includes property-coordinates retrieval and lead-property matching.
Advanced Relevance Search: Two-tier search using hard
searchfilters and softboost[]criteria, combined with DSL help for precise, ranked results across all resources.Real-Estate Workflows: Six canonical RESO-aligned workflows: listing lifecycle, lead-contact lifecycle, sales pipeline, showing/viewing, transaction/offer, and activity/follow-up.
Analytics & Reporting:
Quick counts, top field values, top records, and aggregate metrics (sum/avg/min/max) with grouping.
Flexible
qobrix_dealsshortcut for closed sales, rentals, listings, and pipeline reservations.Time-series analysis with YoY comparison by day/week/month/quarter/year.
Sales funnel with 6-stage conversion percentages, win/loss analytics, stale lead detection, agent scorecards, days-on-market analytics, and repeat customer cohort analysis.
Audit & Change History: Per-record change logs, tenant-wide audit searches, chronological field-level edit history, and top field changers leaderboard.
Schema Discovery: Dynamically retrieve field schemas, enum options, and full search DSL grammar to compose precise queries.
Cache Management: View cache statistics (hits, misses, Redis status) and clear the cache for fresh data.
Session & Identity: Interactive sign-in/out (Mode C OAuth) and current user profile retrieval.
Output Controls: Compact payloads with field selection and output caps to manage context window usage.
Provides optional Redis-backed response caching for improved performance, along with cache management tools (stats and clear).
Click on "Install 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., "@Qobrix CRM MCP Serversearch for active listings under $500k in zip 10001"
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.
Table of contents
Installation Guide — Sharp Matrix intranet, pm2, Apache, Claude.ai + Dust.tt connectors
User Guide — Mode A → Mode B → Mode C → Mode D (Claude.ai + Dust.tt) step-by-step
What It Does
An AI assistant connected to this server can browse properties, qualify leads, track showings, review offers and contracts, audit follow-up activity, and discover CRM field schemas — all through natural language. Every tool description teaches the LLM which canonical real-estate workflow it belongs to, which RESO resource it maps to, and which tools to chain next.
Who it is for
Brokerages & developers using Qobrix who want Claude.ai, Dust.tt, ChatGPT, or Cursor to answer questions grounded in live CRM data (not copy-pasted exports).
Engineers wiring MCP into internal tools: stdio transport, typed Zod inputs, and no write surface — safe to experiment with prompts and agents.
Data & operations teams running dashboards: use
qobrix_count/qobrix_top_valuesfor YoY-style metrics without custom scripts, and response caching to cut API load on repeat queries.Enterprise IT ready for per-agent identity: run Modes A/B from this package, then pair Mode C with SharpSir’s Enterprise OAuth (SSO) product when every user must authenticate as themselves — see Enterprise OAuth.
Canonical RE Workflows
The server is organized around six RESO-aligned business processes. The LLM receives these as built-in instructions so it can navigate the CRM without prior training.
# | Workflow | RESO Mapping | Key Tools |
1 | Listing Lifecycle |
|
|
2 | Lead-Contact Lifecycle |
|
|
3 | Sales Pipeline | 8-stage buyer journey |
|
4 | Showing / Viewing |
|
|
5 | Transaction / Offer |
|
|
6 | Activity / Follow-up | Engagement tracking |
|
Status Mappings
Qobrix Property Status | RESO StandardStatus |
| Active |
| Pending / Under Contract |
| Closed |
| Withdrawn / Canceled |
Qobrix Opportunity Status | RESO Lead Funnel |
| MQL / Raw Lead |
| SQL / Active |
| Closed Won |
| Lost |
Tools at a Glance
64 tools — CRM entities, schema discovery, analytics (qobrix_count, qobrix_top_values, qobrix_top_records, qobrix_aggregate), a flexible deals shortcut (qobrix_deals), reporting (qobrix_timeseries, qobrix_funnel, qobrix_rep_scorecard, qobrix_stale_leads, qobrix_win_loss, qobrix_days_on_market), customer intelligence (qobrix_cohort), audit / change history (qobrix_get_changes, qobrix_search_changes, qobrix_field_change_history, qobrix_top_field_changers), cache helpers (qobrix_cache_stats, qobrix_cache_clear), and session & identity (qobrix_sign_in, qobrix_sign_out, qobrix_whoami):
Entity Group | Tools | Capabilities |
Properties | 5 | List, Get, Search, Coordinates (map), Properties-by-Lead |
Contacts | 3 | List, Get, Search |
Agents | 3 | List, Get, Search |
Opportunities / Leads | 5 | List, Get, Search, Leads-by-Property, Lead-Properties |
Property Viewings | 3 | List, Get, Search |
Tasks | 3 | List, Get, Search |
Media | 2 | List (with entity filter), Get (with size variants) |
Projects | 4 | List, Get, Search, Coordinates |
Offers | 3 | List, Get, Search |
Contracts | 3 | List, Get, Search |
Calls | 2 | List, Get |
Meetings | 2 | List, Get |
Email Messages | 2 | List, Get |
Schema / Meta | 3 | Get Schema (field discovery), Get Field Options (enum values), Search DSL Help (full grammar + cheatsheets) |
Analytics | 4 | Counts, top-N field values, full-scan top-N records by numeric/date, and sum/avg/min/max/count aggregates (with single- or multi-dim grouping). Prefer list/search |
Deals | 1 | Flexible domain shortcut over the Contracts table (sales, rentals, listings, pipeline) with kind / contract_types[] / contract_statuses[] / date_field / min_price / party filters / summary block |
Reporting | 6 | Time-series with YoY ( |
Customers | 1 | Repeat-buyer / seller / lead cohorts ( |
Audit | 4 | Per-record change log ( |
Cache | 2 | Stats and prefix or full invalidation for fresher reads |
Session & identity | 3 | Interactive sign-in ( |
Every tool description includes its canonical workflow role, RESO equivalent, verified include[] options, FK resolution guidance, and search expression examples.
Analytics & Deals usage examples
Server-side sort (OpenAPI sort[]) works for most fields — e.g.
sort: "-list_selling_price_amount" on properties. Use qobrix_top_records /
qobrix_aggregate when you need a full-dataset scan, or when a nullable
field (e.g. opportunities.budget) returns no rows under server sort.
"Closed deals" don't live as a property flag — they're rows in the Contracts
table. The analytics/deals tools remove the need for client-side scripting:
// 1) Top 5 closed 2026 sales, sorted by final_selling_price_amount,
// with property + agent + lawyers resolved to readable names.
{
"tool": "qobrix_top_records",
"args": {
"resource": "contracts",
"sort_by": "final_selling_price_amount",
"search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
"top": 5
}
}
// 2) 2026 sales volume, plus an agent leaderboard in one extra call.
{
"tool": "qobrix_aggregate",
"args": {
"resource": "contracts",
"field": "final_selling_price_amount",
"op": "sum",
"search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
"group_by": "commission_to_2",
"top": 10
}
}
// 3) Flexible "deals" shortcut — same answer as (1) with one default-laden call,
// plus a full-set summary block (by_status, by_type, totals, median).
{ "tool": "qobrix_deals", "args": { "year": 2026, "top": 5 } }
// 4) Best 2026 rental contracts by final rental price.
{ "tool": "qobrix_deals", "args": { "kind": "rental", "year": 2026, "top": 5 } }
// 5) Under-contract reservations + closed sales together (pipeline + actuals).
{
"tool": "qobrix_deals",
"args": { "contract_statuses": ["reserved", "agreed"], "year": 2026 }
}
// 6) "My deals this year": uses the CURRENT_USER special var.
{
"tool": "qobrix_deals",
"args": { "assigned_to": "CURRENT_USER", "year": 2026 }
}
// 7) Monthly 2026 closed-sale volume with prior-year YoY %.
{
"tool": "qobrix_timeseries",
"args": {
"resource": "contracts",
"bucket": "month",
"metric": "sum",
"field": "final_selling_price_amount",
"year": 2026,
"search": "contract_type == \"cos\" and contract_status == \"agreed\"",
"compare_to_prior": true
}
}
// 8) Full 2026 sales funnel (Leads → Qualified → Viewing → Offer → Reserved → Closed).
{ "tool": "qobrix_funnel", "args": { "year": 2026 } }
// 9) 2026 agent leaderboard by volume (omit `user` for leaderboard mode).
{ "tool": "qobrix_rep_scorecard", "args": { "year": 2026, "sort_by": "volume", "top": 10 } }
// 10) Silent leads — open opportunities with no activity in 30 days.
{ "tool": "qobrix_stale_leads", "args": { "since_days": 30 } }
// 11) Multi-dim pivot: 2026 closed-sale volume by city × property_type.
{
"tool": "qobrix_aggregate",
"args": {
"resource": "contracts",
"field": "final_selling_price_amount",
"op": "sum",
"search": "contract_type == \"cos\" and contract_status == \"agreed\" and date_of_contract >= \"2026-01-01\" and date_of_contract < \"2027-01-01\"",
"group_by": ["property_id", "contract_type"],
"top": 10
}
}
// 12) Repeat buyers — contacts behind 2+ closed sales in 2026.
{ "tool": "qobrix_cohort", "args": { "kind": "buyers", "year": 2026, "min_count": 2 } }
// 13) Win-rate by lead source in 2026, with top loss reasons resolved.
{
"tool": "qobrix_win_loss",
"args": { "year": 2026, "group_by": "source", "include_top_losses": true }
}
// 14) 2026 days-on-market by property type, with longest/shortest outliers.
{
"tool": "qobrix_days_on_market",
"args": { "kind": "sold", "year": 2026, "group_by": "property_type", "include_outliers": true }
}Quick Start
git clone https://github.com/gca-ltd/qobrix-crm-mcp.git
cd qobrix-crm-mcp
npm install
npm run buildConfiguration
Create a .env file in the project root:
QOBRIX_API_URL=https://yourcrm.qobrix.com
QOBRIX_API_USER=your-api-user-uuid
QOBRIX_API_KEY=your-api-key
QOBRIX_LOCALE=en-US # optionalVariable | Required | Description |
| Yes (Mode A) | Qobrix instance base URL |
| Yes (Mode A) |
|
| Yes (Mode A) |
|
| No |
|
Auth modes
Clone this package, run Mode A or B, and put live Qobrix data in front of Claude, Cursor, or any MCP client — Apache 2.0.
Mode | In this package? | When | How credentials arrive |
A (default) | Yes |
| Shared |
B | Yes |
| Per-request |
C | Needs companion AS |
| Self-service OAuth: MCP returns a |
D (opt-in) | Needs companion AS |
| Remote MCP OAuth (RFC 9728 PRM + Bearer on |
Modes A and B are fully supported out of this package. Modes C and D require SharpSir’s separate Enterprise OAuth / SSO product — not distributed as part of this repo. Mode D does not change Modes A/B/C — select it when you want remote hosts such as Claude.ai or Dust.tt to drive OAuth themselves.
Enterprise OAuth
Need the agent to work as a signed-in Qobrix user — not a shared API key? Mode C is designed for that. It requires SharpSir’s Enterprise OAuth solution: a hosted Authorization Server bundle (login + 2FA + consent, per-user API-key minting, encrypted credential vault, audience-bound tokens) that pairs exclusively with this MCP server.
How Mode C works (MCP self-auth — northbound clients unchanged):
A tool runs with no session → the MCP returns an authorization URL:
URL-mode elicitation (
JSON-RPC -32042) when the client supportselicitation.url(Claude, Cursor, etc.)A Markdown
[Sign In to Qobrix](/connect?e=…)link in the tool result for clients without elicitation (e.g. ragchat / LangChain) — the LLM must relay it verbatim (unique / single-use; never reuse an older link)
The user opens
/connecton this server (anti-phishing indirection) → signed cookie + redirect to the Enterprise OAuth login pageAfter login + 2FA + consent, the AS redirects to
/oauth/callback; this MCP exchanges the code (PKCE), introspects for Qobrix credentials, and stores them in an encrypted session vaultThe next tool call runs authenticated. On Qobrix
401/403, the vault is cleared and a fresh/connectURL is returnedAgents can also call
qobrix_sign_in,qobrix_whoami, andqobrix_sign_out(full revoke via AS/disconnect+ Qobrix API-key delete)
Not available as a public download and not something you can clone from GitHub.
Delivered and configured by our team upon request as an enterprise solution bundle.
No third-party OAuth servers — Mode C is hard-wired to this Enterprise OAuth solution only.
Security: Mode C uses per-user encrypted session vaults (keyed by chat identity headers) and leaves
/mcpwithout a client bearer. BindQOBRIX_MCP_HOST=127.0.0.1and setQOBRIX_MCP_IDENTITY_SECRET(shared only with the trusted MCP host like ragchat) so identity headers cannot be forged. Keep vault encryption onQOBRIX_MCP_STATE_SECRET(MCP-only). If you reverse-proxy for browsers, publish only/connectand/oauth/callback— deny public/mcpand/health. Local agents (ragchat) callhttp://127.0.0.1:<port>/mcp. WhenALLOWED_HOSTSlists only the public hostname, loopback Host values (127.0.0.1/localhost/::1) are auto-added if the server binds to loopback. Connect cookiePathfollowsPUBLIC_URLpathname; Expresstrust proxyis2behind Cloudflare→Apache. Deliver/connectlinks only to the individual user — never into a shared/group thread.
Ready to upgrade? Contact SharpSir Group · dev@sharpsir.group and ask for the Qobrix CRM MCP Enterprise OAuth bundle.
Once delivered, you point this server at the issuer you receive:
export QOBRIX_MCP_TRANSPORT=http
export QOBRIX_MCP_AUTH=oauth
export QOBRIX_MCP_HOST=127.0.0.1
export QOBRIX_MCP_PORT=3502
export QOBRIX_MCP_PUBLIC_URL=http://127.0.0.1:3502
export QOBRIX_MCP_RESOURCE_URL=http://127.0.0.1:3502/mcp
export QOBRIX_OAUTH_ISSUER=<issuer-from-enterprise-bundle>
export QOBRIX_OAUTH_INTROSPECTION_SECRET=<shared-secret-from-bundle>
export QOBRIX_MCP_STATE_SECRET=<16+-char-secret>
export QOBRIX_MCP_IDENTITY_SECRET=<16+-char-secret-shared-with-ragchat>
export QOBRIX_MCP_DATA_DIR=./data/mcp-oauth
export QOBRIX_MCP_ALLOWED_HOSTS=qobrix-mcp.example.com # loopback Hosts auto-added when HOST is 127.0.0.1
npm startMode C endpoints (after the Enterprise OAuth solution is paired):
GET /connect?e=…— start authorization (sets cookie, 302 to AS)GET /oauth/callback— PKCE code exchange + per-user session vault writeGET /health— includesconnectedandsession_vaultscountUnauthenticated
/mcpis intentional for northbound clients: tools surface the connect URL when needed — keep/mcpon localhost in production
See docs/USER_GUIDE.md for Mode A → B → C step-by-step, reverse-proxy lockdown, and Host allowlist details.
For ragchat / Mode C, register the remote MCP URL (…/mcp) as a normal Streamable HTTP server (no client-side OAuth provider required); the MCP handles auth via /connect. Keep /mcp on localhost in that topology.
Mode D — Claude.ai and Dust.tt remote MCP (shared resource)
Use a separate MCP process (or host) with QOBRIX_MCP_AUTH=oauth-claude. Remote hosts drive OAuth themselves against the same HTTPS /mcp URL:
Host | How to connect | Auth |
Claude.ai / Claude Desktop | Settings → Connectors → Add custom connector | Automatic DCR + PKCE (redirect |
Spaces → Tools → Add MCP Server | Prefer Automatic; Static OAuth fallback — see INSTALL — Connect Dust |
User pastes
https://intranet.sharpsir.group/qobrix-crm/mcpinto Claude or DustHost hits
/mcp→ receives401+WWW-Authenticate: Bearer resource_metadata=…Host fetches
/.well-known/oauth-protected-resource→ discoversQOBRIX_OAUTH_ISSUERHost completes OAuth (DCR or Static) + PKCE against the Enterprise OAuth AS
Subsequent
/mcpcalls sendAuthorization: Bearer <access_token>; this server introspects and runs tools as that Qobrix user
Claude and Dust share one Mode D stack (same MCP resource + same Authorization Server). Each host registers its own OAuth client; each member logs into Qobrix as themselves.
export QOBRIX_MCP_TRANSPORT=http
export QOBRIX_MCP_AUTH=oauth-claude
export QOBRIX_MCP_HOST=127.0.0.1
export QOBRIX_MCP_PORT=3502
export QOBRIX_MCP_ALLOWED_HOSTS=intranet.sharpsir.group
export QOBRIX_MCP_PUBLIC_URL=https://intranet.sharpsir.group/qobrix-crm
export QOBRIX_MCP_RESOURCE_URL=https://intranet.sharpsir.group/qobrix-crm/mcp
export QOBRIX_OAUTH_ISSUER=https://intranet.sharpsir.group/qobrix-crm/mcp-oauth
export QOBRIX_OAUTH_INTROSPECTION_SECRET=<shared-secret-from-bundle>
npm startOn the AS, when using a redirect allowlist, keep Claude’s callback and append exact Dust finalize URLs (never replace Claude’s entry):
export QOBRIX_OAUTH_REDIRECT_ALLOWLIST=https://claude.ai/api/mcp/auth_callback,http://127.0.0.1,http://localhost,cursor://,https://eu.dust.tt/oauth/mcp/finalize,https://eu.dust.tt/oauth/mcp_static/finalize,https://dust.tt/oauth/mcp/finalize,https://dust.tt/oauth/mcp_static/finalize,https://app.dust.tt/oauth/mcp/finalize,https://app.dust.tt/oauth/mcp_static/finalizePublish HTTPS /mcp + PRM (and the AS) to the public internet; allowlist Anthropic egress 160.79.104.0/21 if WAF’d, and allow Dust egress in addition — do not remove Claude’s allowlist. Mode C’s loopback/deny public /mcp guidance stays valid for ragchat deployments — do not flip that topology for Mode C processes.
Full steps: INSTALL — Connect Claude · INSTALL — Connect Dust · Dust: Adding an MCP Server.
Caching
All MCP tools are read-only GETs, so a response cache cannot corrupt CRM state. The server wraps one chokepoint (QobrixClient.request()) with a read-through cache, so every list/get/search/schema call — including each page of a relevance max_scan — is cached. Boost scoring is post-fetch and does not change the cache key, so re-ranking with different boost[] reuses the same candidate pages.
Design — cache-aside with single-flight coalescing:
Tier 1 — in-memory LRU (always on, zero deps): per-process, TTL'd, size-capped.
Tier 2 — Redis (optional, lazy-loaded via dynamic
import()): setQOBRIX_REDIS_URLto enable; the server falls back to memory-only on any Redis error.Single-flight: when the LLM fires parallel tool calls that hit the same cold cache key (common with
qobrix_top_values), all in-process callers share one upstream fetch.Errors are never cached — a transient 5xx will not get stuck.
TTL only, no stale-while-revalidate in v1.
Environment variables:
Variable | Default | Description |
|
| Set to |
|
| TTL in seconds; CRM edits visible within this window |
|
| LRU cap for the in-memory tier |
|
|
|
|
| Namespace when sharing a Redis instance |
Cache tools (exposed to the LLM):
Tool | Use |
| Hits/misses/size/in-flight/Redis status — verify the cache is paying off |
| Invalidate all keys or by |
Recommended Redis server config (for a dedicated cache-only Redis, per Redis docs):
maxmemory 256mb
maxmemory-policy allkeys-lru
maxmemory-samples 10TTL guidance — Redis docs recommend short TTLs for frequently-changing data (60–120s) and longer for stable data (hours). 300s is a conservative default for a CRM that mixes lead pipeline (changes minutely) with property listings (changes hourly). Use qobrix_cache_clear when you need an instant refresh.
Trade-off / known limit: Single-flight coalescing is in-process only. Multi-instance deployments behind one shared Redis can still see modest stampede on cold keys; a distributed SETNX lock is future work and not needed for single-user MCP clients.
Best-practices alignment:
Best practice | Where honored |
Cache-aside / read-through (Redis docs, MCP caching guides) |
|
Canonical, versioned cache key |
|
Conservative TTL |
|
Errors not cached | Wrap stores only on resolved upstream success |
Single-flight stampede prevention | In-process |
| Documented above for self-hosters |
Observability + manual invalidation |
|
Official Node.js Redis client |
|
Cursor IDE setup
This server uses stdio MCP (a local node process). Cursor discovers servers from project or user mcp.json: .cursor/mcp.json inside the folder you opened, or ~/.cursor/mcp.json for all workspaces.
1. Prerequisites
Node.js 20+ on the machine where Cursor runs the MCP (local laptop or remote SSH host).
Clone this repo, install, and build (see Quick Start).
dist/index.jsmust exist (npm run build) before adding the MCP entry.
2. Credentials
Copy the template:
cp .env.example .envEdit
.envand set at leastQOBRIX_API_URL,QOBRIX_API_USER, andQOBRIX_API_KEY(see Configuration).Keep
.envout of git; it is listed in.gitignore.
3. Where to put the JSON
Location | When to use |
| You opened that project folder in Cursor; teammates can commit a template (without secrets) or you keep it local-only. |
| Same MCP on every workspace on that machine. |
Merge your entry into the existing "mcpServers" object; do not replace the whole file if you already have other servers.
4. Recommended: node --env-file (Node 20+)
Pass absolute paths so it works the same whether the workspace root is this repo or a parent folder (and so SSH remote paths resolve correctly).
{
"mcpServers": {
"qobrix-crm-mcp": {
"command": "node",
"args": [
"--env-file=/absolute/path/to/qobrix-crm-mcp/.env",
"/absolute/path/to/qobrix-crm-mcp/dist/index.js"
],
"description": "Read-only Qobrix CRM MCP"
}
}
}Why this pattern:
Credentials stay in
.env, not in JSON.Node loads the file before your server starts, so
process.envis populated even when the host’senvFilefield is ignored or behaves inconsistently for stdio servers.
5. Alternative: inline env
Useful if you cannot use --env-file (older Node). Secrets live in mcp.json — restrict file permissions and do not commit them.
{
"mcpServers": {
"qobrix-crm-mcp": {
"command": "node",
"args": ["/absolute/path/to/qobrix-crm-mcp/dist/index.js"],
"env": {
"QOBRIX_API_URL": "https://yourcrm.qobrix.com",
"QOBRIX_API_USER": "your-api-user-uuid",
"QOBRIX_API_KEY": "your-api-key",
"QOBRIX_LOCALE": "en-US"
}
}
}
}You can also use Cursor’s config interpolation (for example ${env:QOBRIX_API_KEY}) so values are injected from your OS environment instead of literals.
6. Optional: envFile in MCP JSON
Cursor supports an envFile property for stdio servers. Some setups do not pass those variables into the child process reliably; if tools fail with “Missing required environment variables”, switch to --env-file as in step 4.
7. After editing mcp.json or .env
Reload MCP — Command Palette → MCP restart, or reload the Cursor window.
Check logs — View → Output → pick “MCP” / “MCP Logs” in the dropdown; fix path or Node errors there.
Tool approval — By default Cursor asks before each tool call; you can allow auto-run for trusted tools in Cursor settings if you prefer.
Other MCP hosts
Claude.ai / Claude Desktop (Mode D) — remote custom connector at https://intranet.sharpsir.group/qobrix-crm/mcp. See Mode D and INSTALL — Connect Claude.
Dust.tt (Mode D) — Spaces → Tools → Add MCP Server with the same URL. Prefer Automatic auth and Personal accounts. See INSTALL — Connect Dust.
Claude Desktop / Cursor (Mode A stdio) — same stdio shape: command + args to node and either --env-file or env in the host’s MCP config file.
CI / headless — run node --env-file=.env dist/index.js with a stdio MCP client library; ensure .env is supplied via secrets, not committed.
Search Expression Syntax
Tools that accept a search parameter use Qobrix's Symfony Expression Language (OpenAPI SearchExpression). Call qobrix_search_dsl_help for the full grammar + property/project field cheatsheets (optionally with live schema field names).
Feature | Syntax | Example |
Equality |
|
|
Comparison |
|
|
Contains |
|
|
Set membership |
|
|
Range |
|
|
Logical |
|
|
Date helpers |
|
|
Time shortcuts |
|
|
Current user |
|
|
Geo / misc |
|
|
Association path |
|
|
Tip: Call
qobrix_search_dsl_help({ resource: "Properties" })before composing free-language demand into a query. Useqobrix_get_field_optionsfor enum values andqobrix_get_schemafor the full field list.
Relevant search on all resources (F1)
Every qobrix_search_* tool (properties, projects, contacts, agents, opportunities, viewings, tasks, offers, contracts) uses a two-tier design so free-language demand maps to high precision and high recall:
search— hard must-haves (server-side DSL filter → precision floor).boost[]— soft weighted nice-to-haves scored in-process over a candidate pool (recall + ranking).limit— how many ranked rows to return (default 10, max 100). Raise for more options; keep modest to avoid context overload.max_scan— candidate pool when boosting (default 100, hard cap 500). Higher improves recall; each scanned page is response-cached.
With boost, each row includes _relevance (score) and _matched (which clauses hit); pagination.mode is "ranked". Without boost, a single cached list page is returned (mode: "fast").
qobrix_search_properties({
search: 'status == "available" and sale_rent == "for_sale"',
boost: [
{ field: "sea_view", op: "==", value: true, weight: 3 },
{ field: "bedrooms", op: ">=", value: 3, weight: 2 },
{ field: "list_selling_price_amount", op: "in", value: "200000..600000", weight: 2 },
],
limit: 15,
max_scan: 200,
});Lead ↔ listing matching via search (2-way)
Demand → supply: take a lead's criteria →
qobrix_search_properties/qobrix_search_projectswithsearch+boost. Native:qobrix_get_properties_by_lead/qobrix_get_lead_properties.Supply → demand:
qobrix_search_opportunitieswith open-leadsearch+boostagainst the listing (works for projects too). Native for properties only:qobrix_get_leads_by_property.
// Who wants a Limassol 3-bed ~€400k listing?
qobrix_search_opportunities({
search: 'status in ["new","open"] and buy_rent == "buy"',
boost: [
{ field: "area_of_interest", op: "contains", value: "Limassol", weight: 3 },
{ field: "bedrooms_from", op: "<=", value: 3, weight: 2 },
{ field: "list_selling_price_to", op: ">=", value: 400000, weight: 2 },
],
limit: 15,
max_scan: 200,
});Boost operators: == != < > <= >= in contains starts_with ends_with. For ranges use op: "in" with value: "min..max".
Search (and every other list/get) shares the global cache TTL (QOBRIX_CACHE_TTL, default 300s). After CRM edits, refresh with qobrix_cache_clear({ prefix: "v1:request:properties" }) (or opportunities, projects, …).
Fetching Related Data
Three strategies to resolve foreign keys:
include[]parameter — expand associations inline in one call
qobrix_get_property({ id: "...", include: ["Agents", "PropertyViewings"] })Separate get call — take the UUID from an FK field and call the appropriate tool
// property.agent → UUID
qobrix_get_agent({ id: "<agent-uuid>" })Search by FK — find related records via search expression
qobrix_search_properties({ search: 'agent == "<agent-uuid>"' })Only include[] values marked Verified in tool descriptions are guaranteed to work. When include[] is unavailable for an association, use search-by-FK.
Payload defaults
To keep tool outputs short enough for the calling LLM's context window, list / search / get tools default to compact payloads:
Param | Default | Effect when default |
|
| Foreign keys come back as UUID strings instead of being expanded into nested objects. Resolve them on demand with the matching get tool or with a targeted |
|
| Inline media (photos, floor plans, thumbnail URLs) is not attached to list rows. Use |
Override per call only when the caller actually needs the heavier payload:
// Cheap browse — recommended for most reporting / pipeline calls
qobrix_list_properties({ limit: 10 });
// Heavy detail — only when the LLM truly needs nested FKs + media URLs
qobrix_list_properties({ limit: 5, expand: true, media: true });
// Prefer surgical include[] over full expand=true:
qobrix_get_property({ id: "...", include: ["AgentAgents", "ProjectProjects"] });This change typically shrinks qobrix_list_properties({ limit: 10 }) from ~300 KB to ~5–10 KB.
Output cap
Every tool result is capped at QOBRIX_MCP_MAX_RESULT_CHARS characters of rendered JSON (default 30 000, roughly 7.5 K tokens). Behaviour:
Paginated payloads (
{ data: [...], pagination: {...} }): truncated to the largest prefix ofdata[]that fits, and a_truncatedblock is attached withkept_rows,omitted_rows,original_chars,max_chars, and ahinttelling the LLM how to scope the next call. If nested expand/media objects alone blow the cap, rows are compacted to scalars (_truncated.compacted: true) so at least one usable row is returned.Grossly oversized (default: original size
> 8 ×the cap, overrideQOBRIX_MCP_REFINE_MULTIPLIER): returnsstatus: "result_too_large"with_refine_required(assistant instruction + suggested narrowing + smallreturned_sample) so the LLM asks the user to reformulate — not dump.Non-paginated payloads (single
get, custom analytic shapes): the JSON is clipped at the cap and aQOBRIX_MCP TRUNCATEDtrailer is appended (or the same refine directive when grossly oversized).
When boost is used with expand=true or media=true, max_scan is auto-capped at 100 and pagination.scan_capped_reason may be "expand/media".
Override the cap / refine threshold:
QOBRIX_MCP_MAX_RESULT_CHARS=60000
QOBRIX_MCP_REFINE_MULTIPLIER=8If you regularly hit the cap or refine guard, use fields[] (whitelist columns), a tighter search expression, a smaller limit, or keep expand=false / media=false.
Testing
The project includes 226 automated tests across 63 describe suites (integration, multi-step scenarios, RESO workflows, cache, relevance, output-cap, client-sort, and OAuth mode smoke):
# Integration tests — individual tool mechanics
npm test
# Scenario tests — multi-step tool chains (19 real-world scenarios)
npm run test:scenarios
# Workflow tests — canonical RE business processes (8 RESO-aligned suites)
npm run test:workflows
# Cache tests — read-through, single-flight, LRU eviction, search-page keys (no API needed)
npm run test:cache
# Relevance tests — boost scoring, DSL help, search cache keys (no API needed)
npm run test:relevance
# Format tests — output cap + truncation behaviour (no API needed)
npm run test:format
# OAuth modes smoke — Mode B header rejection + Mode C /connect elicitation path
npm run test:oauth-modes
# Run everything
npm run test:allSuite | Tests | Coverage |
Integration | 70 | Every tool, pagination edge cases, include/fields mechanics, analytics + reporting tools |
Scenarios | 55 | Agent morning brief, buyer search, lead triage, FK chains, pipeline reports |
Workflows | 39 | Listing lifecycle, lead funnel, sales pipeline, showing, transaction, media, activity, schema |
Cache | 22 | Read-through cache, single-flight coalescing, LRU eviction, key canonicalization, search-page keys (no live API) |
Relevance | 23 | Boost eval/score/rank (incl. opportunity/contact shapes), fields[]+boost union, DSL help text, search cache-key stability (no live API) |
Format | 7 |
|
Client sort | 7 |
|
OAuth modes | 4 | Mode B headers, Mode C |
Architecture
src/
├── index.ts # MCP server entry point + RESO workflow instructions
├── http.ts # Streamable HTTP transport (Modes B / C)
├── modes.ts # Auth mode resolution (env / headers / oauth / oauth-claude)
├── client.ts # QobrixClient — HTTP + read-through response cache
├── auth-context.ts # AsyncLocalStorage per-request credentials
├── oauth-client.ts # Mode C self-service OAuth client + session vault
├── oauth-rs.ts # Companion AS metadata + introspection helpers
├── request-context.ts# ALS for McpServer (elicitation capability detection)
├── cache.ts # LRU memory tier, optional Redis, single-flight coalescing
├── relevance.ts # Boost scoring + cached candidate pager for search
├── search-dsl.ts # Full SearchExpression DSL reference + field cheatsheets
├── types.ts # TypeScript interfaces
├── schemas.ts # Zod schemas with rich LLM-facing descriptions
└── tools/
├── index.ts # Tool registration hub + formatResult / errorResult
├── properties.ts # Listing Lifecycle + relevance search
├── contacts.ts # Lead-Contact Lifecycle tools
├── agents.ts # RESO Member tools
├── opportunities.ts # Sales Pipeline tools
├── viewings.ts # Showing Lifecycle tools
├── tasks.ts # Follow-up & Pipeline Management tools
├── media.ts # Media Lifecycle tools
├── projects.ts # Project/Development + relevance search
├── offers.ts # Transaction Lifecycle tools
├── contracts.ts # Transaction close tools
├── activities.ts # Activity Tracking (calls, meetings, emails)
├── analytics.ts # qobrix_count, qobrix_top_values, qobrix_top_records, qobrix_aggregate
├── deals.ts # qobrix_deals (flexible Contracts shortcut)
├── reports.ts # qobrix_timeseries (bucketed metric + YoY), qobrix_days_on_market
├── pipeline.ts # qobrix_funnel, qobrix_stale_leads, qobrix_win_loss
├── productivity.ts # qobrix_rep_scorecard
├── customers.ts # qobrix_cohort (repeat buyers/sellers/leads)
├── cache.ts # qobrix_cache_stats, qobrix_cache_clear
├── audit.ts # change log / field history / top changers
└── meta.ts # Schema discovery + qobrix_search_dsl_help
test-suite/
├── integration.test.mjs # Live API smoke tests
├── scenarios.test.mjs # Multi-step CRM scenarios
├── workflows.test.mjs # RESO workflow coverage
├── cache.test.mjs # Cache unit tests (incl. search-page keys)
├── relevance.test.mjs # Boost scoring + DSL help unit tests
├── format.test.mjs # Output-cap / truncation tests
└── oauth-modes.test.mjs # Mode B/C auth smoke testsHow the LLM Learns
The server teaches the LLM at three levels:
Server instructions — top-level
instructionsfield in the MCPinitializeresponse provides the full data model, six canonical workflows with tool recipes, search syntax, FK resolution strategies, and known quirks.Tool descriptions — each tool description includes its canonical workflow role, RESO equivalent, verified
include[]options, FK field mappings, response shape, and search examples. Relevance search tools document the two-tiersearch+boostrecipe;qobrix_search_dsl_helpexposes the full DSL on demand.Parameter descriptions — Zod schemas provide per-parameter help with concrete examples, valid enum values, and cross-tool references.
Technology
Component | Technology |
Runtime | Node.js ≥ 20 |
Language | TypeScript 5.7 |
MCP SDK |
|
Validation | Zod 3.24 |
Optional cache |
|
Transport | stdio (default) · Streamable HTTP (Modes B / C) |
API Auth | Mode A/B: |
Testing | Node.js built-in test runner ( |
License
Apache License 2.0 — Copyright 2025–2026 SharpSir Group
Modes A and B are included in this open-source package. Mode C pairs with SharpSir’s Enterprise OAuth Authorization Server (SSO / per-user identity) — a separate commercial product delivered upon request — sharpsir.group · dev@sharpsir.group.
Available Tools
64 toolsqobrix_aggregateA
Sum / avg / min / max / count of a numeric field across all matching records — optionally grouped by another field (top-N buckets). Paginates server-side (cap 20,000 rows) and computes in-process, which is how to get totals on Qobrix fields the API won't sort. Example uses: Total 2026 closed-sale volume: resource='contracts', field='final_selling_price_amount', op='sum', search='contract_type == "cos" and contract_status == "agreed" and date_of_contract >= "2026-01-01" and date_of_contract < "2027-01-01"'. Agent leaderboard by volume: same search, group_by='commission_to_2', top=5. Average list price by property type: resource='properties', field='list_selling_price_amount', op='avg', group_by='property_type', search='status == "available"'.
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | Aggregation: 'sum' total, 'avg' mean, 'min'/'max' extremes, 'count' rows with a non-empty value. | |
| top | No | When group_by is set, number of top buckets to return (default 10, max 50). Buckets sorted by op desc. | |
| field | Yes | Numeric field to aggregate (e.g. 'final_selling_price_amount', 'commission_value_amount', 'list_selling_price_amount'). For op='count', any field works (only non-null values are counted). | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| resolve | No | If true and group_by looks like a UUID FK (or any dim of a multi-dim group_by does), resolve bucket keys to readable names. Defaults to true when any dim is in the always-resolve set, false otherwise. | |
| group_by | No | Optional grouping. Pass a single field name (e.g. 'commission_to_2' for agent leaderboard, 'property_type' for type-mix, 'city' for geo) or an array of 2-3 fields for a multi-dimensional pivot (e.g. ['city','property_type']). Without group_by returns a single aggregate. | |
| resource | Yes | Resource name (case-sensitive, lowercase plural as used by Qobrix API). Values: properties, opportunities, contacts, agents, tasks, property-viewings, projects, offers, contracts, calls, meetings, email-messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does well by disclosing server-side pagination with a 20,000-row cap and in-process computation. This goes beyond schema info. It does not mention what happens when the cap is exceeded or any side effects, but for a read-only aggregation tool these are relatively minor gaps.
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 function, followed by behavioral details and three illustrative examples. It is longer than a minimal description but every sentence contributes meaningful information, making it well-structured and efficient.
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?
The description covers purpose, behavior, and parameters comprehensively with examples. However, since there is no output schema, it does not explicitly describe the return format (single aggregate vs. bucket list), nor does it address behavior when pagination cap of 20,000 rows is reached. These omissions leave some context incomplete for a complex aggregation 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 description coverage is 100%, and each parameter already has detailed semantics (op enum, search DSL, group_by, resolve, resource list). The tool description adds value through examples but does not introduce new parameter meaning beyond what the schema provides; it reinforces usage rather than expanding semantics.
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's function: aggregating a numeric field via sum/avg/min/max/count across records, with optional grouping and top-N buckets. It provides concrete examples (total 2026 closed-sale volume, agent leaderboard, average list price) that distinguish it from sibling list/search tools and specialized aggregation tools like qobrix_count or qobrix_top_values.
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 explicitly mentions 'which is how to get totals on Qobrix fields the API won't sort', giving a clear when-to-use signal. Multiple examples illustrate real use cases. However, it does not explicitly state when not to use it or name alternative tools for simpler counts or time-series aggregations, so it stops short of full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_cache_clearA
Invalidate cached Qobrix responses. Use this when CRM data was edited in Qobrix and you need fresh reads before the TTL (default 300s) expires. Without 'prefix': clears the whole cache (memory + Redis). With 'prefix': clears only matching keys, e.g. 'v1:request:opportunities' to refresh lead lists, or 'v1:request:properties' to refresh listings. Returns the number of cleared entries in each tier.
| Name | Required | Description | Default |
|---|---|---|---|
| prefix | No | Optional cache-key prefix to clear (e.g. 'v1:request:properties' to invalidate only property responses). Omit to clear the entire cache (memory + Redis). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that without a prefix the entire cache (memory + Redis) is cleared, with a prefix only matching keys are cleared, the default TTL of 300s, and that the return value indicates cleared entries per tier. This is strong coverage, though it stops short of discussing the broader performance impact of clearing the whole cache.
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 three sentences that efficiently cover purpose, trigger condition, mode behavior, examples, and return value. There is no filler; every sentence contributes meaningful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single optional parameter, the description is fully self-sufficient. It explains what the tool does, when to use it, how to use it in both modes, with examples, and what it returns. No output schema is needed because the return behavior is described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the optional 'prefix' parameter with full coverage. The description adds value beyond the schema by providing real-world examples (e.g., 'v1:request:opportunities' for lead lists) and clarifying the behavior difference between including and omitting the prefix.
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 'Invalidate cached Qobrix responses' with a specific verb and resource. It is distinct from all sibling tools, which are read/search/analysis operations, by focusing on cache invalidation.
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 says when to use this tool: 'when CRM data was edited in Qobrix and you need fresh reads before the TTL expires.' It also gives concrete examples for prefix usage. However, it does not mention when not to use it or alternative tools like qobrix_cache_stats.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_cache_statsA
Inspect the response cache: hits/misses, in-memory size, in-flight coalesced requests, TTL (seconds), and Redis tier status. Use to verify the cache is paying off (high hits, low misses on repeated workflows) or to diagnose why a query feels slow (cold cache, Redis degraded). Stats are process-local; restart resets them.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries the full burden. It discloses that stats are process-local and reset on restart, and it describes what the tool reports. It does not explicitly state that it is read-only, but 'Inspect' implies this, and no side effects are mentioned. The process-local caveat is valuable 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?
Three concise sentences: first states what it does, second gives usage guidance, third notes a critical limitation. No filler, front-loaded with the action and resource, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema diagnostic tool, the description is nearly complete. It names all key metrics and gives a caveat about process-local resets. It could theoretically specify the exact return shape, but the listed metrics suffice for an agent to know what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is complete. The description adds semantics by detailing exactly which stats are returned, effectively describing the output fields. Baseline for 0 params is 4, and the description meets that by providing meaningful return-value context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Inspect the response cache' and enumerates specific metrics (hits/misses, in-memory size, in-flight coalesced requests, TTL, Redis tier status). This clearly differentiates it from sibling tools, especially qobrix_cache_clear, by focusing on inspection rather than mutation.
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 explicitly says when to use the tool: 'to verify the cache is paying off' and 'to diagnose why a query feels slow', giving concrete scenarios (high hits, low misses, cold cache, Redis degraded). It does not name alternatives because none exist for stats, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_cohortA
Find contacts that appear on multiple deals or opportunities — the 'repeat customer' report every CRM analyst gets asked for. Three modes: 'buyers' (default) walks closed contracts → opportunity_id → opportunities.contact_name to identify the buyer behind each closed sale. 'sellers' walks contracts → property_id → properties.seller. 'leads' groups all opportunities by contact_name regardless of close. Returns each repeat contact with deal_count, total_volume, total_commission, first_deal, last_deal, and a deals[] breakdown. Example uses: 2026 repeat buyers: { kind: 'buyers', year: 2026, min_count: 2 }. All-time loyal customers: { kind: 'buyers', min_count: 3 }. Recurring sellers this year: { kind: 'sellers', year: 2026 }. Frequent enquirers (any close): { kind: 'leads', since_days: 365 }.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO exclusive upper bound. | |
| top | No | Max repeat contacts to return (default 20). | |
| from | No | ISO inclusive lower bound. | |
| kind | No | Which population to cohort (default 'buyers'). 'buyers' = contacts behind closed contracts (contract.opportunity_id → opportunity.contact_name). 'sellers' = contacts on the listing side (contract.property_id → property.seller). 'leads' = contacts on opportunities regardless of close. | |
| year | No | Calendar year window. | |
| min_count | No | Minimum deal/opportunity count per contact to include them in the cohort (default 2). | |
| since_days | No | Rolling window in days. | |
| contract_types | No | Contract types for buyers/sellers (default ['cos']). | |
| contract_statuses | No | Contract statuses for buyers/sellers (default ['agreed']). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the internal logic for each mode (e.g., 'walks closed contracts → opportunity_id → opportunities.contact_name') and details the exact return fields (deal_count, total_volume, etc.). It does not mention authentication, rate limits, or cost, but for a read-only reporting tool, the disclosed behavior is solid.
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 well-structured and every sentence adds value: overview, mode explanations, return fields, and concrete examples. It is longer than a trivial sentence but appropriate for a tool with 9 parameters and three modes. The examples are concise and directly illustrate usage.
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?
The tool has 9 optional parameters, no output schema, and no annotations. The description covers the core functionality, all three modes, and the return data shape, which is sufficient for most usage. However, it doesn't explain how parameters interact (e.g., 'year' vs 'from/to' vs 'since_days') or edge cases like conflicting windows, which would be helpful for complete guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the 'kind' parameter's three modes in depth and providing example values for 'year', 'min_count', and 'since_days' in context. It also clarifies the meaning of 'buyers' vs 'sellers' vs 'leads' beyond the enum names. However, it does not add extra nuance for parameters like 'contract_types' or 'contract_statuses' beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: finding contacts that appear on multiple deals or opportunities, with a specific verb ('Find') and resource ('contacts'). It distinguishes itself from sibling list/search tools by focusing on repeat-customer cohort analysis across deals and opportunities, and describes three distinct modes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete example use cases with parameter combos (e.g., '2026 repeat buyers', 'All-time loyal customers'), making when to use the tool clear. However, it does not explicitly contrast with alternative sibling tools like qobrix_deals or qobrix_aggregate, which could also be used for similar analytical queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_countA
Count records matching a search expression — returns just the total count, no data payload. Faster and lighter than fetching records when you only need a number. Example uses: Total active sale listings: resource='properties', search='status == "available" and sale_rent == "for_sale"'. Q1 closed-won opportunities: resource='opportunities', search='status == "closed_won" and last_status_change >= "2026-01-01" and last_status_change < "2026-04-01"'. Contacts created this month: resource='contacts', search='created >= THIS_MONTH'.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| resource | Yes | Resource name (case-sensitive, lowercase plural as used by Qobrix API). Values: properties, opportunities, contacts, agents, tasks, property-viewings, projects, offers, contracts, calls, meetings, email-messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the safety/behavior burden. It discloses that the tool returns only a count and no data payload, and that it's faster/lighter, which is the key behavioral trait. It does not mention error cases or auth requirements, but for a count operation these are less critical.
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 purpose, quickly states the performance benefit, then provides three compact examples. Each sentence serves a distinct function; no redundant or filler content.
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?
The description explains the return type (total count, no payload) and gives representative examples for the search DSL. It could mention output format or edge cases, but the examples and performance note cover the main usage scenarios adequately.
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 value with three concrete example search expressions spanning different resources and operators, illustrating how to combine filters and use shortcuts like THIS_MONTH. This exceeds the schema's already detailed parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Count records matching a search expression', explicitly distinguishing from list/fetch tools by stating it returns only the total count, no data payload. This clearly separates qobrix_count from sibling search/list tools.
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 explicitly says 'Faster and lighter than fetching records when you only need a number', giving clear when-to-use context. It doesn't name specific alternative tools or exclusions, but the general fetch vs count distinction is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_days_on_marketA
Days-on-market analytics. Joins Contracts to Properties on property_id and computes the (close_date - listing_date) duration in days, then aggregates count / mean / median / p75 / p90 / min / max. Defaults: kind='sold' (cos + agreed), listing_date_field='listing_date' with per-row fallback to website_listing_date then created. Use group_by to break down by property_type, city, agent, or commission_to_2 (broker). Set include_outliers=true for the 5 longest and 5 shortest deals. Example uses: Overall DOM for 2026 sales: { kind: 'sold', year: 2026 }. DOM by property type: { kind: 'sold', year: 2026, group_by: 'property_type' }. DOM by city (with outliers): { year: 2026, group_by: 'city', include_outliers: true }. Reservation cycle: { kind: 'reserved', year: 2026 }.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO exclusive upper bound. | |
| top | No | Max group buckets to return (default 10). | |
| from | No | ISO inclusive lower bound. | |
| kind | No | Which contracts count as a 'close' (default 'sold' = contract_type=cos + contract_status=agreed). 'reserved' = contract_status=reserved. 'any_closed' = reserved + agreed. | |
| year | No | Calendar year window. | |
| group_by | No | Optional grouping field(s) on the property side: 'property_type', 'city', 'commission_to_2'/'agent' (broker). Multi-dim arrays of 2-3 fields supported. | |
| since_days | No | Rolling window in days. | |
| close_date_field | No | Anchor on the contract side. Default depends on kind: sold→date_of_contract, reserved→date_of_reservation. | |
| include_outliers | No | When true, also returns the 5 longest-DOM and 5 shortest-DOM deals. | |
| listing_date_field | No | Anchor on the property side (default 'listing_date'). Per-row fallback to website_listing_date then created when the chosen field is null. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to fall back on, the description discloses the join, computation, defaults for kind and listing_date_field, the per-row fallback chain, valid group_by fields, outlier behavior, and example combinations. This gives a complete picture of how the tool behaves beyond the raw schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a one-sentence purpose, then dense, purposeful details: defaults, fallback, grouping, outliers, and examples. Every sentence adds information or practical guidance; nothing is wastefully verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description explains the aggregate metrics returned and mentions outlier deals, which covers the main return behavior. It stops short of specifying output ordering or pagination, but for an aggregation tool this is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions, so baseline is 3. The description adds practical value by showing realistic parameter combinations (e.g., { kind: 'sold', year: 2026, group_by: 'city', include_outliers: true }) and reinforcing the meaning of group_by and include_outliers.
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 'Days-on-market analytics' with explicit formula (close_date - listing_date), join logic, and aggregation metrics (count/mean/median/p75/p90/min/max). Clear verb+resource and distinct from sibling analytics tools like funnel or timeseries.
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 four concrete example uses (overall DOM, by property type, by city with outliers, reservation cycle) that clearly convey when to call this tool. Does not explicitly name alternatives or exclusion criteria, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_dealsA
Flexible 'deals' tool over the Contracts table — covers sales, rentals, listing agreements, and pipeline reservations in a single call. Defaults: kind='sale', contract_statuses=['agreed'] (so a no-arg call still means 'closed sale contracts'). Every default is overridable via kind / contract_types / contract_statuses / include_reserved / date_field / min_price / max_price / party filters / raw search. Sorts in-process across the matching set (for a single page of highest prices you can also use list/search with sort='-final_selling_price_amount') and resolves property_id, agent, commission_to, lawyers, bank, etc. to readable names. Example uses: Best 2026 closed sales: { year: 2026, top: 5 }. Best 2026 rentals: { kind: 'rental', year: 2026, top: 5 }. Under-contract pipeline value: { contract_statuses: ['reserved'], year: 2026 }. My deals: { assigned_to: 'CURRENT_USER', year: 2026 }. All revenue deals >€1M last 90 days: { kind: 'any_revenue', since_days: 90, min_price: 1000000 }. Agent leaderboard (by commission): { year: 2026, by: 'commission', top: 10 }.
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | Sort axis (default 'price'). 'price' uses final_selling_price_amount (sale), final_rental_price_amount (rental), or per-row coalesce for mixed kinds. 'commission' uses commission_value_amount. 'date' uses the resolved date_field. | |
| to | No | ISO date (YYYY-MM-DD) exclusive upper bound. | |
| top | No | Number of deals to return (default 10, max 50). The summary block always covers the full filtered set. | |
| desc | No | Sort descending (default true). | |
| from | No | ISO date (YYYY-MM-DD) inclusive lower bound. | |
| kind | No | Semantic shortcut (default 'sale'). Sets default contract_types when contract_types is omitted: 'sale'=['cos'], 'rental'=['tenancy_agreement'], 'listing'=['listing_for_sale','listing_for_rent'], 'any_revenue'=['cos','tenancy_agreement'], 'any'=no contract_type filter. | |
| year | No | Calendar year window (e.g. 2026). | |
| agent | No | Convenience alias for commission_to_2 (the deal's broker/external agent). | |
| search | No | Extra raw Qobrix search expression ANDed with everything else (escape hatch for niche filters). | |
| max_price | No | Upper bound on the kind's natural price field. | |
| min_price | No | Lower bound on the kind's natural price field (selling for sale, rental for rental). | |
| date_field | No | Which date column to filter by (default depends on kind: sale=date_of_contract, rental=start_date, listing=created, otherwise date_of_contract). | |
| since_days | No | Rolling window: only deals dated within the last N days. Mutually exclusive with year/from/to. | |
| assigned_to | No | User UUID assigned to the contract, or the special token 'CURRENT_USER'. | |
| commission_to | No | User UUID receiving commission (commission_to), or 'CURRENT_USER'. | |
| contract_types | No | Explicit contract types (overrides kind defaults). Subset of: cos, tenancy_agreement, listing_for_sale, listing_for_rent, property_management, viewing_agreement. | |
| commission_to_2 | No | Agent UUID receiving commission (commission_to_2). | |
| include_reserved | No | Convenience flag: when true, adds 'reserved' to contract_statuses. | |
| contract_statuses | No | Contract statuses (default ['agreed']). Use ['reserved','agreed'] for under-contract + closed, ['reserved'] for pipeline only, ['cancelled'] for fall-throughs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses defaults, overridability, sorting behavior, field resolution, and the in-process nature of sorting. It does not explicitly state read-only behavior, but that is implied for a query tool. It also omits details about pagination or return format, but the examples imply a list of deals.
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 long but packed with valuable information: purpose, defaults, overridable parameters, and seven distinct example uses. It is front-loaded with the core purpose and defaults, then examples. While it could be formatted more cleanly (e.g., bullet points), every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 19-parameter tool with no output schema, the description is quite complete. It covers defaults, parameter relationships, sorting, field resolution, and provides realistic usage scenarios. It does not explain the return structure, but the examples and schema descriptions cover the essentials. Minor gap: no mention of pagination or how the top parameter interacts with the summary block, but that is in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds meaningful semantics by explaining how kind sets contract_types defaults, default date_field behavior, and the effect of include_reserved. The examples demonstrate how parameters combine for real use cases, adding value 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?
The description clearly states the tool is a flexible 'deals' tool over the Contracts table covering sales, rentals, listing agreements, and pipeline reservations in a single call. It provides multiple example uses that illustrate its scope and differentiates it from sibling tools like list/search by emphasizing its aggregate/filtering capabilities and ability to resolve fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit default behavior (kind='sale', contract_statuses=['agreed']) and a wide range of usage examples (best 2026 closed sales, rentals, pipeline, my deals, revenue >€1M, leaderboard). It even names an alternative approach for a single page of highest prices using list/search with sort='-final_selling_price_amount', providing clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_field_change_historyA
Build a chronological timeline of edits to one field on one CRM record. Paginates GET /{resource}/{id}/changes and filters rows where the field appears in original or changed. Returns [{timestamp, user_id, user_name?, type, before, after}] sorted oldest-first. Use for: 'who changed source on this opportunity and when?'
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Record UUID to inspect | |
| field | Yes | CRM field name whose edits to extract from original/changed objects. Example: 'source', 'status', 'agent'. NOT the LogAudit.source column (that is the resource name). | |
| resource | Yes | CRM resource name. PascalCase (e.g. 'Opportunities', 'Properties', 'Contracts') or kebab slug (e.g. 'opportunities'). Maps to GET /api/v2/{resource}/changes. Common values: Opportunities, Properties, Contacts, Contracts, Offers, Tasks, Calls, Meetings. | |
| max_pages | No | Max API pages to fetch (100 rows/page). Default 10 (1000 audit rows). | |
| resolve_users | No | When true, resolve user_id to display name via Users API (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosure. It transparently explains the pagination ('Paginates GET /{resource}/{id}/changes'), filtering logic, return shape (including optional 'user_name'), sorting order, and the resolve_users behavior. It does not mention error handling or rate limits, but covers the core behavioral traits expected of a read-only history tool.
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 compact and front-loaded. The first sentence states the core purpose, the second details the mechanics, and the final sentence offers a concrete use case. No filler or redundancy—each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters and no output schema, the description is remarkably complete. It documents the return shape inline, pagination defaults, and a real-world scenario. It omits edge-case behavior like empty results or error conditions, but those are less critical for a simple query 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 contextual value beyond the schema: it clarifies that 'field' is not the LogAudit.source column, explains the resource-to-URL mapping, and states defaults for max_pages and resolve_users. This helps select and invoke parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Build a chronological timeline of edits to one field on one CRM record.' This clearly distinguishes it from sibling tools like get_changes or search_changes, which handle broader change queries. The concrete use case 'who changed source on this opportunity and when?' further anchors the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear, explicit use case ('who changed source on this opportunity and when?') that signals when to apply the tool. It does not explicitly name alternatives or exclusions, but the focused purpose implies when it is appropriate relative to more general change-history tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_funnelA
Canonical sales funnel in one call. Six stages with conversion %: Leads (opportunities created in window) → Qualified (status in [open,won]) → Viewing (property-viewings created in window) → Offer (offers created in window) → Reserved (contracts with contract_status=reserved) → Closed (contracts cos + agreed). Each stage is scoped by the same date window and (optional) assigned_to / agent. Use stage_overrides to substitute a tenant-specific definition for any stage. Example uses: 2026 funnel: { year: 2026 }. My funnel last 90 days: { assigned_to: 'CURRENT_USER', since_days: 90 }. Agent Vera's funnel: { agent: '', year: 2026 }.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO exclusive upper bound. | |
| from | No | ISO lower bound. | |
| year | No | Calendar year window for the funnel. | |
| agent | No | Agent UUID (commission_to_2 / Properties.agent) to scope to an external broker. | |
| since_days | No | Rolling window in days. | |
| assigned_to | No | User UUID, or 'CURRENT_USER' to scope the funnel to one rep. | |
| stage_overrides | No | Optional map of stage_name → raw Qobrix search expression to override the canonical stage definition. Valid stage names: 'leads', 'qualified', 'viewing', 'offer', 'reserved', 'closed'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses stage definitions, date-window scoping, optional assigned_to/agent scoping, and stage_overrides behavior. Since no annotations exist, this carries the transparency burden; it's mostly clear, though 'cos' in the Closed stage definition is ambiguous.
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?
At around 150 words, the description is dense but well-structured: state chain, scoping rule, override mechanism, then three examples. No redundant information; each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description compensates by specifying the six stages and conversion %, the scoping rule, and override capability. The examples cover common use cases, making it sufficiently complete for an AI agent to select and invoke 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?
The schema already covers all parameters with 100% coverage, but the description adds meaningful examples showing parameter combinations ({year}, {assigned_to, since_days}, {agent, year}) and clarifies stage_overrides semantics. This elevates understanding beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states this is a sales funnel tool aggregating six stages (Leads, Qualified, Viewing, Offer, Reserved, Closed) with conversion percentages, distinguishing it from sibling list/search tools. It uses a specific verb 'Canonical sales funnel in one call' and details each stage's definition, making the purpose unmistakable.
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 provides three concrete example uses covering year, rolling days with CURRENT_USER, and agent-specific scoping, demonstrating when to invoke this tool. It doesn't explicitly compare against alternatives like qobrix_deals, but the examples imply this is the go-to for funnel metrics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_agentA
Get a single agent by UUID — resolve a RESO Member/ListAgent from a listing or lead. Returns { data: { id, ref, ... } }. Verified include: PrimaryContactContacts, User, Brands, AgencyAgents (parent brokerage). Agent 360° pattern: 1. Active listings: qobrix_search_properties with agent == '' and status == "available" 2. Active leads: qobrix_search_opportunities with agent == '' and status == "open" 3. Pipeline deals: qobrix_search_offers / qobrix_search_contracts linked to agent's opportunities 4. Activity: search Tasks, Calls, Meetings by the agent FK
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Agent UUID | |
| include | No | Associations to expand. Verified options: PrimaryContactContacts, User, Brands, AgencyAgents |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It reveals the return shape ('Returns { data: { id, ref, ... } }'), lists verified include options, and explains the agent's relationships (e.g., parent brokerage). It does not explicitly state that it is read-only, but 'Get' implies a non-mutating operation. Lacks error/rate-limit details, but the provided context is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but every sentence adds useful information: purpose, return shape, include options, and a detailed usage pattern. It is front-loaded with the primary purpose, and the pattern section is a structured list that is easy to scan. Slight redundancy in the pattern but overall efficient.
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 single-resource fetch with only two parameters, the description is remarkably complete: it covers return format, expand options, and provides a full '360°' workflow with sibling tools. Even without an output schema, an agent can reasonably understand what to expect and how to integrate this call.
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 covers both parameters with descriptions, but the tool description adds value by elaborating the 'include' options (verified list) and showing how the UUID is used in related tool calls (e.g., agent == '<uuid>'). This goes beyond the schema's minimal descriptions, enhancing understanding of parameter usage.
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 'Get a single agent by UUID', specifying the exact resource and operation. It differentiates from sibling tools like qobrix_list_agents and qobrix_search_agents by emphasizing single-agent retrieval by UUID, and from qobrix_get_contact by noting this returns a RESO Member/ListAgent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong usage guidance: it says to resolve an agent from a listing or lead, and offers an 'Agent 360° pattern' with explicit tool names and filter examples (e.g., qobrix_search_properties with agent == '<uuid>'). This implicitly tells when to use this tool versus alternatives, making it highly informative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_callA
Get a single call record by UUID — call detail in the Activity Tracking workflow. Returns { data: { id, ... } }. Include: AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, CreatedByUsers.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Call UUID | |
| include | No | Associations to expand. Options: AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, CreatedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return shape as '{ data: { id, ... } }', which is a behavioral trait beyond what the schema provides. It also lists the expandable include associations. It does not mention errors, read-only safety, or pagination (though for a single record this is less critical), so it is not a 5 but is above average.
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 compact and front-loaded with the purpose. The first sentence is the core action, the second provides return structure, and the third lists includes. However, the include list is redundant with the schema's parameter description, so a small amount of the text is wasted. Still, overall it is efficient and readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-record get tool with 2 parameters, no output schema, and no annotations, the description provides the essential return shape ('{ data: { id, ... } }') and the expandable associations. It lacks error behavior or explicit read-only confirmation, but these are less critical for a get operation. The description is sufficiently complete for an agent to invoke the tool 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 description coverage is 100%, so the baseline is 3. The description repeats the include options that are already fully documented in the schema, adding no additional meaning or syntax details. It does not clarify usage nuances beyond what the schema already states, so it neither improves nor degrades parameter understanding.
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 uses a specific verb+resource construction: "Get a single call record by UUID." It clearly identifies the exact scope (single vs. list) and the identifier required, distinguishing it from sibling list/search tools. The addition "call detail in the Activity Tracking workflow" provides contextual framing without ambiguity.
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 to use this tool (when you need a single call's details by UUID) but does not explicitly state alternatives or exclusions. It does not mention that for multiple calls you'd use qobrix_list_calls, nor does it provide any 'when not to use' guidance. The context of 'Activity Tracking workflow' gives some indication, but it's not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_changesA
Retrieve audit / change-log entries for a single CRM record (Qobrix LogAudit). Calls GET /api/v2/{resource}/{id}/changes. Each row has original (before), changed (after), user_id (who), timestamp, type (create/update/delete). IMPORTANT: LogAudit.source is the resource name (e.g. 'Opportunities'), NOT the lead marketing source field. Field-level before/after for e.g. lead source are keys inside original and changed objects. For a filtered timeline of one field use qobrix_field_change_history.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Record UUID — the opportunity/property/contact primary key | |
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort field(s). Prefix - for descending. Example: '-timestamp' (newest first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | LogAudit columns to return. Default all. Recommended for large scans: ['timestamp','user_id','primary_key','original','changed','type'] | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| resource | Yes | CRM resource name. PascalCase (e.g. 'Opportunities', 'Properties', 'Contracts') or kebab slug (e.g. 'opportunities'). Maps to GET /api/v2/{resource}/changes. Common values: Opportunities, Properties, Contacts, Contracts, Offers, Tasks, Calls, Meetings. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the response structure (original, changed, user_id, timestamp, type) and clarifies a potential naming pitfall about LogAudit.source. However, it does not explicitly state that the operation is read-only or mention any rate limits or auth requirements, though the GET endpoint implies safety.
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 compact despite covering multiple aspects: purpose, endpoint, output structure, a critical disambiguation, and a cross-reference. Every sentence contributes meaningful information with no filler. The 'IMPORTANT' note is justified and placed appropriately.
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 there is no output schema and no annotations, the description provides a solid overview of what the tool does and returns, including the row fields and the endpoint. It addresses a common confusion and suggests an alternative, making it adequately complete for a moderately complex tool with 7 parameters.
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 does not add significant per-parameter information beyond the schema; it focuses on response structure and a usage caveat. It indirectly clarifies what 'fields' might contain by listing row fields, but this is 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?
The description clearly states the tool retrieves audit/change-log entries for a single CRM record, specifically naming the Qobrix LogAudit and the endpoint. It distinguishes itself from sibling tools by noting the alternative qobrix_field_change_history for one-field timelines, and implies it is for full audit logs of a single record.
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?
Explicitly provides a use-case alternative: 'For a filtered timeline of one field use qobrix_field_change_history.' This tells the agent when to choose another tool. It also clarifies the intended scope (single record) and gives an important caveat about the LogAudit.source field, which prevents misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_contactA
Get a single contact by UUID — the person/company detail view in the Lead-Contact Lifecycle. Returns { data: { id, first_name, last_name, email, phone, ... } }. Verified include: AssignedToUsers (RESO OwnerMember), User, Language, Organizations. To build the full contact journey (canonical 360° view): 1. Leads: qobrix_search_opportunities with contact_name == '' 2. Tasks: qobrix_search_tasks with contact == '' 3. Calls: qobrix_search_calls (search by contact FK) 4. Meetings: qobrix_search_meetings (search by contact FK) 5. Seller listings: qobrix_search_properties with seller == '' This contact 360° pattern is the core of Lead-Contact Lifecycle and Follow-up workflows.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Contact UUID | |
| include | No | Associations to expand. Verified options: AssignedToUsers, User, Language, Organizations |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the return structure and verified includable associations, which is helpful. However, it omits behavior on not-found, error handling, authentication requirements, or rate limits—context a user might need. It does not contradict any annotations (none exist).
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 well-structured with a clear first sentence and numbered list, but it is lengthy. The 360° workflow steps, while useful, go beyond the immediate tool description and could distract from the core get operation. Several sentences could be trimmed without losing primary functionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get tool with no output schema and no annotations, the description provides the return shape, include options, and links to related search tools. It is reasonably complete for an agent to invoke and interpret results, though some edge cases (e.g., missing UUID behavior) are not covered.
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 description adds extra value by listing 'Verified include: AssignedToUsers, User, Language, Organizations' and decoding the return object shape. The 'id' parameter meaning is already in the schema, but the verified include options are additional, actionable details beyond the generic 'Associations to expand'.
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 'Get a single contact by UUID' with a specific verb and resource, and distinguishes it as 'the person/company detail view' from list/search tools. It explicitly positions itself within the Lead-Contact Lifecycle, making its purpose obvious.
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 for a known UUID ('detail view') and provides a detailed 360° journey with alternative tools for related data. However, it does not explicitly say when NOT to use this tool (e.g., for search) or compare with qobrix_list_contacts/qobrix_search_contacts beyond the UUID pointer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_contractA
Get a single contract by UUID — the deal close detail view in the Transaction Lifecycle. Returns { data: { id, ... } }. Verified include: Contacts (buyer/seller), PropertyIdProperties (the listing), OpportunityIdOpportunities (the lead), PaymentInstallments (payment schedule), ContractParties (all signatories), CreatedByUsers. Use include=['PaymentInstallments'] to audit the payment timeline.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Contract UUID | |
| include | No | Associations to expand. Verified options: Contacts, PaymentInstallments, ContractParties, PropertyIdProperties, OpportunityIdOpportunities, CreatedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the return shape ('Returns { data: { id, ... } }'), enumerates verified include options with their meaning, and gives a practical usage hint. It doesn't cover error cases or authentication, but for a simple GET tool this is solid behavioral disclosure.
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 two sentences long, front-loaded with the core purpose, then return shape, then include semantics, then a practical example. Every sentence earns its place with no fluff or 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?
For a tool with just two parameters, no output schema, and no annotations, the description fully covers the essential context: what it does, what the response looks like, what the include parameter options mean, and a concrete usage scenario. There are no obvious gaps for an agent to invoke 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?
Although the schema already documents both parameters with descriptions (100% coverage), the description adds significant semantic value by explaining what each verified include option represents (e.g., Contacts = buyer/seller, PropertyIdProperties = listing). This goes beyond the schema's generic 'Associations to expand'.
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 'Get a single contract by UUID' with a specific resource and action. It also distinguishes itself from sibling list/search tools by describing it as the 'deal close detail view' and specifies the unique purpose in the Transaction Lifecycle context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool (fetching a single contract detail) and even suggests a specific use case ('Use include=['PaymentInstallments'] to audit the payment timeline'). It doesn't explicitly mention when not to use it, but the context is sufficient for an agent to differentiate from list/search alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_email_messageA
Get a single email message by UUID — email detail in the Activity Tracking workflow. Returns { data: { id, ... } }. Include: Properties, ContactContacts, RelatedOpportunityOpportunities, Agent, Campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Email Message UUID | |
| include | No | Associations to expand. Options: Properties, ContactContacts, RelatedOpportunityOpportunities, Agent, Campaign |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the return shape ({ data: { id, ... } }) and the include options, which is helpful. But it doesn't explicitly state that this is a read-only operation, nor does it mention error handling, pagination, or rate limits. For a simple GET, this is adequate but not rich.
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 concise, about 30 words, and front-loaded with the core action. It includes only necessary extras: return format and include options. No fluff or redundancy. The structure is clear and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with a well-specified schema, the description is mostly complete. It provides the return format and include options, and the Activity Tracking workflow context adds background. It lacks explicit read-only confirmation and error handling, but given the simplicity and absence of output schema, these are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides descriptions for both parameters (id and include) with 100% coverage. The description's 'Include: Properties, ...' line essentially repeats the schema's options, adding little new meaning. The return format hint is somewhat useful but not parameter-specific. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource: 'Get a single email message by UUID'. This clearly differentiates it from sibling tools like qobrix_list_email_messages, which list multiple messages. The phrase 'email detail in the Activity Tracking workflow' adds contextual clarity about its intended use.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it's for retrieving one specific email by UUID, which implies use when you have a UUID and need detail, versus a list tool. It mentions the Activity Tracking workflow, giving a concrete scenario. However, it doesn't explicitly exclude alternatives or state 'use this instead of list when you have a UUID'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_field_optionsA
Get dropdown/enum field options — discover valid values for status fields, types, and categories. Essential for building correct search expressions in any workflow. Returns { data: [...], pagination: { ... } }. Each item has: id, resource, field, label, value. Key examples for canonical workflows: Listing statuses: search='resource == "Properties" and field == "status"' → available/reserved/sold/withdrawn. Lead statuses: search='resource == "Opportunities" and field == "status"' → new/open/won/closed_lost. Property types: search='resource == "Properties" and field == "property_type"'. Task types: search='resource == "Tasks" and field == "task_type"'. Pair with qobrix_get_schema for complete field discovery.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Search expression to filter field options. Example: 'resource == "Properties" and field == "status"' to see allowed status values for properties. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return structure ('Returns { data: [...], pagination: { ... } }'), the per-item fields (id, resource, field, label, value), and provides example queries. This gives useful behavioral insight beyond the name, though it doesn't mention pagination mechanics or potential errors.
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 well-structured and front-loaded. It starts with purpose, then return format, item fields, and key examples, ending with a pairing suggestion. Every sentence contributes practical value, and the examples are concise yet informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only lookup tool with 3 parameters and no output schema, the description is complete. It covers purpose, return format, item structure, practical usage examples, and complementary tools. There are no significant gaps given the tool's simplicity.
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 adds value by providing concrete search expression examples that clarify the 'search' parameter semantics, and it explains output item structure, which helps infer parameter usage. It doesn't add much beyond schema for page/limit but the examples are a meaningful addition.
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's purpose: 'Get dropdown/enum field options — discover valid values for status fields, types, and categories.' It uses a specific verb and resource, and the mention of enum options distinguishes it from sibling tools like qobrix_get_schema and qobrix_top_values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: 'Essential for building correct search expressions in any workflow' and shows concrete examples for common use cases (listing statuses, lead statuses, etc.). It also suggests pairing with qobrix_get_schema for complete field discovery, implying when to use this tool versus the alternative. However, it doesn't explicitly state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_lead_propertiesA
Get properties linked to a lead — the 'demand-side matching' tool in the Sales Pipeline. Answers: 'What properties does this buyer want?' by returning properties attached to an opportunity. This is the canonical property suggestion pattern (RESO Demand/Solution matching). Reverse of qobrix_get_leads_by_property (which finds leads for a property). For free-language / ranked demand→supply (incl. projects), use qobrix_search_properties / qobrix_search_projects with search+boost derived from the lead's criteria. In the 8-stage buyer journey, use at the Solution/Viewing stage to prepare showing candidates. The id is the Opportunity UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Opportunity/Lead UUID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description itself discloses behavior. It explains that the tool returns properties attached to an opportunity in the canonical RESO Demand/Solution matching pattern, and clarifies that it is the demand-side matching tool. It doesn't cover edge behaviors like pagination or auth, but for a simple read operation this is acceptable.
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 longer than one sentence but is well-structured: main purpose, then use-case context, alternatives, stage, and parameter clarification. Every sentence adds value, though it could be tightened slightly.
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 a single parameter, no output schema, and no annotations, the description is remarkably complete. It explains what the tool does, when to use it, what the id refers to, and how it fits into the broader process. An agent should be able to select and invoke this tool 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?
The input schema defines 'id' as 'Opportunity/Lead UUID', which is ambiguous. The description adds precision: 'The id is the Opportunity UUID.' This resolves the ambiguity and adds meaning 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?
The description opens with 'Get properties linked to a lead' which is a clear verb+resource+scope. It further explains the purpose by answering 'What properties does this buyer want?' and distinguishes from the reverse tool qobrix_get_leads_by_property. However, the sibling qobrix_get_properties_by_lead is not mentioned, which could cause ambiguity.
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 states when to use this tool: at the Solution/Viewing stage of the buyer journey, and contrasts it with alternatives: for free-language/ranked demand→supply, use qobrix_search_properties/qobrix_search_projects; the reverse operation is qobrix_get_leads_by_property. This gives clear 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.
qobrix_get_leads_by_propertyA
Get matching leads for a property — the 'supply-side matching' tool in the Sales Pipeline. Answers: 'Who is interested in this listing?' by returning leads whose criteria match the property. This is the canonical buyer-property matching pattern (RESO Prospecting). Use after listing a new property to find potential buyers in the existing lead database. Complement with qobrix_get_lead_properties for the reverse (demand-side) match, or qobrix_search_opportunities with boost for ranked matching (incl. projects). The propertyId is the Property UUID. Returns paginated results.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| propertyId | Yes | Property UUID to find matching leads for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool returns paginated results, identifies the matching pattern, and clarifies the propertyId requirement. However, it does not explicitly state read-only behavior or performance trade-offs (e.g., fast path vs. boost), which are left to the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat long (7 sentences) but each sentence provides distinct value—purpose, business question, domain pattern, usage timing, alternatives, parameter clarification, and pagination. Minor redundancy exists between the first and third sentences, but overall it is well-structured and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without an output schema, the description appropriately confirms that the tool returns matching leads and notes pagination. The schema covers page/limit mechanics thoroughly, and the domain context makes the meaning of 'matching' clear enough. It could be even more complete by specifying what fields each lead includes, but this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage with detailed descriptions for all three parameters, including page/limit behavior with boost. The description's mention that 'propertyId is the Property UUID' largely duplicates the schema's 'Property UUID to find matching leads for' and does not add meaningful new semantics.
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 uses a specific verb-object structure with a clear resource: 'Get matching leads for a property.' It also explicitly differentiates from siblings by naming itself the 'supply-side matching' tool and referencing complementary tools like qobrix_get_lead_properties and qobrix_search_opportunities.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Use after listing a new property to find potential buyers in the existing lead database.' It also names specific alternatives for reverse matching and ranked matching, making it clear when this tool is preferred versus the alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_mediaA
Get a single media item by UUID — media detail view in the Media Lifecycle. Returns media metadata including URL/path. Optionally specify size variant for images: 'thumbnail', 'medium', 'large'. Use 'thumbnail' for preview grids, 'large' for full-resolution display.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Media UUID | |
| size | No | Image size variant (e.g. 'thumbnail', 'medium', 'large') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It discloses the return type ('media metadata including URL/path') and the effect of the optional size parameter. However, it does not mention error handling (e.g., not-found behavior), authentication requirements, or any side effects, which leaves some gaps for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action and resource, followed by targeted parameter guidance. No repetition of schema fields or filler, and every clause contributes actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter getter with no output schema, the description covers the core purpose, the return value, and the optional parameter semantics. It could mention not-found behavior or clarify the 'Media Lifecycle' context more, but it is sufficiently complete for typical use.
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 practical value by explaining the use of the 'size' parameter with concrete examples ('thumbnail', 'medium', 'large') and describing their intended use cases ('preview grids', 'full-resolution display'), going beyond the schema's generic 'Image size variant'.
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 verb ('Get'), resource ('single media item by UUID'), and purpose ('media detail view in the Media Lifecycle'). It distinguishes this from sibling tools like qobrix_list_media by emphasizing 'single' and by specifying the return of metadata including URL/path.
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 context ('media detail view in the Media Lifecycle') and explicit guidance on when to use each size variant ('thumbnail' for preview grids, 'large' for full-resolution display). It does not explicitly name alternatives or state when not to use, but the 'single' wording implies a contrast with list operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_meetingA
Get a single meeting by UUID — meeting detail in the Activity/Showing Lifecycle. Returns { data: { id, ... } }. Include: AssignedToUsers, ContactContacts, ViewingPropertyViewings (if it wraps a showing), CreatedByUsers.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Meeting UUID | |
| include | No | Associations to expand. Options: AssignedToUsers, ContactContacts, ViewingPropertyViewings, CreatedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It reveals the return format ({ data: { id, ... } }) and the meaning of the include parameter, plus the caveat 'if it wraps a showing'. However, it omits error behavior, auth requirements, and potential null results, making it only partially transparent.
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 two sentences long, with the first sentence providing the core purpose and return shape, and the second listing include options. No unnecessary words, and it is front-loaded with the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool with no output schema and no annotations, the description covers the essential aspects: purpose, return shape, and include details. It doesn't explain error responses or what happens when the meeting is not found, but given the simplicity and available schema, it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented. The description adds value by explaining the include associations and adding the nuance 'ViewingPropertyViewings (if it wraps a showing)' which goes beyond the schema's flat list of options. This extra context justifies a 4 over 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?
The description clearly states 'Get a single meeting by UUID' with the specific resource (meeting) and action (get). It also notes the meeting detail in the Activity/Showing Lifecycle and provides the return shape, which distinguishes it from sibling tools like list_meetings or search_meetings.
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 when you have a meeting UUID and need a single meeting's details. It doesn't explicitly mention when not to use it or point to alternatives, but the clear scope and sibling list provide sufficient context. Missing explicit exclusions keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_offerA
Get a single offer by UUID — offer detail view in the Transaction Lifecycle. Returns { data: { id, ... } }. Include: OpportunityOpportunities (the lead/buyer intent), PropertyProperties (the listing), CreatedByUsers, ModifiedByUsers. Use to trace the deal chain: Offer → Opportunity → Contact + Property → Contract.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Offer UUID | |
| include | No | Associations to expand. Options: CreatedByUsers, ModifiedByUsers, OpportunityOpportunities, PropertyProperties |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the transparency burden. It does so by disclosing the return format ('Returns { data: { id, ... } }') and the available include options (OpportunityOpportunities, PropertyProperties, etc.). It does not cover error handling or auth, but for a simple get operation this is adequate.
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 concise—two sentences total. It front-loads the core purpose, then adds include semantics and a use case. No wasted words, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-UUID tool with 2 parameters and no output schema, the description is complete: it states the purpose, return shape, include options, and the transactional context (deal chain). No critical information 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?
The schema has 100% coverage, so baseline is 3. The description adds meaningful semantics to the 'include' parameter by explaining what each option represents (e.g., 'OpportunityOpportunities (the lead/buyer intent), PropertyProperties (the listing)'), going beyond the schema's list of options.
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 starts with 'Get a single offer by UUID' which is a specific verb+resource combination. It also clarifies it as the 'offer detail view in the Transaction Lifecycle', distinguishing it from list/search siblings like qobrix_list_offers and qobrix_search_offers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: 'Use to trace the deal chain: Offer → Opportunity → Contact + Property → Contract.' This explains a primary use case without explicitly stating when not to use or naming alternatives, but it strongly implies a detail-view role compared to broader list/search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_opportunityA
Get a single lead/opportunity by UUID — drill into a pipeline deal in the Sales Pipeline workflow. Returns { data: { id, ref, status, enquiry_type, contact_name, agent, ... } }. RESO mapping: status 'new' = Lead, 'open' = Active/SQL, 'won' = Closed Won, 'closed_lost' = Lost. Verified include: ContactNameContacts (the person), Properties (linked listings), AgentAgents (assigned broker, RESO ListAgent), PropertyTypes, ClosedLostReason, User, OwnerUsers. Canonical deal drill-down pattern: 1. Get the lead with include=['ContactNameContacts','Properties','AgentAgents'] 2. Check showing history: qobrix_list_viewings (search by related property) 3. Check offers: qobrix_search_offers for this lead 4. Check activity: search Tasks, Calls, Meetings linked to this opportunity FK: contact_name → Contacts, agent → Agents, owner → Users.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Opportunity/Lead UUID | |
| include | No | Associations to expand. Verified options: ContactNameContacts (contact details), Properties (linked properties), AgentAgents (assigned agent), PropertyTypes, ClosedLostReason, User, OwnerUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully handles transparency. It discloses the return structure, RESO status mapping, verified include options, and FK relationships. This goes well beyond a simple 'get by ID' and gives the agent deep insight into tool behavior.
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 long but well-structured: core purpose, return shape, mapping, include options, and workflow. Every sentence contributes value, and the front-loaded first sentence states the main action. A slight deduction for density, but it remains focused.
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 single-getter with no output schema, the description is remarkably complete. It covers the return value shape, status semantics, include behavior, and integration with the broader workflow. This fully compensates for the missing output schema and meets the needs of an agent selecting and invoking the 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?
Although schema coverage is 100%, the description adds significant meaning to the 'include' parameter by listing verified options and recommending a canonical include pattern. It also explains the meaning of 'id' as UUID and provides contextual mapping for status values, enriching the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a single-record getter ('Get a single lead/opportunity by UUID') and distinguishes it from list/search siblings by focusing on individual deal drill-down. It also names the resource type explicitly, making its purpose 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?
Provides explicit context on when to use this tool: to drill into a pipeline deal as part of a canonical workflow. It names alternative/complementary tools (qobrix_list_viewings, qobrix_search_offers) and gives a step-by-step pattern, which is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_projectA
Get a single project by UUID — development detail view for off-plan/new-build listings. Returns { data: { id, ... } }. Verified include: Agents, Developer, Translations, LocationLocations, Assignee, Recommended, Favorites. To see project units: qobrix_search_properties with project == ''. To see project media: qobrix_list_media with related_model='Projects' and related_id=.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Project UUID | |
| include | No | Associations to expand. Verified options: Agents, Developer, Translations, LocationLocations, Assignee, Recommended, Favorites |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the return shape ('Returns { data: { id, ... } }') and lists verified include options, which is useful behavioral context. However, it does not explicitly state read-only safety, error behavior, or permission requirements, though these are minimally expected for a 'get' operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences. The first sentence states the core purpose and return shape, the second lists verified includes, and the third provides cross-tool references. Every sentence earns its place with no redundant or filler content.
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 moderate complexity (single resource, two parameters) and no output schema, the description provides essential context: purpose, return shape, includes, and related tools. It lacks error/not-found behavior and authentication notes, but these are not critical for a getter tool and the description is otherwise thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes both parameters (id and include) with clear descriptions, giving high coverage. The description adds value by confirming the verified include options (Agents, Developer, etc.) and providing usage patterns like `project == '<uuid>'` and `related_model='Projects'`, which clarifies how parameters relate to other tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get a single project by UUID — development detail view for off-plan/new-build listings', which uses a specific verb and resource and clearly distinguishes it from sibling tools like qobrix_list_projects (list) and qobrix_get_property (different resource). The phrase 'development detail view' adds domain-specific context, making the purpose 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 explicitly states when to use this tool ('Get a single project by UUID') and directs users to alternatives for related data: 'To see project units: qobrix_search_properties with project == '<uuid>'' and 'To see project media: qobrix_list_media with related_model=''Projects'' and related_id=<uuid>'. This provides clear usage guidance and differentiates from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_project_coordinatesA
Get lat/lng coordinates for projects, useful for map display. Optionally filter with a search expression.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It conveys that the tool is a read operation ('Get') and mentions optional filtering, but it does not disclose whether the response contains multiple projects, pagination behavior, or any other side effects. It is not misleading, but it lacks depth.
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 two short, focused sentences. The main action is front-loaded, and each clause adds value: specifying the coordinates and their use case, followed by the optional filter capability. No waste.
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 the simple tool with one optional parameter and no output schema, the description adequately states the purpose and filter option. However, it does not explain the return format or behavior when no filter is provided (e.g., returns all projects). The schema covers search syntax, but the description leaves minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100% for the only parameter 'search', providing comprehensive details on the DSL. The tool description adds minimal value by noting the filter is optional, which is already implied by zero required parameters. Baseline of 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?
The description clearly states it gets lat/lng coordinates for projects, with a specific verb and resource. It distinguishes itself from siblings like qobrix_get_property_coordinates by explicitly targeting projects, and from qobrix_get_project by focusing on coordinates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a use case ('useful for map display') and mentions optional filtering, but it does not explicitly state when to use this tool versus alternatives such as qobrix_get_property_coordinates or qobrix_search_projects. No exclusions or alternative tool names are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_properties_by_leadA
Get properties explicitly linked to a lead — the 'demand-side view' in the Sales Pipeline. Shows which properties a lead/opportunity has been matched to or expressed interest in. The id parameter is the Opportunity UUID (not the property UUID). In the canonical buyer journey: after Qualification, use this to review Solution/Viewing candidates. Alternative: qobrix_get_opportunity with include=['Properties'] for inline expansion. Complement with qobrix_get_leads_by_property for the reverse (supply-side) match.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Lead/Opportunity UUID | |
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It adds meaningful context: the demand-side scope, explicit linking, and that the parameter is the Opportunity UUID (not property UUID). While it doesn't describe return format or rate limits, it provides substantive behavioral context for a read operation, going beyond a bare statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core purpose, followed by scope clarification, usage context, and alternatives. Every sentence earns its place with no redundancy or 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?
Given the tool's moderate complexity, no output schema, and no annotations, the description is thorough: it covers purpose, id semantics, usage timing, and alternatives. It doesn't detail return structure, but for a list-like read tool, the description provides sufficient context for an agent to select and invoke 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 baseline is 3. The description adds crucial meaning beyond the schema by clarifying that 'id' is the Opportunity UUID (not a property UUID) and framing its use in the buyer journey. This extra semantic value justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it 'get properties explicitly linked to a lead' with a specific resource and scope. It further differentiates by labeling it the 'demand-side view' and clarifies that the id is an Opportunity UUID, not a property UUID, which distinguishes it from similarly named 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?
Provides explicit when-to-use guidance ('after Qualification, use this to review Solution/Viewing candidates') and names concrete alternatives: qobrix_get_opportunity with include=['Properties'] and qobrix_get_leads_by_property for the reverse match. This meets the highest bar for usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_propertyA
Get a single property by UUID — the listing detail view in the Listing Lifecycle. Returns { data: { id, name, status, ... } }. RESO StandardStatus: 'available' = Active, 'reserved' = Pending, 'sold' = Closed, 'withdrawn' = Withdrawn. Use include[] to expand related entities inline: Verified: Agents, PropertyTypes, PropertySubtypes, PropertyViewings, Opportunities, Translations, SalespersonUsers, CreatedByUsers, LocationLocations, AgentAgents, SellerContacts, ProjectProjects. Workflow tips: include=['PropertyViewings'] → see showing history (Showing Lifecycle). include=['Opportunities'] → see interested leads (Sales Pipeline). include=['AgentAgents'] → listing agent (RESO ListAgent). include=['SellerContacts'] → seller/owner (RESO OwnerMember). FK fields: agent → Agents, seller → Contacts, project → Projects, salesperson → Users.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Property UUID | |
| expand | No | Expand FK references into full nested objects. Default false (FKs stay as UUID strings). Prefer include[] for surgical expansion of specific associations. | |
| include | No | Associations to expand. Verified options: PropertyTypes, PropertySubtypes, Agents, Opportunities, PropertyViewings, Translations, SalespersonUsers, CreatedByUsers, LocationLocations, AgentAgents, SellerContacts, ProjectProjects |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by explaining the return shape, mapping RESO StandardStatus values, describing include[] expansion behavior, and listing FK field targets. The verb 'Get' implies a read-only operation, and the description adds substantive behavioral context beyond simply fetching an item.
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 long but dense and well-structured, starting with the primary purpose, then return format, status mapping, include options, workflow tips, and FK fields. Every section carries useful information, but it could be slightly trimmed without losing value. The use of sections and examples makes it navigable despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (multiple include[] options, FK fields, and no output schema), the description is remarkably complete. It covers return shape, status enum meanings, expansion capabilities, and practical workflow mappings. There is no output schema, so the description correctly takes on the responsibility of explaining the data structure and usage patterns.
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?
Although the schema already provides 100% coverage with descriptions for all three parameters, the description adds significant meaning beyond the schema. It enumerates verified include[] options, provides workflow tips for specific includes, and explains the relationship between expand and include (e.g., 'Prefer include[] for surgical expansion'). It also maps FK fields to their target resources, which is not present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get a single property by UUID', a specific verb+resource combination that clearly states the tool's core function. It distinguishes itself from sibling tools like list/search by positioning it as 'the listing detail view in the Listing Lifecycle', making the use case 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 provides clear context for when to use this tool (when you have a UUID and need a single property detail view) and includes workflow tips for specific include[] expansions that guide usage for showing history, interested leads, etc. However, it does not explicitly name alternative tools (e.g., qobrix_list_properties) or state when not to use this tool, so it falls slightly short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_property_coordinatesA
Get lat/lng coordinates for properties, useful for map display. Optionally filter with a search expression to get coordinates for a subset. Returns array of { id, coordinates } objects.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It explicitly discloses the return format (array of { id, coordinates } objects) and the optional filtering behavior. While it doesn't discuss edge cases like missing coordinates or errors, the core behavioral traits are transparent for a read-only getter.
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 three short, purposeful sentences: states the main action, the optional filtering capability, and the return shape. No redundancy or filler—every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one optional parameter and no output schema. The description covers purpose, filtering, and return type. It does not mention what happens when no properties match or if coordinates are missing, but these are minor edge cases for such a focused tool. Overall, it is complete enough for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'search', has 100% schema description coverage with detailed DSL grammar and examples. The tool description adds minimal semantic value beyond stating that filtering is optional and returns a subset. With high schema coverage, the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves lat/lng coordinates for properties, which is a specific verb-resource combination. It distinguishes itself from sibling tools like qobrix_get_property (full property details) and qobrix_get_project_coordinates (coordinates for projects) by explicitly scoping to properties.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: for map display, and optionally with a search expression for a subset. It does not explicitly name alternatives or state when not to use it, but the intended use case is evident. A clear context without exclusions aligns with a score of 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_schemaA
Get the full field schema for any CRM resource — the Schema Discovery tool. CALL THIS FIRST when unsure about field names for search, fields[], or sort. Returns every field with name, type, label, and validation rules (RESO Data Dictionary equivalent). Resources (case-sensitive): Properties, Contacts, Opportunities, Agents, Tasks, PropertyViewings, Projects, Offers, Contracts, Calls, Meetings, EmailMessages, Media, PropertyTypes, PropertySubtypes, PropertyFeatures, Locations. Canonical use: before building search expressions for any workflow (Listing, Sales Pipeline, Follow-up), call this to discover the correct field names. The schema is the source of truth. Pair with qobrix_get_field_options to see allowed enum values for dropdown fields. For search grammar, prefer qobrix_search_dsl_help.
| Name | Required | Description | Default |
|---|---|---|---|
| resource | Yes | Resource name (case-sensitive, PascalCase). Valid values: Properties, Contacts, Opportunities, Agents, Tasks, PropertyViewings, Projects, Offers, Contracts, Calls, Meetings, EmailMessages, Media, PropertyTypes, PropertySubtypes, PropertyFeatures, Locations. Returns every field with name, type, label, and validation rules. Use this to discover field names before building search expressions or fields[] arrays. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool returns every field with name, type, label, and validation rules, and notes that resources are case-sensitive. It implicitly indicates a read-only schema operation without side effects, which is sufficient for this tool type, though it doesn't explicitly say 'read-only' or discuss auth/rate limits.
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 well-structured and front-loaded, opening with the main purpose and a strong 'CALL THIS FIRST' directive. It includes a useful resource list and related-tool pointers. A minor redundancy exists between 'CALL THIS FIRST' and 'Canonical use,' but overall every sentence adds value, and length is appropriate for the role.
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?
Despite having no output schema, the description explains the return format: 'Returns every field with name, type, label, and validation rules.' It also covers the full context of when and why to use the tool, lists all valid resource values, and references complementary tools. This is complete for a schema-discovery operation with only one parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage, including valid values and usage context for the 'resource' parameter. The description repeats much of this but adds marginal context such as 'source of truth' and 'canonical use.' Per the rubric, when schema coverage is high, a baseline of 3 is appropriate, and the description doesn't add significant parameter-level meaning 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?
The description clearly states the tool's purpose: 'Get the full field schema for any CRM resource' and lists the exact resource types. It also distinguishes itself from siblings by explicitly mentioning qobrix_get_field_options (enum values) and qobrix_search_dsl_help (search grammar), making its role unique.
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?
Guidance is explicit: 'CALL THIS FIRST when unsure about field names for search, fields[], or sort.' It defines the canonical use case and names when to prefer alternative tools ('Pair with qobrix_get_field_options...', 'For search grammar, prefer qobrix_search_dsl_help'). This is perfect 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.
qobrix_get_taskA
Get a single task by UUID — task detail for pipeline management and follow-up audit. Returns { data: { id, ... } }. Include: AssignedToUsers (who), ContactContacts (for whom), Properties (which listing), RelatedOpportunityOpportunities (which deal), RelatedAgentAgents, TaskStatus, TaskTypes.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Task UUID | |
| include | No | Associations to expand. Options: TaskStatus, TaskTypes, Properties, AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, CreatedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return shape ('{ data: { id, ... } }') and explains the meaning of several include options, which is valuable behavioral context. The verb 'Get' implies a read operation, though it doesn't discuss error handling or auth requirements. This is strong for a simple get tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose, and efficiently lists include options with parenthetical clarifications. No redundant or vague content.
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 the tool's simplicity (2 params, no output schema), the description covers the essential details: purpose, return envelope, and include associations. It could mention potential absence behavior or typical use cases, but it is reasonably 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?
The schema already provides 100% coverage for both parameters, so baseline is 3. The description adds beyond that by parenthetically explaining the semantics of include options (e.g., 'AssignedToUsers (who)'), which enriches understanding. It doesn't explain every option (e.g., CreatedByUsers) but adds meaningful 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?
The description clearly states 'Get a single task by UUID', a specific verb+resource combination. It also provides context ('task detail for pipeline management and follow-up audit') and implicitly distinguishes from sibling list/search tools which return multiple tasks.
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 when a specific task UUID is known, and mentions pipeline management and follow-up audit as use cases. However, it does not explicitly name alternatives (e.g., qobrix_list_tasks) or state when-not-to-use, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_get_viewingA
Get a single viewing by UUID — the showing detail view in the Showing Lifecycle. Returns { data: { id, ... } }. Verified include: PropertyViewingViewing. After retrieving, use the property and contact FKs to trace back to the listing and lead.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Property Viewing UUID | |
| include | No | Associations to expand. Verified options: PropertyViewingViewing |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the return shape ('Returns { data: { id, ... } }'), indicates a verified include option, and hints that the response contains property and contact FKs for tracing back to listing and lead. This is valuable, though it stops short of covering error handling or permissions.
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 compact and front-loaded with the main purpose. Each sentence adds distinct information: purpose (Get a single viewing), return format, verified include, and a follow-up workflow hint. There is no redundancy or filler, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ID tool, the description is complete: it states what it does, the response envelope, the valid include option, and a concrete next step. The lack of an output schema is mitigated by the explicit mention of the return shape, and the parameter schema covers the input details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage for both parameters (id as 'Property Viewing UUID' and include as 'Verified options: PropertyViewingViewing'). The description mostly repeats the include option and adds no deeper meaning beyond the schema, so it contributes minimal additional insight.
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 'Get a single viewing by UUID' with a specific verb and resource, and the phrase 'the showing detail view in the Showing Lifecycle' adds context. It is distinct from the sibling tools like list_viewings and search_viewings because it targets a single view by identifier.
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 when you have a specific viewing UUID, and the reference to the Showing Lifecycle provides context. However, it does not explicitly mention alternatives or exclusion criteria (e.g., when to use list_viewings or search_viewings instead), so it falls short of an explicit 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_agentsB
List agents (RESO Member resource) — real estate brokers managing listings and leads. Agents are the central actor across all workflows: they manage the Listing Lifecycle, drive the Sales Pipeline, and own Follow-up activities. Referenced by property.agent and opportunity.agent FKs. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Verified include: PrimaryContactContacts, User, Brands, AgencyAgents (parent agency). Workflow: to see an agent's full portfolio, search Properties and Opportunities by agent == ''.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: PrimaryContactContacts, User, Brands, AgencyAgents |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses the return shape ({ data, pagination }) and verified include associations, which is useful. However, it does not state if any default filters apply, nor any permissions or side effects. This is moderate transparency for a read-only list tool.
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 'List agents' and each sentence serves a purpose. It includes useful context about agents' roles, though the workflow sentence is somewhat tangential. It is not overly verbose.
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?
The description provides the resource definition, return shape, include options, and a workflow tip. It lacks explicit usage guidance relative to qobrix_search_agents and does not describe default behavior, but given the detailed schema and no output schema, it is fairly complete for a list 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 value by listing the verified include options (PrimaryContactContacts, User, Brands, AgencyAgents) and mentioning agent FK references, which enriches the include and search parameter semantics.
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 it lists agents (RESO Member resource) with a specific verb and resource. It defines what agents are, but does not explicitly differentiate from the sibling qobrix_search_agents, which also deals with agents.
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?
No explicit guidance on when to use this tool versus alternatives like qobrix_search_agents. The description provides domain context and a follow-up workflow, but no direct when-to-use or when-not-to-use recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_callsA
List call records — part of the Activity Tracking / Follow-up workflow. Calls are touchpoints in the Lead-Contact Lifecycle; zero tolerance on missed follow-ups. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Include: ContactContacts (who was called), AssignedToUsers (who made the call), RelatedOpportunityOpportunities (which lead), RelatedAgentAgents, RelatedContractContracts. Workflow: use with qobrix_list_meetings and qobrix_list_email_messages for a complete activity timeline. To audit a contact's engagement: search calls, meetings, and emails by their contact UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Options: AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, RelatedContractContracts, CreatedByUsers, ModifiedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of disclosure. It describes the return shape ({ data, pagination }), the expandable associations, and the domain context. While it doesn't explicitly state read-only or discuss rate limits/auth, the list verb and return-pagination detail make the behavior reasonably transparent for a read-only list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense and well-structured: it states purpose, return shape, includable associations, and workflow in a compact block. The phrase 'zero tolerance on missed follow-ups' is slightly rhetorical but reinforces the operational context. No significant redundancy with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description appropriately includes the pagination return shape. It also explains the tool's role in the activity timeline and how to audit contacts. Given that all parameters are already documented thoroughly in the input schema, this description sufficiently completes the picture for an agent to invoke the tool 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?
The input schema already documents all five parameters with detailed descriptions (100% coverage), so the description doesn't need to add parameter-level semantics. The tool description adds use-case context and mentions included associations, but those are also listed in the schema's include parameter. This meets the baseline but doesn't exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List call records'—a specific verb and resource—and immediately frames it within the 'Activity Tracking / Follow-up workflow'. It clearly distinguishes itself from sibling tools like qobrix_list_meetings and qobrix_list_email_messages by focusing on calls, and from qobrix_get_call by being the list operation.
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?
Explicit workflow guidance is provided: 'use with qobrix_list_meetings and qobrix_list_email_messages for a complete activity timeline' and 'To audit a contact's engagement: search calls, meetings, and emails by their contact UUID.' This tells the agent when to use this tool and names alternatives/associated tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_contactsA
List contacts (RESO Contacts resource) from Qobrix CRM — the people/companies in the CRM. Core to the Lead-Contact Lifecycle: a Contact becomes a Lead when an Opportunity is created for them. RESO ContactType mapping: use opportunity.enquiry_type and property.seller FK to determine Buyer/Seller/Tenant role. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Key fields (42 total): first_name, last_name, name, email, phone, city, country, assigned_to (UUID → user, RESO OwnerMember), role, is_company, nationality, preferred_language, preferred_contact_method, consent fields, created, modified. Cross-references: property.seller → Contact UUID, opportunity.contact_name → Contact UUID, task.contact → Contact UUID, call/meeting.contact → Contact UUID. Workflow: to see a contact's full journey, search Opportunities, Tasks, Calls, and Meetings by their UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: AssignedToUsers, User, Language, Organizations | |
| segment | No | Filter contacts by segment |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given no annotations, the description discloses the response shape ({ data, pagination }) and key fields, plus cross-references to other entities. It does not mention side effects, auth, or rate limits, but as a list operation these are less critical. The description adds context beyond the schema without contradicting anything.
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 longer than typical but each section adds value: purpose, lifecycle, response format, key fields, cross-references, and workflow suggestion. It is front-loaded with the core purpose and structured logically, though could be slightly trimmed.
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?
Considering there is no output schema, the description compensates by explaining the response format, the pagination object, key fields, and cross-references. It covers the tool's role in the broader CRM model. It doesn't mention all 42 fields or exactly which fields are returned by default, but the schema and description together provide sufficient context for a list 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 description coverage is 100%, and the parameter descriptions are exceptionally detailed (especially search). The description itself does not add additional parameter semantics beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List contacts (RESO Contacts resource) from Qobrix CRM' with a specific verb and resource. It also provides meaningful context about the Contact-to-Lead lifecycle. However, it does not explicitly distinguish itself from sibling tools like qobrix_search_contacts, which is a minor gap.
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 context about when this tool fits in the workflow ('Core to the Lead-Contact Lifecycle') and suggests searching other resources for a full journey. However, it does not explicitly state when to choose this over qobrix_search_contacts or list variants, so guidance 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.
qobrix_list_contractsA
List contracts (RESO TransactionManagement close) — the 'Deal Signing / Payment / Close' stage of the Sales Pipeline. A Contract finalizes the transaction: it links the Property, buyer/seller Contacts, and the Opportunity. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Verified include: Contacts, PropertyIdProperties, OpportunityIdOpportunities, PaymentInstallments (payment schedule), ContractParties (all signatories), CreatedByUsers. Canonical chain: Offer → Contract → Payment → Close. After contract signing, the property status moves to 'reserved' (Pending), then 'sold' (Closed).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: Contacts, PaymentInstallments, ContractParties, PropertyIdProperties, OpportunityIdOpportunities, CreatedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, but the description provides valuable behavioral context: it discloses the return shape ({ data, pagination }), lists verified includes, and explains the downstream effect on property status ('reserved' then 'sold'). It does not explicitly state read-only behavior, but the listing nature implies it.
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 moderately long but front-loaded with the core action. Every section (stage, return shape, includes, canonical chain, status change) contributes value, though it could be slightly more concise. No fluff.
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 providing the return shape and pagination keys. It also adds rich domain context (pipeline stage, relationships, property status flow) that helps the agent understand the tool's role among many sibling tools. Minor gap: no explicit alternative tool guidance.
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 schema already documents all 5 parameters. The tool description adds no new parameter-specific semantics; it merely repeats the verified include options that are already in the schema's include description. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'List contracts' and specifies the business stage (RESO TransactionManagement close, Deal Signing/Payment/Close). It defines what a contract is and its relationships, distinguishing it from other list/get/search tools by contextualizing it within the sales pipeline.
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 when dealing with contracts in the sales pipeline and mentions the canonical chain (Offer → Contract → Payment → Close), but it does not explicitly state when to use this list tool versus qobrix_search_contracts or qobrix_get_contract. No alternatives or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_email_messagesA
List email messages — part of the Activity Tracking / Follow-up workflow and marketing campaigns. Emails are touchpoints in the Lead-Contact Lifecycle for nurturing and communication. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Include: ContactContacts (recipient/sender), Properties (listing references), Campaign (marketing campaign), RelatedOpportunityOpportunities, RelatedAgentAgents. Use with qobrix_list_calls and qobrix_list_meetings for a complete contact engagement timeline.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Options: Properties, CreatedByUsers, ModifiedByUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, RelatedContractContracts, OwnerUsers, Agent, Contract, Opportunity, Campaign |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the return format ('Returns { data: [...], pagination: ... }') and the expandable associations (Include: ...), which is genuinely useful. However, it doesn't mention read-only status, default ordering, pagination behavior beyond the structure, or any potential error conditions. For a list operation, this is adequate but not rich.
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, each earning its place: the first states the action and workflow context, the second specifies the return shape, and the third explains the include options and companions. No filler, no repetition of schema information, and the most important information is front-loaded.
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 the rich schema (all params documented) and the absence of an output schema, the description provides enough context for an agent to decide when to invoke it and what to expect in return. It explains the use case (activity tracking, campaigns, contact timeline) and the meaningful relationships in the include field. It could mention parent/child scoping (e.g., whether it's for a single contact or all contacts), but the description is sufficiently complete for a list tool in this sibling ecosystem.
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 five parameters in detail. The description adds some semantic context by explaining what several include associations mean (e.g., ContactContacts = recipient/sender, Properties = listing references), but this is marginal value beyond the schema's already-thorough parameter descriptions. The baseline 3 applies because the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List email messages' — a specific verb and resource — and immediately distinguishes this tool from siblings like qobrix_list_calls and qobrix_list_meetings by framing it within the Activity Tracking / Follow-up workflow. It clearly positions email messages as touchpoints in the Lead-Contact Lifecycle, making the tool's purpose unambiguous and differentiating it from other list tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear situational context: 'part of the Activity Tracking / Follow-up workflow and marketing campaigns' and explicitly recommends pairing it with qobrix_list_calls and qobrix_list_meetings for a complete engagement timeline. It doesn't explicitly state when not to use it or mention alternatives like qobrix_get_email_message, but the companion guidance is a strong usage signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_mediaA
List media items (RESO Media resource) — photos, documents, floor plans attached to any entity. Core to the Media Lifecycle: every listing needs photos and floor plans; projects need brochures. NOTE: Returns { data: [...] } WITHOUT pagination metadata (unlike other endpoints). Must provide BOTH related_model AND related_id together, or omit both for global media. Listing media: related_model='Properties', related_id=''. Contact documents: related_model='Contacts', related_id=''. Project brochures: related_model='Projects', related_id=''. Alternative: qobrix_list_properties with media=true (default) embeds media in property responses. Each item has: id, media_type, reference_id, display_order, category, created.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| related_id | No | UUID of the related entity. Must be used together with related_model. Example: related_model='Properties', related_id='<property-uuid>' to get all media for a property. | |
| related_model | No | Filter by related entity type. Values: 'Properties', 'Contacts', 'Projects', 'Agents'. Must be used together with related_id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the non-standard response shape without pagination metadata, the required parameter pairing, and the exact list of returned fields. This is rich behavioral context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: from the resource definition to lifecycle context, pagination warning, parameter pairing, examples, alternative tool, and return fields. It is front-loaded with the primary purpose and well-organized.
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 fully documents return values and response shape, covers usage contexts for multiple entity types, and provides a cross-reference to a sibling tool. It is a complete, self-contained reference for the media listing operation.
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%, but the description adds meaning by explaining the relationship between related_model and related_id, offering concrete example values for each entity type, and introducing the 'global media' mode when both are omitted. This goes far beyond the schema's field-level descriptions.
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 verb+resource: 'List media items (RESO Media resource)' and enumerates content types (photos, documents, floor plans). It distinguishes itself from siblings like qobrix_get_media and qobrix_list_properties by explaining its role in the Media Lifecycle and cross-referencing 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?
It provides concrete usage scenarios (properties, contacts, projects) and explicitly names qobrix_list_properties as an alternative for embedding media. It also explains the critical constraint of pairing related_model and related_id, or omitting both.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_meetingsA
List meetings — bridges the Activity Tracking and Showing Lifecycle workflows. Meetings can wrap property viewings (RESO Showing ↔ Meeting). Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Include: ContactContacts, ViewingPropertyViewings (linked showings), AssignedToUsers, RelatedOpportunityOpportunities, RelatedAgentAgents, CreatedByUsers, ModifiedByUsers. Workflow: include=['ViewingPropertyViewings'] to see which meetings are property showings vs general meetings. The first meeting/showing is the canonical trigger that moves a lead from follow-up to active sales.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Options: AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, ViewingPropertyViewings, CreatedByUsers, ModifiedByUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the return structure ({ data, pagination }), the available include associations, and a specific workflow. However, it does not explicitly state read-only semantics, permissions, or rate limits. For a list operation, the 'List' verb and return details provide reasonable transparency, but not exhaustive.
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 four sentences long, front-loaded with the core purpose. Each sentence provides distinct information: purpose, return shape, include options, and workflow. It is slightly dense but well-organized, with no filler or redundancy. The structure flows logically from general to specific, making it easy for an agent to parse key details quickly.
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 the absence of an output schema, the description appropriately explains the paginated return shape. It also addresses the key ambiguity around meetings vs viewings, which is essential for correct tool selection. The description does not mention potential error conditions, sorting nuances, or edge cases, but for a list tool with a rich parameter schema, this level of context is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all 5 parameters with 100% description coverage, establishing a baseline of 3. The tool description adds value by explaining the include parameter's role in distinguishing meetings from viewings and suggesting a concrete workflow. While the schema already lists the include options, the description provides the meaningful 'why' behind using them, and the emphasis on the first meeting/showing as a lead trigger adds context 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?
The description clearly states 'List meetings' with a specific verb and resource, and further distinguishes it from sibling tools like qobrix_list_viewings by explaining that meetings can wrap property viewings via RESO Showing ↔ Meeting. It also provides domain context (bridges Activity Tracking and Showing Lifecycle workflows), making its purpose 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 gives clear usage context: it explains the relationship between meetings and viewings and recommends the include=['ViewingPropertyViewings'] workflow to differentiate property showings from general meetings. It also mentions the canonical trigger role, but does not explicitly contrast with alternative tools (e.g., 'use this instead of list_viewings when...'), so some inference is left to the user.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_offersA
List offers (RESO TransactionManagement) — the 'Decision Making' stage of the Sales Pipeline. An Offer formalizes a buyer's intent: it links an Opportunity (the lead) to a Property (the listing) with a price. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Include: OpportunityOpportunities (the lead), PropertyProperties (the listing), CreatedByUsers, ModifiedByUsers. Canonical transaction chain: Lead → Viewing → Offer → Contract → Close. After an offer is accepted, the next step is Contract creation (qobrix_list_contracts).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Options: CreatedByUsers, ModifiedByUsers, OpportunityOpportunities, PropertyProperties |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral disclosure burden. It provides the return shape ({ data, pagination }) and include options, which is useful, but it does not explicitly state that the operation is read-only, mention authentication or scoping, or disclose side effects, leaving some transparency gaps.
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 compact and front-loaded, with each sentence adding business context, return shape, or pipeline positioning. It does repeat the include options already present in the schema, but the extra domain explanation justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the domain complexity and lack of output schema, the description covers the essential context: what an offer is, the transaction chain, return format, and the next step. It does not exhaustively cover behavior like pagination defaults or list-vs-search boundaries, but the schema fills many of those gaps, making it largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All five parameters are fully described in the input schema (100% coverage), so little extra parameter interpretation is necessary. The description's mention of include associations adds a small semantic layer, but the schema already documents each field thoroughly, matching the baseline.
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 starts with 'List offers (RESO TransactionManagement)' and explains the domain object as linking an Opportunity to a Property with a price. This clearly identifies the resource, the action, and the pipeline stage, distinguishing it from sibling tools like qobrix_get_offer or qobrix_search_offers.
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 places the tool in the canonical chain 'Lead → Viewing → Offer → Contract → Close' and explicitly mentions qobrix_list_contracts as the next step after acceptance. However, it does not contrast with qobrix_search_offers or state conditions for list-vs-search, limiting the exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_opportunitiesA
List opportunities/leads from Qobrix CRM — the central entity of the Sales Pipeline and Lead-Contact Lifecycle. In Qobrix, leads ARE opportunities. Each represents a buyer/renter/investor enquiry. RESO funnel mapping: 'new' = MQL/Lead, 'open' = SQL/Active, 'won' = Closed Won, 'closed_lost' = Lost. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. IMPORTANT: Avoid include=['Locations']. Safe verified includes: ContactNameContacts, Properties, AgentAgents, PropertyTypes, ClosedLostReason, User, OwnerUsers. Key fields (77 total): status, enquiry_type (buy/rent/invest), buy_rent, contact_name (UUID → Contact), agent (UUID → Agent), owner (UUID → user), source, area_of_interest, bedrooms_from/to, price ranges, next_follow_up_date, enquiry_date. Workflow patterns: Pipeline overview: group by status to see funnel distribution. Overdue follow-ups: status == "open" and next_follow_up_date <= NOW. New leads this week: created >= THIS_WEEK and status == "new". Two-way matching: demand→supply via qobrix_search_properties with lead criteria; supply→demand via this tool with boost against a listing (or native qobrix_get_leads_by_property).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. IMPORTANT: avoid 'Locations' unless you also select the location FK via fields[]. Verified safe options: ContactNameContacts, Properties, AgentAgents, PropertyTypes, ClosedLostReason, User, OwnerUsers |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries behavioral disclosure. It reveals the return shape ({ data, pagination }), flags the problematic 'Locations' include, lists verified safe includes, maps status enums to standard funnel stages, and explains the boost behavior in the page parameter. This goes far beyond what annotations would provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized with clear segments (domain, funnel mapping, return format, includes warning, key fields, workflows). It front-loads the core purpose and uses labels like 'IMPORTANT' and 'Safe verified includes' to aid skimming. Slightly long but every section earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description is remarkably complete: it documents return structure, field semantics, common workflow patterns, search syntax references, and include restrictions. It equips an agent to invoke the tool correctly across multiple use cases without needing external documentation.
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%, and every parameter has a detailed description with examples (sort, search, fields, include). The top-level description adds contextual workflow examples but does not materially extend the schema's parameter-level semantics. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'List opportunities/leads from Qobrix CRM' and adds crucial domain context ('leads ARE opportunities'). It distinguishes the entity from contacts, properties, etc., and the title itself aligns with the list sibling group. The RESO funnel mapping further clarifies the semantic scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit workflow patterns (pipeline overview, overdue follow-ups, new leads this week) and names alternative tools: use qobrix_search_properties for demand→supply matching, qobrix_get_leads_by_property for supply→demand, and qobrix_search_dsl_help for search syntax. It also warns about unsafe include values, giving clear usage guidance beyond a generic 'when to use'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_projectsA
List projects (property developments/complexes) — RESO Project equivalent for off-plan and new-build listings. Projects group multiple property units under one development, relevant in the Listing Lifecycle for new-builds. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Properties reference their project via the 'project' FK. Verified include: Agents, Developer, Translations, LocationLocations, Assignee, Recommended, Favorites. Workflow: to see units in a project, qobrix_search_properties with project == ''.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: Agents, Developer, Translations, LocationLocations, Assignee, Recommended, Favorites |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It does disclose the return shape: 'Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }' and a relational detail: 'Properties reference their project via the "project" FK.' However, it does not mention rate limits, permissions, or error behavior, though for a read-only list operation these may be less critical.
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 well-structured and front-loaded with purpose. Each sentence adds context, though the 'Verified include' line is somewhat redundant with the schema's include description. Overall appropriate length for the tool's complexity.
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?
Considering the tool has 6 parameters, no output schema, and no annotations, the description is reasonably complete. It provides the return shape, pagination, a key foreign-key relationship, and a workflow hint. Missing explicit read-only confirmation and edge-case behavior, but sufficient for an agent to select and invoke the tool 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 description coverage is 100%, so the baseline is 3. The description adds little beyond the schema; the 'Verified include' list repeats the include parameter's documented options. No new parameter semantics are introduced in the description.
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 verb and resource: 'List projects (property developments/complexes) — RESO Project equivalent for off-plan and new-build listings.' It distinguishes from singular get_project by being plural, but does not explicitly contrast with sibling qobrix_search_projects, which is a similar listing/search tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Some usage context is provided: 'relevant in the Listing Lifecycle for new-builds' and a workflow hint 'to see units in a project, qobrix_search_properties with project == "<uuid>"'. However, there is no explicit guidance on when to use list_projects vs search_projects, nor any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_propertiesA
List properties (RESO Property resource) from Qobrix CRM. Core tool for the Listing Lifecycle — use to browse active inventory, track status changes, or audit listings. Returns { data: [...], pagination: { count, current_page, has_next_page, has_prev_page, page_count, limit } }. RESO StandardStatus mapping: 'available' = Active, 'reserved' = Pending/Under Contract, 'sold' = Closed, 'withdrawn' = Withdrawn. Key fields (184 total): name, ref, status, sale_rent (for_sale/for_rent), property_type, property_subtype, city, country, list_selling_price_amount, list_rental_price_amount, bedrooms, bathrooms, covered_area_amount, plot_area_amount, agent (UUID → qobrix_get_agent), seller (UUID → qobrix_get_contact), project (UUID → qobrix_get_project), salesperson (UUID → user). Workflow recipes: Active inventory → search: status == "available" and sale_rent == "for_sale". Recent listings → sort: '-created'. Buyer-property match → prefer qobrix_search_properties with search + boost for free-language demand. Listing media → follow up with qobrix_list_media(related_model='Properties'). PAYLOAD DEFAULTS: expand=false and media=false — FKs come back as UUIDs and media is not inlined (set expand=true / media=true explicitly when full nested objects or media URLs are needed). Prefer include[] for surgical expansion of specific associations. Default limit 10, max 100.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| media | No | Include inline media (photos, floor plans, thumbnails) on each row. Default false. Each media-rich property can add 5-20 KB; only set true when the caller needs media URLs. For media alone use qobrix_list_media(related_model='Properties', related_id=<uuid>). | |
| expand | No | Expand FK references into full nested objects (developer, project, seller, location, etc.). Default false. With expand=false each FK is just a UUID string — much smaller payload. Prefer include[] for surgical expansion of specific associations. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: PropertyTypes, PropertySubtypes, Agents, Opportunities, PropertyViewings, Translations, SalespersonUsers, CreatedByUsers, ModifiedByUsers, LocationLocations, AgentAgents, SellerContacts, ProjectProjects |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description fully carries the burden. It discloses payload defaults (expand=false, media=false, default limit 10, max 100), explains that FKs come back as UUIDs and media is not inlined, and maps RESO statuses to internal values. This adds rich behavioral context beyond the schema and covers what an agent needs to know about the response behavior.
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 long but every section earns its place: purpose, return shape, status mapping, key fields, workflow recipes, payload defaults, and parameter hints are all organized and front-loaded. No fluff; only high-value information is present.
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 8 parameters, no output schema, and no annotations, the description is exceptionally complete. It covers return structure, field selection, status mapping, workflow recipes, and points to additional resources (qobrix_search_dsl_help, qobrix_get_schema) for deeper needs. It is a model of contextual completeness.
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 already covers 100% of parameters, but the description adds significant practical value: it provides search expression examples, sort syntax examples, include[] options, and guidance on when to set media/expand. It also explains the interaction between page and boost (though boost is not a parameter in this schema, the context is still useful). This goes far beyond the baseline schema descriptions.
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 'List properties (RESO Property resource) from Qobrix CRM' and specifies its role as the 'Core tool for the Listing Lifecycle'. It distinguishes from siblings by explicitly suggesting qobrix_search_properties for buyer-property match and qobrix_list_media for media, so the verb+resource+scope is specific and well-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use context: 'use to browse active inventory, track status changes, or audit listings'. Offers concrete workflow recipes (e.g., active inventory via search, recent listings via sort) and explicitly names alternatives (qobrix_search_properties for free-language demand, qobrix_list_media for media-only needs), giving clear exclusions and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_tasksA
List tasks — the operational backbone of all canonical workflows: Follow-up, Pipeline Management, and Listing Checklists. Tasks drive daily agent cadence: overdue follow-ups, listing prep, closing steps, payment tracking. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Include: AssignedToUsers (task owner), ContactContacts (related person), Properties (listing), RelatedOpportunityOpportunities (lead), RelatedAgentAgents, RelatedContractContracts, TaskStatus, TaskTypes, CreatedByUsers, ModifiedByUsers. Canonical patterns: My open tasks: search with assigned_to == CURRENT_USER and status != "completed". Overdue: search with due_date <= NOW and status == "pending". Tasks for a lead: search with related opportunity FK. Listing checklist: search tasks linked to a property UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Options: TaskStatus, TaskTypes, Properties, AssignedToUsers, ContactContacts, RelatedOpportunityOpportunities, RelatedAgentAgents, RelatedContractContracts, CreatedByUsers, ModifiedByUsers, ContractorContacts, RelatedActionPlanSteps |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the return envelope ({ data, pagination }), the expandable associations, and the canonical search patterns. It does not explicitly state read-only operation, but as a list tool, that is clear from context; it also doesn't mention auth or rate limits, but these are likely shared across the API.
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 lengthy but well-structured: purpose first, then return shape, includes, and canonical patterns. It front-loads the main verb. Some promotional phrasing ('operational backbone of all canonical workflows') could be trimmed, but the content is relevant and organized.
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?
There is no output schema, so the description compensates by spelling out the response shape and the list of includable associations. The canonical patterns cover the most likely agent scenarios. It is complete enough for a list tool with a rich 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?
The input schema already describes all five parameters with 100% coverage, including detailed grammar and defaults. The description adds canonical usage examples for the search parameter but does not explain any parameter semantics beyond what the schema provides. Per the guidelines, this is a 3 when schema coverage is high.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List tasks' and immediately frames it as the operational backbone of canonical workflows, making the verb and resource clear. However, it never distinguishes this tool from sibling qobrix_search_tasks, even though the search parameter overlaps with a search tool's job. The canonical patterns do clarify core use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides four canonical patterns (My open tasks, Overdue, Tasks for a lead, Listing checklist) with concrete search expressions, showing exactly when to reach for this tool. It does not explicitly state when not to use it or name alternatives, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_list_viewingsA
List property viewings (RESO ShowingAppointment) — the Showing/Viewing Lifecycle tool. Viewings are the pivot between Follow-up and Active Sales: the first viewing marks a lead as actively engaged. Returns { data: [...], pagination: { count, current_page, has_next_page, ... } }. Each viewing links a property, a contact, and an agent/creator. Verified include: PropertyViewingViewing. Workflow patterns: This week's viewings: search with created >= THIS_WEEK. Property's showing history: qobrix_get_property with include=['PropertyViewings']. Meetings linked to viewings: qobrix_list_meetings with include=['ViewingPropertyViewings']. After a showing, the next pipeline step is Offer → Contract → Close.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Associations to expand. Verified options: PropertyViewingViewing |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It discloses the return shape with pagination details, confirms only 'PropertyViewingViewing' include is verified, and describes the data linkage (property, contact, agent). However, it does not mention auth requirements or rate limits, which is a minor gap for a read-only listing tool.
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 information-dense and well-structured, starting with purpose, then lifecycle context, return format, include verification, and workflow patterns. It is longer than minimal but every sentence earns its place. There is slight redundancy with the schema's include description, but it does not detract significantly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 5 parameters and no output schema, the description provides return format, pagination, workflow patterns, and cross-tool references. It is complete enough for an agent to select and use correctly, though it could explicitly contrast with qobrix_search_viewings and qobrix_get_viewing for even better sibling differentiation.
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?
Input schema coverage is 100% and all 5 parameters have detailed descriptions. The description adds no parameter-specific meaning beyond what the schema already provides; its search example (created >= THIS_WEEK) is already covered by the schema's THIS_WEEK shortcut. Thus, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List property viewings (RESO ShowingAppointment)' and positions it as the 'Showing/Viewing Lifecycle tool', giving a specific verb+resource and a clear role. This distinguishes it from siblings like qobrix_search_viewings and qobrix_get_viewing, as it emphasizes the listing and lifecycle aspect.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit workflow patterns: 'This week's viewings: search with created >= THIS_WEEK', 'Property's showing history: qobrix_get_property...', 'Meetings linked to viewings: qobrix_list_meetings...'. These give concrete when-to-use guidance and name alternative tools, fulfilling the criteria for explicit usage guidelines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_rep_scorecardA
Per-rep productivity roll-up. One call returns a wide row for a single user or a top-N leaderboard (default). Counts calls/meetings/emails/tasks/viewings/opportunities and deals closed; sums total_volume + total_commission from closed contracts. Bucketed by assigned_to across every resource. Example uses: Leaderboard 2026 by volume: { year: 2026 }. My scorecard last 30 days: { user: 'CURRENT_USER', since_days: 30 }. Top 5 by activities this quarter: { from: '2026-01-01', to: '2026-04-01', sort_by: 'activities', top: 5 }.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO exclusive upper bound. | |
| top | No | Leaderboard size (default 10). Ignored when `user` is set. | |
| from | No | ISO lower bound. | |
| user | No | User UUID for a single-rep card. Omit for top-N leaderboard mode. Accepts the special token 'CURRENT_USER'. | |
| year | No | Calendar year window. | |
| sort_by | No | Leaderboard sort axis (default 'volume'). Ignored when `user` is set. | |
| since_days | No | Rolling window in days. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses what the tool aggregates (counts per resource, sums from closed contracts), how it buckets data (by assigned_to across every resource), and that it returns a wide row or leaderboard. It does not mention potential performance implications or exact return field list, but it gives a solid behavioral overview beyond what the name alone conveys.
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 compact yet information-dense. It front-loads the purpose, then summarizes the return type and aggregation logic, and ends with three illustrative examples that clarify parameter usage. Every sentence adds value, and the structure makes the tool's behavior easy to grasp quickly.
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 the tool's complexity and the absence of an output schema, the description does a good job of explaining what is returned (wide row or leaderboard, counts and sums). It stops short of explaining field names in the output or edge cases like combining multiple time windows (year vs from/to), but it is sufficiently complete for most agent decision-making.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% parameter coverage, so the baseline is 3. The description adds valuable context: default leaderboard size, interaction between 'user' and 'top'/'sort_by', support for 'CURRENT_USER', and the meaning of 'since_days' as a rolling window. This goes beyond the schema and helps the agent construct correct call parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states this is a 'per-rep productivity roll-up' that returns either a single-user wide row or a top-N leaderboard. It specifies exactly which resources are counted (calls, meetings, emails, tasks, viewings, opportunities, deals closed) and which metrics are summed (volume, commission). This clearly distinguishes it from sibling list/search/get tools, which operate on individual resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the two modes (single-user via 'user' vs leaderboard by default) and provides concrete example parameter combinations for common use cases. It does not explicitly say when NOT to use this tool or name alternative tools, but the examples and mode explanations effectively imply the appropriate usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_agentsA
Relevance-ranked agent search (F1-optimized). TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences; limit/max_scan control top-N and pool size. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Agents'}) for DSL + fields. Example: boost=[{field:'ref',op:'contains',value:'LIM',weight:2}], limit=10, max_scan=100.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: two-tier filtering, ranked pagination mode, soft boosts never filtering, max_scan capped under expand/media, response caching, and the presence of _relevance/_matched fields in ranked results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences plus a reference call and example. Every phrase adds value with no repetition or filler. Front-loaded with the core purpose and key mechanics.
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?
The description is highly complete for a search tool, covering ranking behavior, pagination modes, limits, and the relationship between parameters. It could explicitly state when to choose this over qobrix_list_agents, but the 'relevance-ranked' positioning largely conveys it. Lacks output schema but mentions key returned fields.
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%, but the description adds the high-level two-tier concept linking search (hard filters) and boost (soft preferences), plus a concrete example. This goes beyond the schema's per-parameter descriptions.
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 performs a relevance-ranked agent search, explicitly mentioning 'agent search' and 'TWO-TIER' model. It distinguishes from list_agents by emphasizing ranking and F1 optimization.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance on how to use search vs boost, controls like limit/max_scan, and references helper tools for DSL, fields, and enums. It does not explicitly contrast with list_agents or other search tools, but the usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_changesA
Search tenant-wide audit log for a CRM resource (Qobrix LogAudit). Calls GET /api/v2/{resource}/changes. Use to find who changed what across all records. Search examples: timestamp >= DAYS_AGO(30), user_id == "", primary_key == "". Pair with qobrix_top_field_changers for leaderboards or qobrix_field_change_history for one record.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort field(s). Example: '-timestamp'. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | LogAudit columns to return. Default all. Recommended for large scans: ['timestamp','user_id','primary_key','original','changed','type'] | |
| search | No | Qobrix search on LogAudit rows. Examples: 'timestamp >= DAYS_AGO(30)', 'user_id == "<uuid>"', 'primary_key == "<opportunity-uuid>"'. | |
| resource | Yes | CRM resource name. PascalCase (e.g. 'Opportunities', 'Properties', 'Contracts') or kebab slug (e.g. 'opportunities'). Maps to GET /api/v2/{resource}/changes. Common values: Opportunities, Properties, Contacts, Contracts, Offers, Tasks, Calls, Meetings. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the scope (tenant-wide, all records) and the endpoint, but does not explicitly state that this is a read-only operation, nor does it mention rate limits, permissions, or return format. This is not a contradiction but leaves some behavioral aspects undeclared.
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 five sentences, each earning its place: purpose, endpoint, use case, examples, and sibling pairing. It is front-loaded with the core functionality and avoids fluff.
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 the six parameters, no output schema, and the sibling tool suite, the description covers purpose, scope, examples, and tool selection guidance. It lacks an explicit description of the response shape, but the fields parameter hints at return columns, so it is reasonably complete for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so the baseline is 3. The description reinforces the search examples but adds no new parameter semantics beyond what is already in the schema, which contains detailed descriptions for all six parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specifically states it searches a tenant-wide audit log for a CRM resource, with the exact endpoint GET /api/v2/{resource}/changes. It also distinguishes from related sibling tools by pairing with qobrix_top_field_changers and qobrix_field_change_history.
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?
Explicitly says 'Use to find who changed what across all records' and provides search examples. It does not explicitly state when not to use, but the pairing guidance with alternatives gives clear selection context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_contactsA
Relevance-ranked contact search (F1-optimized). TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences scored over up to max_scan candidates; limit = top-N returned. With boost: rows get _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Contacts'}) for DSL + fields. Examples: search='country == "CY"', boost=[{field:'city',op:'==',value:'Limassol',weight:2},{field:'is_company',op:'==',value:false,weight:1}], limit=10, max_scan=100. Hard-only: assigned_to == CURRENT_USER; name contains "Smith"; created >= THIS_MONTH.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It thoroughly explains the two-tier mechanism, that 'boost never filters out rows', how ranking and _relevance/_matched work, pagination mode behavior, max_scan caps (including the expand/media cap), and response caching. This is exceptional transparency beyond what could be inferred from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately dense and well-structured. It front-loads the core purpose, then explains the two-tier model, gives examples, and lists edge-case behaviors. Every sentence adds value, and the use of examples (e.g., boost array, hard-only expressions) makes complex behavior immediately understandable without unnecessary verbosity.
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 tool with high complexity, no output schema, and no annotations, the description is remarkably complete. It covers return behavior (_relevance, _matched, pagination.mode), parameter interactions, limits, examples, and references to helper tools (qobrix_search_dsl_help, qobrix_get_field_options, qobrix_get_schema). No significant gaps are apparent.
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?
Despite 100% schema coverage providing baseline parameter explanations, the description adds substantial meaning: it explains the interplay between search, boost, limit, and max_scan, illustrates with concrete examples for both boosted and hard-only queries, and clarifies nuances like pagination behavior and when parameters are ignored. This exceeds the baseline 3 by a wide margin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Relevance-ranked contact search (F1-optimized)', which clearly identifies the tool as a search operation with a specific resource (contacts) and a distinguishing feature (relevance ranking). This differentiates it from sibling tools like qobrix_list_contacts (which likely enumerates contacts) and qobrix_get_contact (which retrieves a single contact). The two-tier hard/soft search model further clarifies its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: for relevance-ranked search with hard filters ('search') and optional soft preferences ('boost'). It gives examples of hard-only usage and boosted usage, making the intended scenario clear. However, it does not explicitly state exclusions or alternatives (e.g., 'for a simple list, use qobrix_list_contacts'), so it lacks explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_contractsA
Relevance-ranked contract search (F1-optimized). TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences; limit/max_scan for top-N and pool. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Contracts'}) for fields. Example: search='contract_type == "cos" and contract_status == "agreed"', boost=[{field:'final_selling_price_amount',op:'>=',value:300000,weight:2}], limit=10, max_scan=150. Prefer qobrix_deals for common closed-deal questions.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the two-tier ranking behavior, the `_relevance`/`_matched` output fields, `pagination.mode='ranked'`, and that boost never filters out rows (implied by 'soft weighted preferences'). It also mentions 'F1-optimized' as a recall/precision trait. It doesn't state auth or side-effect status, but as a search tool this is less critical.
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?
Six sentences, each packed with distinct information: purpose, two-tier model, output markers, field help pointer, example, and alternative tool. No fluff, though it is dense.
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 7 params, no output schema, and no annotations, the description is remarkably complete: it covers the two-tier model, gives an example, directs users to qobrix_search_dsl_help for fields, and names the preferred alternative for closed deals. The main gap is the lack of a full response format, but the field-help pointer mitigates that.
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 3. The description adds significant semantic value by explaining how `search` and `boost` interact, providing a concrete example with all key params, and clarifying that `limit` means top-N with boost and page size without.
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?
Describes itself as 'Relevance-ranked contract search (F1-optimized)' with a specific resource (contracts) and a distinct two-tier search mechanism. Also explicitly steers users to qobrix_deals for common closed-deal questions, distinguishing it from sibling tools.
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?
Explicitly says 'Prefer qobrix_deals for common closed-deal questions,' providing an alternative. It also gives precise guidance on when to use `search` (hard must-haves) vs `boost` (soft preferences), and how `limit`/`max_scan` control top-N and pool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_dsl_helpA
Return the full Qobrix Search Expression DSL reference so you can build correct search strings and boost[] clauses for ANY qobrix_search_* tool (properties, projects, contacts, agents, opportunities, viewings, tasks, offers, contracts). Includes operators, functions, date helpers, association paths, and the two-tier relevance recipe (hard search filter + soft boost ranking + limit/max_scan). Optional resource (e.g. 'Properties', 'Opportunities', 'Contacts') appends a field cheatsheet and live schema field names (schema fetch is response-cached). Call before composing free-language queries.
| Name | Required | Description | Default |
|---|---|---|---|
| resource | No | Optional resource to append a field cheatsheet and live schema field names. Use 'Properties' or 'Projects' (case-insensitive). When set, also fetches schema/{resource} (cached) and lists field names. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses a caching behavior ('schema fetch is response-cached') and the content of the returned reference (operators, functions, date helpers, association paths, two-tier relevance recipe). However, it doesn't explicitly state that the tool is read-only or describe the response format, though those are less critical for a help tool.
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 three sentences long, front-loaded with the main purpose, and packs necessary details (DSL contents, resource parameter, caching, when to call) without repetition or filler. Every sentence contributes actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter, no output schema) and its role as a reference/help tool, the description fully covers what it returns, what it includes, how to set the resource, that the schema fetch is cached, and when to call it (before composing free-language queries). No critical information is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents the optional `resource` parameter with 100% description coverage, including the caveat to use 'Properties' or 'Projects' (case-insensitive). The description adds examples like 'Opportunities' and 'Contacts', which conflict with the schema's stated valid values, potentially misleading the agent. The caching behavior is also already noted in the schema, so the description adds little genuine semantic value beyond the contradictory examples.
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 'Return the full Qobrix Search Expression DSL reference' with a specific resource type, and explicitly distinguishes it from sibling search tools by indicating it helps build correct `search` strings and `boost[]` clauses for ANY qobrix_search_* tool. This is a specific verb+resource that separates it from the sibling tools.
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 provides explicit when-to-use guidance: 'Call before composing free-language queries.' It also scopes applicability to 'ANY qobrix_search_* tool' and lists the resources covered, which tells the agent exactly when to invoke this reference tool. No alternatives are mentioned because none exist for a help/reference function.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_offersA
Relevance-ranked offer search (F1-optimized). TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences; limit/max_scan for top-N and pool. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Offers'}) for fields. Example: search='created >= THIS_MONTH', boost=[{field:'created',op:'>=',value:'2026-01-01',weight:1}], limit=10, max_scan=100.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it delivers: it discloses that results are relevance-ranked, that boost never filters but only ranks, that response includes _relevance and _matched, and that pagination.mode becomes 'ranked'. This goes well beyond the schema's parameter-level notes, though it omits details like fast-path (no-boost) response behavior or rate-limit/caching caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences: purpose, two-tier model, behavioral output traits, and an illustrative example. Every sentence adds unique value and there is no fluff or repetition of schema content.
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 7-parameter tool with no output schema, the description covers the core execution modes (with/without boost), the output markers, and references qobrix_search_dsl_help for field discovery. It could be more complete by describing the fast-path (no-boost) response/pagination, but the schema fills in most of those details.
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 adds the conceptual 'TWO-TIER' model and a concrete example tying search, boost, limit, and max_scan together. This helps the agent reason about how parameters interact beyond their individual schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Relevance-ranked offer search (F1-optimized)', which clearly identifies the verb (search), resource (offers), and the distinguishing feature (relevance ranking). This differentiates it from siblings like qobrix_list_offers (plain listing) and qobrix_get_offer (single record fetch).
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 explains the two-tier model: 'search = hard must-haves; boost[] = soft weighted preferences', and shows when boost is appropriate. It also directs users to qobrix_search_dsl_help for field details. However, it does not explicitly state when to prefer this over simpler tools like qobrix_list_offers or qobrix_search_properties, so it misses the exclusion/alternative guidance needed for a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_opportunitiesA
Relevance-ranked lead/opportunity search (F1-optimized) — primary pipeline filter AND supply→demand matching. TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences scored over max_scan candidates; limit = top-N. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Opportunities'}) for DSL + buyer-criteria fields. Pipeline recipes: status == "open"; created >= THIS_WEEK and status == "new"; next_follow_up_date <= NOW and status == "open". Supply→demand (who wants this listing?): search='status in ["new","open"] and buy_rent == "buy"', boost=[{field:'area_of_interest',op:'contains',value:'Limassol',weight:3},{field:'bedrooms_from',op:'<=',value:3,weight:2},{field:'list_selling_price_to',op:'>=',value:400000,weight:2}], limit=15, max_scan=200. Works for projects too (native by-property does not).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure, and it excels. It discloses the two-tier ranking behavior (hard `search` filters vs. soft `boost` preferences), the scoring mechanism over `max_scan` candidates, the inclusion of `_relevance` and `_matched` fields, and pagination mode 'ranked'. It also mentions edge cases like the effective scan cap for expand/media (noted in max_scan schema) and the distinction between fast and ranked paths. No contradictions with annotations (none exist).
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 long but information-dense, with a front-loaded primary purpose and then progressively detailed guidance. Each sentence adds value: the two-tier model, recipes, and example are all useful. No fluff. However, it could be slightly more concise by trimming repeated emphasis on boost behavior already in the schema, but overall structure is logical and scannable.
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 tool with 7 parameters and no output schema, the description is remarkably complete. It covers the primary use cases (pipeline filtering, supply→demand), provides recipes, gives a full example, mentions compatibility with projects, and references supplementary tools for deeper DSL and field info. The return values (_relevance, _matched, pagination mode) are disclosed, though a full output schema is absent. The description leaves little ambiguity about how to use this complex 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 significant value beyond the schema by explaining the interplay between parameters: how `search` (must-haves) pairs with `boost` (nice-to-haves), how `limit` becomes top-N with boost vs. page size without, and how `max_scan` defines the candidate pool. The detailed supply→demand example demonstrates parameter usage with real field names and values, clarifying semantics beyond the schema's descriptions.
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's primary purpose: 'lead/opportunity search' with 'Relevance-ranked' functionality, and identifies it as the 'primary pipeline filter AND supply→demand matching.' It distinguishes from siblings by noting 'Works for projects too (native by-property does not),' which is a direct differentiator. The verb 'search' + resource 'opportunities' is explicit and specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: it tells when to use this tool (primary pipeline filter, supply→demand matching) and when not (native by-property search doesn't work for projects). It offers concrete pipeline recipes and a full supply→demand example with search, boost, limit, and max_scan values. It also directs to qobrix_search_dsl_help for DSL and buyer-criteria fields, giving clear alternatives and supplementary resources.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_projectsA
Highly relevant project (development) search for free-language demand (F1-optimized). TWO-TIER RECIPE: (1) search = hard DSL must-haves (server filter → precision). (2) boost[] = soft weighted nice-to-haves scored over up to max_scan candidates (recall + ranking). (3) limit = how many ranked rows to return (default 10, max 100). With boost: top-N with _relevance and _matched; pagination.mode='ranked'. Without boost: fast path single cached page; pagination.mode='fast'. Call qobrix_search_dsl_help({resource:'Projects'}) for DSL + field cheatsheet. Example: search='city contains "Paphos"', boost=[{field:'starting_price_from',op:'<=',value:400000,weight:2},{field:'construction_stage',op:'==',value:'under_construction',weight:1}], limit=10, max_scan=150. When expand=true or media=true, max_scan is auto-capped at 100. If status='result_too_large' with _refine_required, ask the user to narrow then retry. All upstream pages are response-cached.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| media | No | Include inline media on each row. Default false. | |
| expand | No | Expand FK references into nested objects. Default false. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries behavioral disclosure. It explains ranking behavior, _relevance/_matched fields, pagination modes, auto-capping of max_scan with expand/media, response caching, and result_too_large error handling — all beyond what the schema provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place, covering purpose, recipe, example, edge cases, and helper references. It is front-loaded with the purpose and uses a clear two-tier recipe structure, making it compact for the complexity it handles.
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 9 parameters, no output schema, and no annotations, this description provides a remarkably complete picture: input semantics, ranking vs fast modes, scan caps, caching, page behavior, and error-refinement guidance. An agent can correctly select and invoke the tool without needing external documentation.
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?
Although schema coverage is 100%, the description adds substantial meaning: it details the search/boost/limit/max_scan interaction, gives concrete examples, clarifies that boost never filters but only ranks, and notes the fast-path behavior with or without boost. This is far beyond the baseline schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific, non-tautological statement: 'Highly relevant project (development) search for free-language demand (F1-optimized).' It clearly identifies the verb (search), resource (projects/developments), and scope (free-language demand), and the distinctive two-tier search/boost recipe further differentiates it from sibling search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear guidance on how to use the tool internally: 'search = hard DSL must-haves' vs 'boost[] = soft weighted nice-to-haves', and explains fast vs ranked paths. However, it does not explicitly tell when to prefer this tool over alternatives like qobrix_list_projects or qobrix_get_project, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_propertiesA
Highly relevant property search for free-language buyer demand (F1-optimized). TWO-TIER RECIPE: (1) search = hard DSL must-haves (server filter → precision). (2) boost[] = soft weighted nice-to-haves scored client-side over up to max_scan candidates (recall + ranking → better precision@top). (3) limit = how many ranked rows to return (default 10, max 100) — raise for more options, keep modest to avoid context overload. With boost: returns top-N with _relevance (score) and _matched (which boosts hit); pagination.mode='ranked' and pagination.scanned shows pool size. Without boost: fast path — single cached list page (pagination.mode='fast'). Call qobrix_search_dsl_help({resource:'Properties'}) before composing queries. Examples: Hard only: search='status == "available" and sale_rent == "for_sale" and city contains "Limassol"'. Demand match: search='status == "available" and sale_rent == "for_sale"', boost=[{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2},{field:'list_selling_price_amount',op:'in',value:'200000..600000',weight:2}], limit=15, max_scan=200. PAYLOAD: keep expand=false / media=false for search; when either is true, max_scan is auto-capped at 100. If a result returns status='result_too_large' with _refine_required, ask the user to narrow the query (filters, fields[], smaller limit, drop expand/media) then retry. All upstream pages are response-cached (QOBRIX_CACHE_TTL, default 300s).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| media | No | Include inline media on each row. Default false. Only set true when media URLs are needed. | |
| expand | No | Expand FK references into nested objects. Default false (FKs stay as UUID strings). | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels: it discloses the fast path vs. ranked mode, that boost 'Never filters out rows — only ranks them,' that results include _relevance/_matched and pagination.mode='ranked', that result_too_large triggers _refine_required, and that pages are response-cached with QOBRIX_CACHE_TTL. This is rich, actionable behavioral transparency.
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 long but extremely dense and well-structured: it opens with a clear value proposition, uses a labeled recipe, includes concrete examples, and closes with caching/error handling. Every sentence contributes operational value, and the structure makes the complexity navigable rather than overwhelming.
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 tool with 9 parameters, no output schema, and no annotations, the description is remarkably complete. It explains both execution modes, return metadata, pagination behavior, error handling (result_too_large/_refine_required), caching, and performance trade-offs of max_scan. It also points to helper tools (qobrix_search_dsl_help, qobrix_get_field_options, qobrix_get_schema) for further context.
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?
Although schema coverage is 100%, the description adds substantial semantic value beyond the schema: it explains the search/boost/limit/max_scan interplay, that page is 'Ignored when boost is set,' that expand/media cap max_scan at 100, and it provides complete examples. This goes far beyond repeating parameter names and helps the agent select the right combination.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Highly relevant property search for free-language buyer demand (F1-optimized),' clearly identifying the action (search) and resource (properties) plus the unique value proposition. The two-tier recipe further clarifies its purpose, but it does not explicitly distinguish itself from sibling tools like qobrix_list_properties or qobrix_search_projects, so it lacks an explicit sibling contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: it explains when to use boost vs. plain search, advises calling qobrix_search_dsl_help before composing queries, and gives practical guidance like 'keep modest to avoid context overload.' However, it never states when NOT to use this tool or names alternatives such as qobrix_list_properties, so the when/when-not guidance is not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_tasksA
Relevance-ranked task search (F1-optimized) — daily ops for pipeline and follow-up. TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences; limit/max_scan for top-N and pool. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'Tasks'}) for fields. Recipes: search='assigned_to == CURRENT_USER and status != "completed"', boost=[{field:'due_date',op:'<=',value:'2026-12-31',weight:3}], limit=15, max_scan=100. Overdue hard filter: due_date <= NOW and status == "pending".
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excels: it discloses the two-tier semantics, that boost never filters but ranks, the `_relevance`/`_matched` return fields, pagination.mode='ranked', the fast-path vs boost behavior, and scan behavior including caps and response caching. This is far beyond minimal disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-structured, front-loaded with the core purpose and then systematically explaining the two-tier model, recipes, and edge cases. Every sentence contributes, with no filler or repetition of schema details.
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 the tool's complexity (7 params, nested boost objects, no output schema), the description is remarkably complete: it covers the search grammar, boost behavior, pagination modes, return fields, and even provides ready-to-use recipes. It also points to qobrix_search_dsl_help for field-level details, making it self-sufficient for an agent.
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, but the description adds substantial meaning: it explains how `search` and `boost` interact, when `page` is ignored, how `limit`/`max_scan` function as pool/top-N, and provides concrete recipes. This enriches the schema significantly.
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 uses a specific verb+resource ('Relevance-ranked task search') and clearly differentiates from siblings like qobrix_list_tasks by emphasizing the two-tier relevance ranking (search + boost). It also states the operational purpose ('daily ops for pipeline and follow-up'), giving it a distinct identity among similar search/list tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: hard must-haves go in `search`, soft preferences in `boost[]`, and explains `limit`/`max_scan` for top-N and pool. It includes recipes and directs users to qobrix_search_dsl_help for fields. However, it does not explicitly state when to prefer qobrix_list_tasks or other alternatives, so it stops short of full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_search_viewingsA
Relevance-ranked viewing search (F1-optimized). TWO-TIER: search = hard must-haves; boost[] = soft weighted preferences; limit/max_scan for top-N and pool. With boost: _relevance + _matched; pagination.mode='ranked'. Call qobrix_search_dsl_help({resource:'PropertyViewings'}) for fields. Example: search='created >= THIS_WEEK', boost=[{field:'created',op:'>=',value:'2026-01-01',weight:1}], limit=10.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default 1). Used on the fast path (no boost). Ignored when boost is set (ranking returns a single top-N page). | |
| sort | No | Sort by field name (maps to Qobrix OpenAPI sort[]). Prefix with - for descending. Comma-separated for multi-key (e.g. '-list_selling_price_amount,-created'). Examples: '-created' (newest first), 'name' (alphabetical), '-list_selling_price_amount' (highest list price first). | |
| boost | No | Soft relevance criteria (nice-to-haves). Never filters out rows — only ranks them. When present, the tool scans up to max_scan candidates matching `search`, scores each row as the sum of matched clause weights, and returns the top `limit` with _relevance and _matched. Put must-haves in `search`; put preferences here. Example: [{field:'sea_view',op:'==',value:true,weight:3},{field:'bedrooms',op:'>=',value:3,weight:2}]. | |
| limit | No | How many results to return (1-100, default 10). With boost: top-N after ranking. Without boost: page size. Raise when the user wants more options; keep low to avoid context overload. | |
| fields | No | Limit response to specific fields only (partial response). Reduces payload size. Example: ['id','name','status','list_selling_price_amount']. Omit to get all fields. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| max_scan | No | Candidate pool size when boost is set (default 100, hard cap 500). When expand=true or media=true the effective scan is capped at 100 (pagination.scan_capped_reason='expand/media') to keep latency and payload size safe. Higher improves recall (less chance of missing a good listing) but costs more API pages. Ignored on the fast path (no boost). Each scanned page is response-cached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses key behavioral traits: boost never filters, results include `_relevance` and `_matched`, pagination mode is 'ranked', and max_scan forms a candidate pool. It does not explicitly state read-only behavior, but the search semantics and level of detail are strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, front-loaded with the key purpose, followed by usage rules, behavior notes, and an example. No wasted words; every sentence contributes.
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 moderately complex search tool with no output schema, the description explains the ranking behavior, candidate pool, and where to find field details, plus an example. It could mention the return shape more explicitly, but it is otherwise complete enough to guide invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by defining the conceptual relationship between parameters (search=hard filters, boost=soft scoring, limit/max_scan=top-N and pool) and provides a concrete example that ties them together.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Relevance-ranked viewing search (F1-optimized)', giving a specific verb+resource+mode. It clearly distinguishes from plain listing/search siblings by emphasizing the two-tier ranking design and the search vs. boost distinction.
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 explains when to use `search` (hard must-haves) versus `boost[]` (soft preferences), and clarifies the roles of `limit`/`max_scan`. It also points to qobrix_search_dsl_help for fields. However, it does not name alternative tools like qobrix_list_viewings or state explicit exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_sign_inA
Start interactive Qobrix sign-in (Mode C only). When not connected, returns a Sign In to Qobrix link (or native URL elicitation) for the user to complete login + 2FA + consent. When already connected, reports the current identity. In Mode A/B this is a no-op — credentials come from env / request headers. Mode C uses a per-user encrypted session vault keyed by the chat identity (X-Chat-Platform / X-Chat-User-Id). Deliver the Sign In link only to that individual — never post it into a shared/group thread.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It discloses the tool's behavior across states: returns a link or native URL elicitation for login/2FA/consent, reports identity when already connected, and is a no-op in Modes A/B. It also reveals the underlying mechanism (per-user encrypted session vault keyed by chat identity headers) and the security constraint about shared threads.
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 three sentences, each earning its place: the first states the primary action, the second covers the two connection states, and the third explains mode behavior and security. It is front-loaded with the core purpose and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no parameters and no output schema, the description is remarkably complete. It covers all relevant contexts: mode restrictions, connection states, authentication steps, security warnings, and the identity of the user. An agent can understand exactly when and how to invoke this tool, and what to do with 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?
The input schema has zero parameters, so the baseline is 4. The description doesn't need to explain parameter semantics, but it does add context about the authentication flow and mentions relevant headers (X-Chat-Platform / X-Chat-User-Id) which are not parameters but add useful context 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?
The description clearly states the tool's function: 'Start interactive Qobrix sign-in (Mode C only).' It specifies the action (start sign-in), the resource (Qobrix), and the scope (Mode C). It also distinguishes itself from siblings like qobrix_sign_out (logout) and qobrix_whoami (identity check) by describing the sign-in flow and identity reporting.
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 says when to use the tool ('When not connected') and when it's a no-op ('In Mode A/B this is a no-op'), providing clear guidance on context. It also includes a security guideline: 'Deliver the Sign In link only to that individual — never post it into a shared/group thread.' This is strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_sign_outA
Sign out of Qobrix (Mode C only). Fully revokes the current user's session: calls the Authorization Server /disconnect (deletes the minted Qobrix API key and clears AS tokens/vault), then clears this user's local encrypted session vault. Other users' vaults on this MCP process are not affected. In Mode A/B there is no interactive session to clear.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description takes full responsibility and details side effects: 'calls the Authorization Server /disconnect (deletes the minted Qobrix API key and clears AS tokens/vault)', 'clears this user's local encrypted session vault', and 'Other users' vaults on this MCP process are not affected.' This is comprehensive behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences front-load the core action and then add necessary behavioral detail. No wasted words; every clause adds value about scope, process, or exclusions.
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?
The tool is simple (no params, no output schema), and the description covers purpose, usage modes, side effects, and exclusions. It fully equips an agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty with zero parameters, so the baseline is 4. The description adds meaningful context about the sign-out operation's effects, though it doesn't need to explain parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Sign out of Qobrix (Mode C only)' – a specific verb and resource. It details the operation's scope and distinguishes it from sibling tools like qobrix_sign_in and qobrix_whoami by describing full session revocation.
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 explicitly scopes usage to 'Mode C only' and explains that 'In Mode A/B there is no interactive session to clear.' This provides clear when-to-use and when-not-to-use context, though it does not name an alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_stale_leadsA
Find live opportunities (default status in [new,open]) that have no recent activity. An opportunity is 'stale' when no call/meeting/email/task touched it within since_days AND the opportunity itself wasn't modified within that window. Sorted oldest-modified first. Example uses: Silent leads (default, 30d): {}. Aggressive cadence: { since_days: 7 }. My silent leads: { assigned_to: 'CURRENT_USER' }.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Max stale leads to return (default 50). Sorted oldest-modified first. | |
| statuses | No | Opportunity statuses considered 'live' (default ['new','open']). | |
| since_days | No | Threshold in days (default 30). A lead is 'stale' if no Call/Meeting/Email/Task touched it and the opportunity itself wasn't modified within this window. | |
| assigned_to | No | Scope to one rep's leads. UUID or 'CURRENT_USER'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It explains the precise staleness logic, default statuses, sorting order, and the effect of since_days. It does not explicitly state read-only behavior, but the 'Find' verb and focus on reading make it inferable.
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 compact and front-loaded with the core purpose. Every sentence adds useful information: the definition, the sorting rule, and practical examples. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the moderate complexity and absence of an output schema, the description covers the essential behavior, defaults, and use cases. It does not describe the returned object structure, but the tool's output as a list of opportunities is reasonably inferred from the name and sibling 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 description coverage is 100%, so the parameters are already well-documented. The description adds example values (since_days: 7, assigned_to: 'CURRENT_USER') but does not meaningfully expand on the schema's parameter explanations, warranting the baseline score of 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?
The description clearly identifies the tool's function: finding live opportunities with no recent activity. It provides a precise definition of 'stale' and distinguishes this from generic opportunity listing/searching tools by focusing on inactivity criteria.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete example use cases (silent leads, aggressive cadence, assigned to current user), which strongly implies when to use the tool. It does not explicitly name alternative tools for non-stale searches, but the examples and stale definition make the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_timeseriesA
Time-bucketed metric (count / sum / avg / min / max) over any resource. Paginates once over the window, buckets in-process by day/week/month/quarter/year (default 'month'). Per-resource default date_field: contracts→date_of_contract, opportunities/properties/calls/etc.→created. Use search to filter (e.g. only closed sales). Set compare_to_prior=true to also fetch the prior identical-length window for YoY %. Example uses: Monthly 2026 closed-sale volume with YoY: resource='contracts', metric='sum', field='final_selling_price_amount', year=2026, search='contract_type == "cos" and contract_status == "agreed"', compare_to_prior=true. Weekly lead intake last 90 days: resource='opportunities', bucket='week', metric='count', since_days=90. Quarterly listing additions 2026: resource='properties', bucket='quarter', year=2026, metric='count'.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO date (YYYY-MM-DD) exclusive upper bound. | |
| from | No | ISO date (YYYY-MM-DD) inclusive lower bound. | |
| year | No | Calendar year window. | |
| field | No | Numeric field aggregated by `metric` (required when metric != 'count'). Examples: 'final_selling_price_amount' (contracts), 'budget' (opportunities). | |
| bucket | No | Bucket size (default 'month'). 'week' uses ISO weeks starting Monday. | |
| metric | No | Aggregation inside each bucket (default 'count'). Anything other than 'count' requires `field`. | |
| search | No | Extra raw Qobrix search expression ANDed with the date window. | |
| resource | Yes | Resource name (case-sensitive, lowercase plural as used by Qobrix API). Values: properties, opportunities, contacts, agents, tasks, property-viewings, projects, offers, contracts, calls, meetings, email-messages. | |
| date_field | No | Date column to bucket on. Defaults per-resource: contracts → date_of_contract, opportunities → created, properties → created, calls/meetings/email-messages/tasks → created. | |
| since_days | No | Rolling window: only rows dated within the last N days. Mutually exclusive with year/from/to. | |
| compare_to_prior | No | If true, runs the same query over the prior identical-length window and returns a `prior` block + YoY % diffs (when buckets line up). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses important behavior: paginates once over the window, buckets in-process, per-resource default date_field, and prior-window behavior with YoY. It doesn't mention auth or rate limits, but covers the main operational traits.
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 purpose and then uses examples to illustrate parameter combinations. It is long but each sentence adds useful detail for an 11-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity and lack of annotations/output schema, the description covers defaults, windowing options, search filtering, and compare_to_prior. It doesn't fully specify the main return shape, but the examples and behavior notes make it reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters, but the description adds value with per-resource date_field defaults, concrete search expressions, and example combinations. It clarifies semantics beyond the raw schema fields.
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 computes time-bucketed metrics (count/sum/avg/min/max) over any resource, which is a specific verb+resource combination. It distinguishes from list/get siblings but does not explicitly differentiate from other analytics siblings like qobrix_aggregate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete usage scenarios (e.g., monthly 2026 closed-sale volume with YoY, weekly lead intake) and explains when to use search and compare_to_prior. It does not state 'when not to use' or name alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_top_field_changersA
Leaderboard: which users most often edited a given field (tenant-wide audit scan). Paginates GET /{resource}/changes, counts rows where field appears in changed, groups by user_id. Returns [{user_id, user_name?, change_count, latest_change_at, sample_record_ids}]. Use for: 'who rewrites lead source to direct most often in the last 6 months?'
| Name | Required | Description | Default |
|---|---|---|---|
| field | Yes | Field name to rank editors by (must appear in LogAudit.changed). Example: 'source'. | |
| limit | No | Max users in leaderboard (default 20). | |
| since | No | Lower bound for timestamp search. Qobrix expression fragment or full clause. Examples: 'DAYS_AGO(180)' (auto-wrapped as timestamp >= ...), '2025-01-01'. | |
| until | No | Upper bound. Example: 'NOW' or ISO date. Wrapped as timestamp <= ... when bare. | |
| resource | Yes | CRM resource name. PascalCase (e.g. 'Opportunities', 'Properties', 'Contracts') or kebab slug (e.g. 'opportunities'). Maps to GET /api/v2/{resource}/changes. Common values: Opportunities, Properties, Contacts, Contracts, Offers, Tasks, Calls, Meetings. | |
| max_pages | No | Max API pages to scan (100 rows/page). Default 50 (5000 audit rows). | |
| resolve_users | No | When true, resolve user_id to display name (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the internal algorithm (pagination over GET /{resource}/changes, counting appearances in changed, grouping by user_id) and the exact return structure including sample_record_ids. This goes beyond a generic 'top users' statement but does not cover performance or rate-limit implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences plus an example question. It front-loads the core purpose, packs in implementation detail and return format, and ends with a realistic use case—all without unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex analytic tool (7 params, no output schema), yet the description provides the return format, pagination strategy, grouping logic, and a concrete example. The schema handles parameter details, so the description gives enough context to select and invoke the tool 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?
The schema already describes all 7 parameters (100% coverage), so the baseline is 3. The description adds meaningful context by explaining how parameters fit the algorithm: field must appear in the changed log, resource maps to the endpoint, since/until bound the scan. This clarifies the intent behind each parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Leaderboard: which users most often edited a given field' and immediately distinguishes it from sibling list/search tools by focusing on ranking field editors. The mechanism (paginates, counts, groups by user_id) is clear and unique.
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 a concrete use case ('who rewrites lead source to direct most often in the last 6 months?') that illustrates when to invoke this analytical tool. It clearly separates it from plain change-listing tools like qobrix_get_changes, though it does not explicitly mention when not to use it or name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_top_recordsA
Top-N rows of any resource sorted by a numeric or ISO-date field. Paginates server-side (cap 20,000 rows), sorts in-process, and resolves common FK fields (property_id, agent, owner, assigned_to, commission_to, commission_to_2, contact_name, salesperson, seller, project, developer_id, campaign_id) into readable names so the agent doesn't have to chain lookups. Use this for full-dataset top-N, or when list/search sort returns no rows on a nullable/computed field (e.g. opportunities.budget). For a single page of highest list prices, prefer qobrix_list_properties / qobrix_search_properties with sort='-list_selling_price_amount'. Example uses: Top 2026 closed sales: resource='contracts', sort_by='final_selling_price_amount', search='contract_type == "cos" and contract_status == "agreed" and date_of_contract >= "2026-01-01" and date_of_contract < "2027-01-01"'. Largest active listings (full scan): resource='properties', sort_by='list_selling_price_amount', search='status == "available" and sale_rent == "for_sale"'. Most recently modified leads: resource='opportunities', sort_by='modified'.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Number of top records to return (default 10, max 50). | |
| desc | No | Sort descending (default true). | |
| fields | No | Optional projection. Always-resolved FK keys (property_id, agent, owner, assigned_to, etc.) are fetched regardless; this just limits other fields on the raw row. | |
| search | No | Hard-filter Qobrix search expression (server-side precision). Operators: == != <> < > <= >=, contains, starts with, ends with, in [...], not in, ranges in a..b, and/or/not. Functions: DISTANCE_FROM, IN_POLYGON, TRANSLATED, MIN/MAX, DAYS_AGO(n), MONTHS_AGO(n), DAYS_FROM_NOW(n). Shortcuts: NOW, TODAY, THIS_WEEK, LAST_MONTH, THIS_YEAR, CURRENT_USER. Strings double-quoted; booleans true/false; association paths e.g. SalespersonUsers.Contacts.country. Example: status == "available" and sale_rent == "for_sale" and list_selling_price_amount <= 500000. For the full grammar + field cheatsheets call qobrix_search_dsl_help. For enum values call qobrix_get_field_options; for all fields call qobrix_get_schema. | |
| include | No | Optional Qobrix associations to expand inline (passed through to the underlying list call). | |
| resolve | No | Extra FK field names to resolve to readable names, in addition to the always-resolve set (property_id, agent, owner, assigned_to, commission_to, commission_to_2, contact_name, salesperson, seller, project, developer_id, campaign_id). | |
| sort_by | Yes | Field to sort by (numeric or ISO date). Pages through matching rows and sorts in-process. Prefer list/search `sort='-field'` for a single page. Use this for full-dataset top-N, or when server-side sort returns no rows on a nullable/computed field (e.g. opportunities.budget). | |
| resource | Yes | Resource name (case-sensitive, lowercase plural as used by Qobrix API). Values: properties, opportunities, contacts, agents, tasks, property-viewings, projects, offers, contracts, calls, meetings, email-messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses server-side pagination with a 20,000-row cap, in-process sorting, and automatic FK resolution into readable names. It also mentions that the search parameter is a hard server-side filter, providing a clear operational model.
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 well-structured with a lead definition, usage guidance, alternative, and examples. It is longer than minimal but every sentence earns its place; no filler or redundancy is present.
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 the tool's complexity (server-side pagination, in-process sort, FK resolution, search DSL), the description is complete: it covers capabilities, limitations, alternatives, and applied examples. The lack of an output schema is acceptable because the return format is secondary to the tool's selection and configuration.
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 contextual meaning by explaining when sort_by is preferable (nullable/computed fields) and by providing full example search expressions, but this is complementary rather than essential beyond the schema's existing detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource definition: 'Top-N rows of any resource sorted by a numeric or ISO-date field.' It also explicitly contrasts with sibling list/search tools, stating when to use qobrix_top_records versus qobrix_list_properties/qobrix_search_properties, which fully distinguishes it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: 'Use this for full-dataset top-N, or when list/search sort returns no rows on a nullable/computed field' and names the alternative for single-page scenarios. Three concrete example use-cases with resource, sort_by, and search strings further clarify appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_top_valuesA
Aggregate records by a field and return the top N most-frequent values with counts. This tool paginates through all matching records server-side — no client-side scripting needed. Caps at 20,000 records for safety; use a search filter to narrow large datasets. Example uses: Top listing developers: resource='properties', field='developer_id', search='status == "available" and sale_rent == "for_sale"', resolve=true. Lead sources: resource='opportunities', field='source', search='created >= "2026-01-01"'. Agent workload: resource='opportunities', field='owner', search='status == "open"', resolve=true. Property type mix: resource='properties', field='property_type', search='status == "available"'. Set resolve=true to convert UUIDs (developer_id, agent, owner, etc.) to human-readable names.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Number of top values to return (default 10, max 50). Returns the N most-frequent values. | |
| field | Yes | Field name to aggregate by (e.g. 'developer_id', 'agent', 'status', 'source', 'owner', 'city', 'property_type'). Must be a top-level scalar field on the resource. | |
| search | No | Optional Qobrix search expression to filter records before aggregating. Example: 'status == "available" and sale_rent == "for_sale"' to only aggregate active sale listings. | |
| resolve | No | If true, attempt to resolve UUID foreign keys to human-readable names by looking up the referenced entity (Contacts, Agents, Projects, Users). Default false. | |
| resource | Yes | Resource name (case-sensitive, lowercase plural as used by Qobrix API). Values: properties, opportunities, contacts, agents, tasks, property-viewings, projects, offers, contracts, calls, meetings, email-messages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavior. It does well by explaining server-side pagination, the 20,000-record cap, and the resolve=true option to convert UUIDs to names. It mentions the output shape (top N values with counts). It doesn't explicitly state read-only safety, but the aggregation semantics imply it, and the cap warning addresses a key risk.
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 a clear purpose statement, followed by behavioral notes and then examples. The multiple examples (four) make it longer than strictly necessary, but each adds concrete context and earns its place. The structure is logical, and the final sentence on 'resolve' is placed at the end as a modifier. Slightly verbose but well-organized.
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 tool with 5 parameters, no output schema, and no annotations, the description is thorough. It covers what the tool does, how it behaves (pagination, cap, resolve), and includes examples. It doesn't detail the exact output JSON structure beyond 'top N... values with counts', but that is likely sufficient for an agent to invoke and interpret results. Minor gap: no explanation of what happens if the cap is exceeded or if the field is not aggregatable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers 100% of parameter syntax and default values, so the baseline is 3. The description adds notable value by providing concrete example values for 'field' (developer_id, agent, source), 'search' expressions, and explaining the practical meaning of 'resolve'. This goes beyond schema descriptions and helps the agent map parameters to real-world scenarios.
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's function: 'Aggregate records by a field and return the top N most-frequent values with counts.' This goes beyond a simple restatement, providing a specific verb and resource scope. It also distinguishes itself from sibling analytics tools (e.g., qobrix_count, qobrix_aggregate) by focusing on frequency-based ranking of top values.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context, such as 'This tool paginates through all matching records server-side' and 'Caps at 20,000 records for safety; use a search filter to narrow large datasets.' It gives practical examples of when to use it (top developers, lead sources, etc.). However, it doesn't explicitly contrast this tool with alternatives (e.g., qobrix_aggregate), so it's clear but lacks direct exclusions or alternative references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_whoamiA
Return the current Qobrix user profile, capabilities, and portals (GET /api/v2/session/). In Mode C with no session for this chat identity, surfaces a Sign In link so the user can authenticate first. Also includes the OAuth subject when available. Use to confirm which CRM identity the agent is acting as for this user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the transparency burden. It discloses a conditional behavior (surfacing a Sign In link in Mode C without a session) and notes that OAuth subject is included when available. This goes well beyond a simple 'returns the current user' statement.
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 three sentences, each earning its place: what it returns, an edge-case behavior, and the intended use. It is front-loaded and free of filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter, no-output-schema tool, the description covers all essential context: the resource returned, the authentication edge case, and why to call it. It is complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema confirms this. According to the rubric, the baseline for 0 params is 4, and the description does not need to add parameter-level detail. It correctly avoids inventing any.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Return the current Qobrix user profile, capabilities, and portals', which uses a specific verb and resource and clearly distinguishes this from sibling tools that query CRM data. It is immediately obvious what the tool does.
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 explicitly states 'Use to confirm which CRM identity the agent is acting as for this user', giving a clear when-to-use scenario. It also describes the Mode C no-session behavior, which implies it is relevant after authentication. It does not name alternatives, but no sibling tool serves the same purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qobrix_win_lossA
Win-rate analytics over opportunities. Globally returns counts of new / open / won / closed_lost plus win_rate_pct = won / (won + closed_lost). Optional group_by slices by source, enquiry_type, owner, agent, or closed_lost_reason_id (multi-dim arrays supported). Window applied to last_status_change (fallback modified). Set include_top_losses=true to also receive the 10 most-recent closed_lost opportunities with reason labels and details. Example uses: Overall 2026 win rate: { year: 2026 }. Win rate by lead source: { year: 2026, group_by: 'source' }. Top loss reasons last 90 days: { since_days: 90, group_by: 'closed_lost_reason_id' }. My win rate: { assigned_to: 'CURRENT_USER', year: 2026 }. Forensic loss review: { year: 2026, include_top_losses: true }.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | ISO exclusive upper bound. | |
| top | No | Max group buckets to return (default 10). | |
| from | No | ISO inclusive lower bound. | |
| year | No | Calendar year window. | |
| agent | No | Scope to one external broker (opportunities.agent UUID). | |
| group_by | No | Optional slicing dimension(s). Common values: 'source', 'enquiry_type', 'owner', 'agent', 'closed_lost_reason_id'. Pass an array of 2-3 fields for a multi-dim pivot. | |
| since_days | No | Rolling window in days. Window is applied to last_status_change (fallback modified). | |
| assigned_to | No | Scope to one rep's opportunities (UUID or 'CURRENT_USER'). Maps to opportunities.owner. | |
| include_top_losses | No | When true, also returns the 10 most-recent closed_lost opportunities with closed_lost_details, source, last_status_change, and resolved contact_name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure. It goes well beyond a simple summary by exposing the exact win_rate_pct formula, the windowing fallback (last_status_change then modified), the scope of global returns, the multi-dim grouping capability, and the extra data delivered by include_top_losses. This is exceptionally transparent and sets clear expectations.
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 compact but dense. It starts with a clear one-sentence summary, then explains the return payload, optional grouping, and window behavior, followed by five illustrative examples. Every sentence carries useful information, though the example list makes it slightly longer than necessary. Still, it is well-structured and easy to scan.
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 tool with 9 parameters, no output schema, and no annotations, the description is remarkably complete. It covers the main output metrics, the windowing semantics, grouping options, multi-dim support, the optional top-losses payload, and practical usage patterns. An agent could confidently invoke this tool and correctly interpret results without additional documentation.
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%, but the description adds substantial meaning beyond individual parameter descriptions. It explains how parameters interact (e.g., group_by valid values, multi-dim arrays), defines the window fallback, clarifies that 'CLOSED' maps to assigned_to, and shows real parameter combinations via examples. This transforms the bare schema into a rich usage model.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Win-rate analytics over opportunities,' a specific verb+resource phrase that clearly distinguishes this tool from sibling tools like qobrix_deals or qobrix_funnel. It further specifies exactly what it returns (counts, win_rate_pct, optional top losses), leaving no ambiguity about its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides multiple concrete example use cases ('Overall 2026 win rate,' 'Win rate by lead source,' 'Top loss reasons last 90 days,' 'My win rate,' 'Forensic loss review') that clearly imply when to use the tool. However, it does not explicitly name alternative tools or state when NOT to use this tool, so it misses the top tier of usage guidance.
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.
64 tool updates
v1.8.2- First observed
qobrix_aggregate - First observed
qobrix_cache_clear - First observed
qobrix_cache_stats - First observed
qobrix_cohort - First observed
qobrix_count - First observed
qobrix_days_on_market - First observed
qobrix_deals - First observed
qobrix_field_change_history - First observed
qobrix_funnel - First observed
qobrix_get_agent - First observed
qobrix_get_call - First observed
qobrix_get_changes - First observed
qobrix_get_contact - First observed
qobrix_get_contract - First observed
qobrix_get_email_message - First observed
qobrix_get_field_options - First observed
qobrix_get_lead_properties - First observed
qobrix_get_leads_by_property - First observed
qobrix_get_media - First observed
qobrix_get_meeting - First observed
qobrix_get_offer - First observed
qobrix_get_opportunity - First observed
qobrix_get_project - First observed
qobrix_get_project_coordinates - First observed
qobrix_get_properties_by_lead - First observed
qobrix_get_property - First observed
qobrix_get_property_coordinates - First observed
qobrix_get_schema - First observed
qobrix_get_task - First observed
qobrix_get_viewing - First observed
qobrix_list_agents - First observed
qobrix_list_calls - First observed
qobrix_list_contacts - First observed
qobrix_list_contracts - First observed
qobrix_list_email_messages - First observed
qobrix_list_media - First observed
qobrix_list_meetings - First observed
qobrix_list_offers - First observed
qobrix_list_opportunities - First observed
qobrix_list_projects - First observed
qobrix_list_properties - First observed
qobrix_list_tasks - First observed
qobrix_list_viewings - First observed
qobrix_rep_scorecard - First observed
qobrix_search_agents - First observed
qobrix_search_changes - First observed
qobrix_search_contacts - First observed
qobrix_search_contracts - First observed
qobrix_search_dsl_help - First observed
qobrix_search_offers - First observed
qobrix_search_opportunities - First observed
qobrix_search_projects - First observed
qobrix_search_properties - First observed
qobrix_search_tasks - First observed
qobrix_search_viewings - First observed
qobrix_sign_in - First observed
qobrix_sign_out - First observed
qobrix_stale_leads - First observed
qobrix_timeseries - First observed
qobrix_top_field_changers - First observed
qobrix_top_records - First observed
qobrix_top_values - First observed
qobrix_whoami - First observed
qobrix_win_loss
TDQS
Scored across 64 tools
Most tools are clearly distinct by resource (contacts, properties, opportunities, etc.) and action (list, get, search). However, there are some overlaps: qobrix_get_properties_by_lead and qobrix_get_lead_properties appear to do the same thing (both return properties for a lead), and qobrix_search_offers / qobrix_search_contracts vs qobrix_deals may be confused for deal queries. Also, qobrix_count, qobrix_top_values, qobrix_top_records, qobrix_aggregate, qobrix_timeseries all perform analytics over resources, requiring agents to read carefully to choose the right one.
Tool names follow a consistent verb_noun pattern: list_<resource>, get_<resource>, search_<resource>, plus a few domain-specific verbs like count, aggregate, timeseries, funnel, win_loss, etc. All are snake_case with clear resource identifiers. The few exceptions (qobrix_deals, qobrix_funnel, qobrix_win_loss) are still consistent with the verb-based style (e.g., deals is a verb-like noun). Overall, the naming is predictable and uniform.
64 tools is on the heavier side, but the server covers a full CRM domain with core entities (contacts, properties, opportunities, viewings, tasks, media, projects, offers, contracts, calls, meetings, emails) plus analytics and admin tools. While a 64-tool surface may be overwhelming for agents, the tools are organized and each serves a specific purpose. The count is borderline high but justified by the breadth of functionality. It is not an extreme mismatch (like 100+ or a single trivial tool).
The tool surface covers the primary CRM lifecycle: list/get/search for all main entities, plus creation/update/delete appears missing for most resources—only search/list/get are provided. However, the server is likely read-only (no create/update/delete tools, except for auth). Given that the domain is CRM data retrieval and analytics, the coverage is quite complete for read operations: all key resources are represented, and advanced analytics (funnel, win_loss, stale_leads, cohort) fill gaps. Some missing operations like creating a contact or updating an opportunity are absent, but the server appears designed as a read/analytics layer rather than a full CRUD tool, so this is a minor gap.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
- dataOAuthco.thinair
Read-only PostgreSQL, MySQL, SQL Server access via MCP — 24 dialect-aware hosted tools.
Hosted MCP server for real-world data: business registries, sanctions, companies, domains, crypto.
API-first CRM for LLMs - contacts, companies, deals and activities over a native MCP server.
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.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA comprehensive Model Context Protocol server for real estate data management that provides tools and resources for property listings, agent management, market analysis, client relationships, and area intelligence.57AGPL 3.0
- AlicenseAqualityCmaintenanceRead-only MCP server for the Daktela contact center REST API, providing 40 tools to access tickets, calls, emails, chats, contacts, CRM records, campaigns, and real-time agent status.451MIT
- AlicenseCqualityDmaintenanceEnterprise-level MCP server integrating with Vista CRM (Loft Edition) for real estate operations, offering 40+ tools for property search, pipeline management, lead capture, and agenda control.42MIT
- FlicenseNot gradedqualityCmaintenanceMCP server for Moody's Commercial Real Estate API, providing 37 tools for property lookups, market analytics, comps, CMBS data, tax records, and more.-