Skip to main content
Glama

Server Details

Zoning, parcel, and development feasibility for a street address in Canada and the US.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
100.0% over 62 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
markbucky/bucky-plugin
GitHub Stars
0
Server Listing
Bucky

TDQS

A3.9/5.0

Scored across 26 tools

Disambiguation4/5

Most tools target a clearly distinct resource and action, and descriptions actively steer away from confusable pairs (previewSiteCoverage vs getFeasibilitySnapshot, findPlacesByMarket vs screenLots, submitBuckyFeedback vs proposeResultFlags). The main soft spots are saveToProject doing three unrelated things (create/attach_parcels/attach_reference) and uiGetAnalysisStatus overlapping getProjectContext, though the latter is explicitly marked as one the model should not use.

Naming Consistency4/5

The set is overwhelmingly consistent camelCase verb_noun (getFeasibilitySnapshot, createSavedFolder, removeSavedFolderItem, runFeasibilityAnalysis, proposeResultFlags). Two deviations stand out: cityInventory is a bare noun with no verb, and uiGetAnalysisStatus carries a UI-specific prefix.

Tool Count4/5

At 26 tools the surface is on the heavy side, but the domain is genuinely broad (feasibility lookup, bylaw text, saved lots and folders, projects, screening, market ranking, reports, publishing, feedback), and nearly every tool maps to a real operation. It is slightly over what an agent can hold comfortably, but not padded.

Completeness4/5

Coverage is strong: folder lifecycle is full CRUD plus membership add/remove, saving/unsaving lots, project context/update/analysis/report/publishing, screening and market discovery, status explanation and bylaw text retrieval. Gaps exist but are minor and often acknowledged: no project archive/delete, no detach-lot-from-project, and no delete for a saved search list, with several writes deliberately pushed to the CLI.

Available Tools

26 tools
addSavedFolderItemadd Saved Folder ItemA
Idempotent
Inspect

Add exactly one saved lot or project to a private folder. Pass folderId and target with savedLotId (a save id from listSaved) or projectId. Repeating the same membership is safe. Use preview=true first.

NameRequiredDescriptionDefault
targetYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.
folderIdYes

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=false, so 'Repeating the same membership is safe' largely restates idempotentHint. The genuinely additive parts are the 'private folder' scope and the preview-first recommendation, but nothing is said about permissions, failure modes, or what happens when the target already exists in another folder.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and cardinality constraint, then the parameter shape, then behavior and workflow. No sentence is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter mutation with no output schema, the description covers the action, the target union, idempotency and a preview safety path, which is enough to call it correctly. It omits folder ownership or permission requirements and what the caller gets back on a successful add.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%, and the description compensates on the hardest part: it explains the target anyOf union by telling the agent to supply either savedLotId or projectId, which the schema only expresses structurally. It also flags preview=true semantics in-line. It adds no detail on the required 'context' field, but the schema already spells that out at length.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Add exactly one saved lot or project to a private folder.' That precisely separates it from createSavedFolder (makes folders), saveLot (saves lots) and removeSavedFolderItem (the inverse), though it names only listSaved explicitly rather than its nearest sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Gives a concrete upstream dependency ('savedLotId (a save id from listSaved)') and a recommended workflow ('Use preview=true first'), plus an idempotency note that tells the agent repeats are harmless. It stops short of stating when NOT to use it or naming removeSavedFolderItem as the undo path.

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

cityInventorySee what Bucky has mapped for a cityA
Read-onlyIdempotent
Inspect

Public city catalogue inventory. Pass exactly one of: cityName, lat and lng together, or geoDivisionId. A city name with multiple matches returns choices; after the user chooses, call again with that candidate geoDivisionId. Never pass a slug. Shows datasets grouped by topic as on file, not loaded yet, unavailable, or not confirmed. This is city coverage, not lot feasibility or operator health. CMHC rental survey figures describe purpose-built rentals; the new-build proxy is the 2000 or later band. Missing facts are not surveyed or unavailable, never zero. Cite RMS figures as Source: CMHC, Rental Market Survey, October YYYY using referencePeriod. Cite starts and completions with their own source and period. If Bucky has not mapped the place, the result points to recording demand. It does not record demand by itself.

NameRequiredDescriptionDefault
latNo
lngNo
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
cityNameNo
geoDivisionIdNo

TDQS

A4.1/5.0
Behavior5/5

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

Annotations already declare read-only/idempotent/non-destructive, yet the description still adds substantial behavior: the four coverage states in the response, the two-step disambiguation flow, the rule that missing facts mean "not surveyed or unavailable, never zero," the distinction between CMHC rental-survey figures and the 2000+ new-build proxy, and per-figure citation obligations with referencePeriod. None of that is recoverable from the annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The argument-selection rules are correctly front-loaded, but the back half stacks citation boilerplate ("Cite RMS figures as Source: CMHC, Rental Market Survey, October YYYY...", "Cite starts and completions with their own source and period") that is formatting policy rather than tool-selection guidance. Every clause is defensible in isolation, yet the block runs long and mixes invocation rules with output-citation rules.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the work of explaining returns: topic grouping, the four availability states, disambiguation behavior, and the fallback when a place is unmapped. That is enough for an agent to call it and interpret results. The residual gap is that the required `context` parameter and the semantics of `geoDivisionId` versus a name are only implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20% (only `context` is documented), so the description must carry the load, and it largely does: it states the one-of constraint across cityName / lat+lng / geoDivisionId and the constraint that lat and lng travel together. It never mentions the required `context` analytics parameter, so it does not fully close a 0%-covered required field even though the schema covers that one.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Public city catalogue inventory" plus "Shows datasets grouped by topic as on file, not loaded yet, unavailable, or not confirmed" establishes the resource and the return shape concretely. The description then rules out adjacent scopes ("not lot feasibility or operator health"), which separates it from the feasibility siblings. It loses a point only because the opening noun phrase is jargon-ish and the verb has to be inferred from later sentences.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

The caller is told the three admissible input modes, the lat/lng pairing requirement, the "never pass a slug" exclusion, and the exact disambiguation loop (multiple matches → user picks → re-call with geoDivisionId). It also bounds the tool against feasibility and against the un-named "recording demand" tool. What is missing is a named sibling alternative; exclusions are stated by negation rather than by pointing at a specific tool.

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

createSavedFoldercreate Saved FolderAInspect

Create a named private folder. A repeated create makes another folder. Use preview=true first and listSavedFolders to check an uncertain outcome before retrying.

NameRequiredDescriptionDefault
nameYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false; the description adds the practical consequence — a repeated create produces a duplicate folder rather than updating — plus a safe dry-run path via preview. It leaves out auth/permission requirements and what happens on duplicate names, but it meaningfully extends the annotation set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action, then the duplicate-creation caveat, then the safe-retry procedure. No filler and nothing buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple create tool with annotations and no output schema, the description covers the main risk (accidental duplicates) and the mitigation. It omits error behavior on duplicate names and permission requirements, which an agent would want before calling in a real workspace.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, so baseline is 3; the description earns an extra point by explaining why preview exists in workflow terms ('use preview=true first'), which goes beyond the schema's terse 'inspect the request without writing'. The name parameter's constraints (1-120 chars) and the context analytics parameter are left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a named private folder'), which is clearly distinct from renameSavedFolder, deleteSavedFolder, and addSavedFolderItem. It doesn't explicitly contrast with saveToProject or saveLot, which are the nearest ambiguous alternatives, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Gives concrete operational guidance: use preview=true first, and use listSavedFolders to verify an uncertain outcome before retrying. It names the sibling to consult and the situation that warrants it, though it doesn't say when not to use this tool versus other save mechanisms.

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

deleteSavedFolderdelete Saved FolderA
DestructiveIdempotent
Inspect

Delete a private folder by folderId and remove its memberships. Its lots stay saved and its projects are kept. Use preview=true first; this MCP tool does not restore deleted folders.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.
folderIdYes

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and idempotentHint=true, but the description goes further by disclosing exactly what is destroyed (memberships) and what survives (lots remain saved, projects kept) plus the absence of any restore path. That is precisely the partial-destructiveness context an agent needs before committing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying distinct payload: the operation, the cascade semantics, and the safety protocol. Front-loaded with the verb and resource, no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive tool with no output schema, it covers the essential unknowns: blast radius, surviving data, irreversibility, and the preview safeguard. It omits permission/authorization requirements and whether deletion is scoped to the caller's own folders, which an agent might need.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, with folderId documented only by a regex pattern, so the description's "by folderId" plus the folder-level scope adds real meaning. "Use preview=true first" also gives preview a workflow role beyond the schema's bare "inspect the request without writing." It stops short of describing what inspect output contains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Delete a private folder by folderId") and immediately clarifies the cascade scope: memberships removed, lots and projects kept. It is clearly a delete operation distinct from createSavedFolder or renameSavedFolder, though it never names a sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Gives explicit pre-call guidance ("Use preview=true first") and rules out a recovery expectation ("does not restore deleted folders"). It doesn't contrast against removeSavedFolderItem for removing contents versus deleting the container, so the alternative-selection guidance is implicit rather than complete.

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

explainFeasibilityStatusExplain a Bucky feasibility statusA
Read-onlyIdempotent
Inspect

Explain one Bucky coverage or per-fact provenance status and the safe next action. This is a pure static lookup: it does not inspect an address, retrieve property data, or call a database, geocoder, AI model, or third-party API. Accepts exactly one of: live, live_unavailable, planned_not_live, geo_division_uncatalogued, unseeded_place, geocode_failed, cited, cited_conditional, conditional_unresolved, no_limit_in_bylaw, not_extracted, site_specific_schedule, unverified_default, derived_from_cited, defaulted, missing. Copy the status verbatim from a feasibility result. An unknown status returns this list instead of failing.

NameRequiredDescriptionDefault
statusYesA Bucky coverage resolution status or per-fact provenance status returned by a feasibility result. Copy it verbatim. Do not paraphrase or invent a status.
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."

TDQS

A4.7/5.0
Behavior5/5

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

The description provides critical behavioral context by explicitly stating that the tool is a 'pure static lookup' and listing which systems it does *not* interact with (database, geocoder, AI model, etc.), defining its operational boundaries.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is highly dense and efficient. It front-loads the core purpose and follows up with detailed operational constraints, ensuring every sentence provides necessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool is defined as a pure static lookup, the description is extremely complete. It defines the exact input constraints (verbatim status), output constraints (returning the list if unknown), and operational limits.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage, the baseline is strong. The description significantly adds value by listing every single possible enum value for the 'status' parameter, removing any ambiguity for the calling agent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly defines the tool's function as explaining a specific 'Bucky coverage or per-fact provenance status' and providing the 'safe next action.' This is distinct from other analysis or retrieval tools in the sibling list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

While it does not compare itself to other tools, it provides strict usage guidelines by requiring a status to be copied 'verbatim' from a feasibility result, defining its precise domain of applicability.

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

findPlacesByMarketFind places by their rental marketA
Read-onlyIdempotent
Inspect

Find which places to look at by their rental market: filter and rank the places Bucky sells (reviewed catalogue places) on market facts and signals. Signed-in only; read scope. Pass country (CA has data today) and a preset (CA: tight-rental, fast-rent-growth, undersupplied, mli-select-headroom), filters ({ key, min, max }, inclusive), or both; optional region (province code or name), sort, limit (default 20, max 50) and offset. An unknown key returns the filterable keys. Returns counts { places, matched, excluded, unknown }, matched places with their values, and the unknown places with their missing keys. Report the unknown count: a place missing a filtered value is not a match and not a fail. Places are compared on one survey period. truncation says what was left out: places pages with truncation.places.nextOffset as the next offset; unknown lists at most 50 places by name, counts.unknown is the total. Cite every figure with the sources lines (CMHC licence). Market data filters places, not lots: use screenLots for lots inside a place.

NameRequiredDescriptionDefault
sortNoDefaults to the preset sort, else the first filter key
limitNo
offsetNoMatched places to skip. Copy truncation.places.nextOffset for the next page.
presetNoA preset id for the country; its filters apply first, then `filters` by key
regionNoProvince or state, as a code (AB) or a name (Alberta)
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
countryYesISO country code. Places are filtered and ranked only within this country.
filtersNo

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare the safety profile, yet the description adds auth requirements, the fact that places are compared on a single survey period, pagination behavior via 'truncation.places.nextOffset', the 50-name cap on unknown lists, and the licensing/citation obligation. It also explains a non-obvious semantic: a place missing a filtered value is 'not a match and not a fail'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose and the sibling exclusion before descending into parameters and return semantics. Dense and mostly earning its place, though a few sentences pack multiple facts and the parameter enumeration is longer than strictly necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description fully specifies the return shape: counts { places, matched, excluded, unknown }, matched places with values, unknown places with missing keys, and truncation details. Nothing an agent needs to call or interpret results is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Adds real meaning beyond the 75%-covered schema: the concrete preset ids (tight-rental, fast-rent-growth, undersupplied, mli-select-headroom), 'CA has data today' for country, region as 'province code or name', and inclusive bounds for filters. Some of it repeats schema facts (limit default 20 / max 50), which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Find which places to look at by their rental market') and clarifies the scope as 'the places Bucky sells (reviewed catalogue places)'. The closing line 'Market data filters places, not lots: use screenLots for lots inside a place' explicitly separates it from the nearest sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

States access conditions ('Signed-in only; read scope') and names the alternative for a common confusion ('use screenLots for lots inside a place'). It also tells the agent how to discover valid filter keys ('An unknown key returns the filterable keys'). It does not cover when to prefer presets over filters or when other siblings apply, so not a full 5.

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

getBuckyMcpGuideGet the Bucky MCP guideA
Read-onlyIdempotent
Inspect

Call with no arguments on first contact. Optional role, market, and scale answer the first-call questions on a second call. Returns what this session should do next.

NameRequiredDescriptionDefault
roleNoWho is asking. Answers "Developer, GC, or municipal reviewer?".
scaleNoOne site or several. Answers "Single parcel, or a portfolio?".
marketNoWhich country the site is in. Answers "US or Canada?".
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds real behavioral value by disclosing the two-call pattern and that the output is directional next-step guidance rather than data. It does not say what happens if optional params are supplied on the first call or whether they persist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero filler, and the most important instruction (call with no arguments first) is front-loaded before the optional refinement detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining the return value, and 'what this session should do next' stays abstract — an agent cannot anticipate whether it gets prose instructions, tool recommendations, or a checklist. Combined with the unresolved required-`context` conflict, the definition is usable but leaves gaps for a first-contact tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explains the sequencing of the three optional enums (they answer the first-call questions on a second call), which the schema alone does not convey. However, it instructs 'Call with no arguments on first contact' while the schema marks `context` as required — a direct conflict that will confuse an agent about whether it can call with zero arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states concretely that the tool returns 'what this session should do next' and frames the call pattern (first contact vs. second call), which makes the onboarding/guidance purpose clear in combination with the name and title. It stops short of saying outright that it returns the MCP usage guide itself, so the resource is implied rather than named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

It gives an explicit call sequence: no arguments on first contact, then optionally pass role/market/scale on a second call to answer the first-call questions. There is no realistic alternative sibling for onboarding, so the absence of named alternatives costs nothing.

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

getBylawSectionGet cited bylaw section textA
Read-onlyIdempotent
Inspect

Return the stored bylaw section text behind a snapshot citation. Pass sectionIds copied from citations.*.knowledgeSectionId on getFeasibilitySnapshot. Or pass geoDivisionId from coverage.geoDivisionId, zoneCode from zone.code, and sectionNumbers such as 3.1 or 3.2. The markdown is the schedule text. A number in the snapshot can still be conditional on frontage, tenure, or adjoining district. Each section returns at most 12,000 characters. A cut section has truncated: true, totalChars and nextOffset: call again with that section id and textOffset: nextOffset for the rest. Ids or section numbers with no active chunk come back in missing.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
zoneCodeNozone.code from getFeasibilitySnapshot, for example C-2.
sectionIdsNoCopy citations.*.knowledgeSectionId from getFeasibilitySnapshot. 1 to 4 ids.
textOffsetNoCharacter to start each section at. Default 0. Copy nextOffset from a truncated section to read the rest.
geoDivisionIdNocoverage.geoDivisionId from getFeasibilitySnapshot.
sectionNumbersNoSection numbers to read, for example 3.1 or 3.2. 1 to 4 numbers.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/idempotent annotations, it discloses the 12,000-character per-section cap, the truncation contract (`truncated`, `totalChars`, `nextOffset` plus the resume call with `textOffset`), the `missing` result set for unresolved ids, and the substantive caveat that a cited number may still be conditional on frontage, tenure, or adjoining district. That is exactly the behavior an agent needs before relying on the returned text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Six tight sentences, front-loaded with the purpose and the primary id-based path before the alternate path, pagination, and error case. No filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must carry return-value semantics — and it does, describing markdown content, the truncation fields, the resume protocol, and the `missing` collection. For a 6-parameter read tool this leaves nothing an agent needs unresolved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds the mutually exclusive grouping of the two parameter sets ("Or pass..."), which the schema itself never states, plus how `textOffset` is derived from `nextOffset`. It also gives concrete example values for `sectionNumbers` (3.1, 3.2).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Return the stored bylaw section text behind a snapshot citation" names a specific verb (return), resource (bylaw section text), and scope (behind a snapshot citation). This clearly distinguishes it from the sibling getFeasibilitySnapshot, which produces the citations rather than the text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

The description gives two concrete invocation paths — copy `sectionIds` from `citations.*.knowledgeSectionId`, or use `geoDivisionId` + `zoneCode` + `sectionNumbers` — and implicitly establishes getFeasibilitySnapshot as the prerequisite. It does not state when this tool is not appropriate (e.g. no snapshot yet, or coverage gaps), but the context is otherwise clear.

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

getFeasibilitySnapshotGet feasibility snapshot for an addressAInspect

Look up lot, zone, and building envelope for one street address in Canada or the US. Pass address. One address per call; cannot search or compare. A live answer uses one site lookup from the monthly plan allowance; usage says if it was charged and how many are left. getBuckyMcpGuide reports the allowance for free. CMHC rental survey figures describe purpose-built rentals; the new-build proxy is the 2000 or later band. Missing facts are not surveyed or unavailable, never zero. Cite RMS figures as Source: CMHC, Rental Market Survey, October YYYY using referencePeriod. Cite starts and completions with their own source and period. Every envelope value carries a status. Never report not_extracted or site_specific_schedule as no limit or as zero — call explainFeasibilityStatus first. Envelope numbers are extracted ceilings. Call getBylawSection with a citation knowledgeSectionId, or with coverage.geoDivisionId, zone.code, and the section number, before treating a number as available on this lot. Do not fetch zone.bylawSourceUrl. lot.minLotFrontageM is the zone minimum. lot.lotConformity compares lot width, lot area, and floor area per unit to those minima. A missing input is unknown, never a pass. State every fail before quoting a unit count.

NameRequiredDescriptionDefault
sourceNoWhich question the caller is answering. Used for attribution and to pick the link back; the payload is the same either way.full
addressYesStreet address to analyse, e.g. "4170 Sophia St, Vancouver BC".
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."

TDQS

A4.5/5.0
Behavior5/5

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

Explains why the tool is not read-only/idempotent: 'A live answer uses one site lookup from the monthly plan allowance; `usage` says if it was charged and how many are left' — a cost/rate-limit disclosure the annotations cannot express. It also discloses interpretation hazards ('Missing facts are not surveyed or unavailable, never zero'; 'Envelope numbers are extracted ceilings') that materially affect how results are reported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the single-address constraint are front-loaded, and most sentences carry actionable content (status handling, citation formats, conformance semantics). It is dense and long, with citation-format rules and envelope caveats packed into one undifferentiated block, which slightly hurts scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description takes on responsibility for return-value interpretation and does so thoroughly (status values, missing-vs-zero, citation requirements, lot conformity logic). The `source` parameter's role in attribution is left to the schema, a minor gap for a high-complexity tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents all three parameters well, including examples and the `context` privacy constraint. The description only reinforces the `address` constraint (one per call, no search) and never mentions `source` or `context`, so it adds little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Look up lot, zone, and building envelope for one street address in Canada or the US.' The 'One address per call; cannot search or compare' clause immediately separates it from batch siblings like screenLots and runFeasibilityAnalysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Explicit routing rules: call `explainFeasibilityStatus` before interpreting `not_extracted`/`site_specific_schedule`, call `getBylawSection` before treating an envelope figure as available on the lot, and use `getBuckyMcpGuide` for the free allowance check. It also names an explicit don't ('Do not fetch `zone.bylawSourceUrl`').

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

getProjectContextGet project context bundleA
Read-onlyIdempotent
Inspect

Load one project with analysis envelope, compact agentStatus, document summaries, evidence summaries, the project memory digest, and external_ref when the project was imported from another system. Pass include for optional sections: tasks, members, insights, capital, visualEvidence. Default is none, so the payload stays the same as a call without include. Documents and evidence return up to documentsLimit / evidenceLimit (default 20, max 50); each include list returns up to 20. truncation gives total, returned and truncated for every list that can be cut. Writes to those sections stay on the Bucky CLI. You do not need a UUID: pass project with the name the user said, or call with neither and the result lists their projects to choose from. Use before composing reports or after scheduling analysis.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
includeNoOptional extra sections. Default is none, so the payload matches a call without include. tasks, members, insights, capital, and visualEvidence each reuse the matching product read — they are not separate tools. Writes stay on the Bucky CLI.
projectNoProject name to match, when you do not have the UUID. Case-insensitive; an exact name wins over a partial one. Matching more than one lists the candidates instead of guessing.
projectIdNoProject UUID. Omit if you pass `project`.
evidenceLimitNo
documentsLimitNo

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnly, idempotent, non-destructive), it discloses default include=none, per-list return caps with defaults and maxima, that truncation metadata (`total`, `returned`, `truncated`) is supplied for every cuttable list, that ambiguous project names return candidates instead of guessing, and that writes are out of scope. This is exactly the behavioral context the annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with what is loaded, then moves through optional sections, limits, truncation, and the UUID-free path in a logical order with no filler. It is dense but every sentence carries actionable information; the sentence about writes staying on the CLI is the only mild repetition with the `include` schema description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter read tool with no output schema, the description adequately conveys both input behavior (include, limits, project resolution) and output shape (envelope sections, truncation metadata), so an agent can call it and interpret the response without additional docs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% and the two numeric limits have no schema descriptions at all, so the description does real work: it states their default of 20 and max of 50, notes each include list returns up to 20, and explains project-name matching semantics (case-insensitive, exact beats partial, ambiguity lists candidates). The `include` optionality and payload-equivalence with an omitted include are also clarified.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('Load one project') and enumerates the exact contents of the bundle (analysis envelope, agentStatus, document/evidence summaries, memory digest, external_ref). It is clearly distinguishable from siblings like produceProjectReport or uiGetAnalysisStatus, which generate output or report status rather than loading a project context bundle.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

It gives concrete timing guidance ('Use before composing reports or after scheduling analysis') and points write operations to the Bucky CLI, which implicitly scopes this tool to reads. It also explains the no-UUID path (pass `project`, or call with neither to list projects). It stops short of naming a specific sibling to prefer for a given alternative scenario.

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

listSavedlist SavedA
Read-onlyIdempotent
Inspect

List the signed-in user’s saved lots and projects. Returns at most limit rows (default 50, maximum 200), with folder ids and project stages. Use folderId to read one private folder. Copy a lot entry’s id as savedLotId when filing it; lotId identifies its parcel. A saved lot is not a project.

NameRequiredDescriptionDefault
limitNo
offsetNo
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
folderIdNo

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already carry readOnly/idempotent/non-destructive, and the description adds real value on top: a default page size of 50, a hard maximum of 200, and the fact that folder ids and project stages come back. Pagination cursor/offset behavior is left unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the core action then limits, then parameter guidance, then the disambiguation. No filler or redundant restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description does describe the shape of results (folder ids, project stages, lot entries with two distinct ids), which is what an agent needs. Offset semantics and the meaning of 'project stages' remain thin.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% (only context is documented), so the description must compensate and largely does: it explains limit's default and cap, folderId's purpose, and the savedLotId vs lotId distinction. The offset parameter goes unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'List the signed-in user's saved lots and projects.' The closing line 'A saved lot is not a project' preempts a likely conceptual confusion, though it never names the nearest sibling listSavedFolders to distinguish scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

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

Gives one concrete usage instruction ('Use folderId to read one private folder') and a downstream hint about reusing the id as savedLotId. It does not say when to prefer this over listSavedFolders or when to fall back to unsaveLot/saveToProject, leaving sibling selection implicit.

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

listSavedFolderslist Saved FoldersB
Read-onlyIdempotent
Inspect

List the signed-in user’s private folders, most recently used first, with item counts. Returns at most limit rows (default 50, maximum 200). Folders can contain saved lots and projects from different places.

NameRequiredDescriptionDefault
limitNo
offsetNo
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real context on top: sort order, that rows include item counts, and that folders aggregate lots and projects from different places. It does not disclose whether more rows exist beyond the limit or how paging behaves, which is the remaining behavioral gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and scope; the padding and counting details follow naturally. The final sentence on folder contents earns its place by clarifying what a folder is.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With readOnly annotations and no output schema, the safety and return-shape burden is light, and the description covers ordering and counts. But pagination semantics (offset, whether a total is returned, what an empty list looks like) are missing, leaving an agent unable to page confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% - just the context analytics parameter is documented. The description restates limit's default and maximum (already in the schema, so no added value) but says nothing at all about offset, which is the parameter an agent needs to understand to page through folders. The low-coverage case requires the description to compensate and it does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the signed-in user's private folders') plus the ordering and returned fields (most recently used first, with item counts). It implies the user-private scope that separates it from the broader listSaved sibling, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

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

Usage is implied rather than stated: an agent can infer this is the browse entry point for folders that feed addSavedFolderItem/removeSavedFolderItem, but nothing says when to prefer it over listSaved or how to page through results. No exclusions or prerequisites are given.

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

previewSiteCoveragePreview what Bucky has on file for an addressA
Read-onlyIdempotent
Inspect

Free preview, no sign-in needed. For one street address in Canada or the US, it says whether Bucky covers the place and which zoning facts it holds for the lot (lot boundary, zone, height, density, setbacks, permitted uses, overlays, parking): found, partly on file, or not on file. It returns no values: no zone code, heights, setbacks or areas. The lot outline is a shape with no scale. Use it when the user is not signed in and asks what they can build at an address. For the numbers, call getFeasibilitySnapshot. That call asks the user to sign in.

NameRequiredDescriptionDefault
addressYesStreet address to analyse, e.g. "4170 Sophia St, Vancouver BC".
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already cover safety (readOnly, idempotent, non-destructive, openWorld), yet the description still adds non-obvious behavior: the call is free and requires no sign-in, it returns presence status (found / partly on file / not on file) rather than values, and the lot outline is an unscaled shape. This prevents an agent from misreading the result as real dimensional data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the two facts an agent needs most (free, no sign-in), then scope, then the negative space (no values returned), then routing to the sibling. Every sentence carries distinct information; nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must carry the return semantics — and it does, spelling out the three coverage statuses and explicitly warning that no zone codes, heights, setbacks or areas come back. Combined with the geographic scoping and the sign-in routing, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the address format and the analytics-only 'context' parameter are already documented. The description still adds a real constraint the schema lacks: exactly one address, restricted to Canada or the US. It adds nothing about the 'context' parameter, but the schema handles that thoroughly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: a free, no-sign-in preview of what coverage/zoning facts exist for one street address. It enumerates the facts checked (lot boundary, zone, height, density, setbacks, permitted uses, overlays, parking) and explicitly contrasts itself with getFeasibilitySnapshot, so an agent can separate it from siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Gives an explicit use condition — 'when the user is not signed in and asks what they can build at an address' — plus the alternative and its consequence: 'For the numbers, call getFeasibilitySnapshot. That call asks the user to sign in.' Both the when and the when-not are stated.

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

produceProjectReportCompose and export a project report PDFAInspect

Compose a project report PDF. Pass projectId or project; with neither, the result lists projects and no meter is spent. preview=true composes without spending. confirm=true exports, spends records.exports, and is irreversible. Returns a signed download URL, never PDF bytes.

NameRequiredDescriptionDefault
detailNodetailed
confirmNoWhen true, compose (if needed), save, export PDF, and return a download URL. Required when preview is false. Spends records.exports and cannot be undone.
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoWhen true, compose only — no export meter spend and no download URL.
projectNoProject name to match, when you do not have the UUID. Case-insensitive; an exact name wins over a partial one. Matching more than one lists the candidates instead of guessing.
requestNo
audienceNoowner
planNameNo
projectIdNoProject UUID. Omit if you pass `project`.

TDQS

A4.4/5.0
Behavior5/5

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

The description carries full behavioral disclosure: meter spend on records.exports, irreversibility of export, the listing fallback, and the concrete return shape (signed download URL, never PDF bytes). This goes well beyond the {readOnlyHint:false, destructiveHint:false, openWorldHint:true} annotations; the 'irreversible' note is consistent with an additive, non-destructive export rather than a contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then progressively discloses the decisions that matter (project selection, preview vs confirm, spend/return). Every sentence earns its place; no redundant restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Strong for a 9-parameter mutation tool with no output schema — return format, cost, and reversibility are all covered. The remaining gap is the opaque `request` parameter and the unexplained content-shaping params (audience, detail, planName).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds real meaning for the key params (projectId/project resolution, the preview/confirm coupling) and even documents the no-project fallback that the schema lacks. However, it leaves `request`, `audience`, `detail`, and `planName` unaddressed, and `request` has no schema description at all, so the agent cannot infer its role.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Compose a project report PDF,' which clearly distinguishes this from analysis/context siblings. However, it does not explicitly compare itself to any sibling tool, leaving that differentiation to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Explicitly defines the operating modes: pass projectId or project, get a project listing with no spend if neither, preview=true to compose without spending, and confirm=true to export and spend. An agent knows precisely which path to take for each goal.

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

proposeResultFlagsPropose "not a fit" on saved-search resultsA
Idempotent
Inspect

Suggest that results of one saved search are not a fit, for the user to confirm or reject on the result row. Signed-in only; write scope. Pass profileId and 1–25 proposals { lotId, reasonCode, evidence }. lotId comes from screenLots with that profileId. reasonCode is existing_use, zoning_wrong, lot_size_shape_access, already_developed, environmental, other, or the lot’s own typology: / existing_use_class:. evidence says in a few words what you saw, e.g. "assessor use: assisted living". A proposal changes nothing until the user confirms it: it hides no lot, changes no alert and teaches the search nothing. Tell the user what you proposed and that they confirm it on the list. Returns results with { lotId, proposed: true, flagId } or { lotId, proposed: false, skipped }. skipped is already_flagged, declined (the user said no: never propose it again), not_in_search, reason_mismatch or limit. pending gives open proposals and the limit (25 per search); at the limit, wait for the user to answer. Not for feedback about Bucky (submitBuckyFeedback). preview=true returns the request and proposes nothing.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to see the request without proposing anything.
profileIdYesSaved search (screening profile) id.
proposalsYes

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=true) by explaining exactly what is and isn't changed: "it hides no lot, changes no alert and teaches the search nothing." It discloses auth requirements, the 25-per-search cap, dedup behavior via skipped=already_flagged, and enumerates the full skipped vocabulary so the agent can interpret partial failure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the human-confirmation caveat are front-loaded, then progressively finer detail (params, non-effects, return shape, limits). It is a single dense paragraph that is longer than the minimum, with a few sentences that duplicate the schema, but almost every sentence carries operational weight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates fully by documenting the return shape: results with { lotId, proposed, flagId } or { lotId, proposed: false, skipped } plus the pending/limit object. Combined with the auth, limit and side-effect disclosures, an agent has everything needed to call this correctly and interpret the response.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, and the description adds real value by stating provenance ("lotId comes from screenLots with that profileId") and that evidence is a short free-text observation, not a verdict. Some content (the reasonCode list, the 1–25 bound, preview behavior) merely restates the schema, so it adds lineage rather than fully new semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: "Suggest that results of one saved search are not a fit", and immediately clarifies the human-in-the-loop nature ("for the user to confirm or reject on the result row"). It explicitly disambiguates from sister tools (submitBuckyFeedback) and names screenLots as the source of lotId, so an agent can distinguish it from siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Strong operational guidance: signed-in only, write scope, preview=true proposes nothing, "never propose it again" for declined lots, and at the 25-per-search limit "wait for the user to answer". It names an explicit alternative to avoid (submitBuckyFeedback) and a prerequisite source (screenLots). What it lacks is an explicit trigger statement for when a lot should be judged "not a fit" beyond the reason codes.

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

removeSavedFolderItemremove Saved Folder ItemA
Idempotent
Inspect

Remove exactly one saved lot or project from a private folder. Pass folderId and target with savedLotId or projectId. The lot stays saved and the project is kept. Use preview=true first.

NameRequiredDescriptionDefault
targetYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.
folderIdYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare destructiveHint=false and idempotentHint=true; the description adds the crucial side-effect context that 'The lot stays saved and the project is kept,' which is exactly the behavioral detail annotations cannot express. It does not cover failure cases, such as what happens if the item is not in the folder or lacks permission.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action and scope, then the parameter guidance, then the safety step. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers scope, parameters, side effects, and a preview path, which is close to complete. Remaining gaps are error/idempotency specifics and folder-membership preconditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%, and folderId has no schema description at all, but the description compensates by explaining that 'target' is a discriminated object taking either savedLotId or projectId, which the schema alone conveys only structurally. This is meaningfully more than the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Remove exactly one saved lot or project from a private folder') and the 'exactly one' scoping distinguishes it from bulk operations. It also implicitly separates itself from deleteSavedFolder by noting the item is merely detached from the folder, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

'Use preview=true first' gives an explicit precondition for safe invocation, and the two target variants (savedLotId or projectId) tell the agent which branch of the union to use. It stops short of stating when to prefer deleteSavedFolder or unsaveLot instead.

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

renameSavedFolderrename Saved FolderA
Idempotent
Inspect

Rename a private folder by folderId. Pass name and use preview=true first to inspect the request without writing.

NameRequiredDescriptionDefault
nameYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.
folderIdYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare the safety profile (not read-only, non-destructive, idempotent), and the description adds the dry-run preview workflow, which is genuinely useful. It does not disclose permissions required to rename, whether the old name is recoverable, or what happens to folder contents, so it adds only moderate value beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no waste; the operation and its identifier are front-loaded, and the preview recommendation follows immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple mutation with no output schema and three required parameters, the definition plus annotations cover the essentials: what changes, how to target it, and how to dry-run it safely. Minor gaps remain around permission requirements and the unexplained name length constraint.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: context is fully documented in the schema and preview is described identically there, while name and folderId carry no schema descriptions. The description identifies folderId as the folder selector and reinforces preview, but adds nothing about name constraints (1-120 chars) or the analytics-only nature of context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Rename a private folder") and names the identifier (folderId), which is clearly distinct from createSavedFolder, deleteSavedFolder, and listSavedFolders by verb alone. It does not explicitly contrast with siblings, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Gives actionable usage guidance: supply name, and call with preview=true first to inspect the request before writing. It does not state when to prefer an alternative tool or any preconditions (e.g. ownership of the folder), which keeps it below a 5.

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

runFeasibilityAnalysisRun project feasibility analysisAInspect

Enqueue a fresh deterministic analysis run for a saved project. Pass projectId, or project with the name the user said; with neither, the result lists their projects and nothing is queued. Returns immediately with agentStatus (queued, running, current, failed, or none) and a receipt id; does not block on completion. Irreversible: a queued run cannot be un-queued from MCP. Re-check with getProjectContext, but no more than once every 15 seconds — it is a multi-query bundle, not a status endpoint.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
projectNoProject name to match, when you do not have the UUID. Case-insensitive; an exact name wins over a partial one. Matching more than one lists the candidates instead of guessing.
projectIdNoProject UUID. Omit if you pass `project`.

TDQS

A4.6/5.0
Behavior5/5

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

Adds substantial context beyond annotations: non-blocking return, the full agentStatus enum, a receipt id, and the key irreversibility warning that a queued run cannot be cancelled from MCP. That irreversibility caveat is exactly the kind of thing destructiveHint=false and idempotentHint=false cannot convey on their own, and it is consistent with them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action in the first sentence, then layers the conditional parameter behavior, return contract, and polling guard in descending order of importance. No sentence is filler and nothing is repeated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the needed work by naming the return fields and their possible values. It leaves unspecified what the analysis itself yields and how a typical run duration should be communicated to a user, which matters for a non-blocking operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already carries the per-parameter detail, but the description adds the cross-parameter semantics that matter: projectId vs project name precedence and the neither-supplied branch. The `context` analytics parameter is left unmentioned in prose, which is fine given the schema documents it fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Enqueue a fresh deterministic analysis run for a saved project') and implicitly separates itself from siblings like getFeasibilitySnapshot and explainFeasibilityStatus, which read rather than enqueue. The agent can tell what it produces (a queued run) without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

Explicitly routes the follow-up check to getProjectContext and warns against using it as a poll endpoint more than once per 15 seconds, and describes the no-identifier fallback (lists projects, nothing queued). It stops short of saying when not to enqueue at all, e.g. when agentStatus is already 'current' and a snapshot read would suffice.

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

saveLotsave LotA
Idempotent
Inspect

Save one parcel by lotId without creating a project or running analysis. Copy lotId from a screenLots lot or assembly lot. Saving it again keeps the same save. Use preview=true first to inspect the request without writing.

NameRequiredDescriptionDefault
lotIdYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the description isn't carrying the safety burden. It still adds real value by spelling out that no project is created and no analysis is run, and by giving the idempotency hint concrete meaning ('Saving it again keeps the same save').

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and its scope, followed by the identifier source and the preview workflow. Nothing is redundant or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description covers the essential call contract: single-parcel save, idempotency, no side effects beyond saving, and a dry-run option. It could say slightly more about where the saved lot surfaces (listSaved/saved folders), but nothing critical to invoking it is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, with lotId carrying only format/pattern and no prose. The description compensates by telling the agent where a valid lotId comes from (a screenLots lot or assembly lot) and by restating the dry-run meaning of preview=true.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('Save one parcel by lotId') and bounds the scope by excluding project creation and analysis runs, which separates it from saveToProject and runFeasibilityAnalysis. It never names those siblings outright, so the differentiation is inferred rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

It gives a concrete prerequisite ('Copy lotId from a screenLots lot or assembly lot'), states the repeat-call behavior, and recommends 'Use preview=true first'. What's missing is an explicit statement of when to choose saveToProject instead of this tool for project-scoped saving.

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

saveToProjectCreate or attach to a projectAInspect

Create a project (create), attach lots (attach_parcels), or attach a knowledge reference (attach_reference). Pass projectId or project; with neither, the result lists projects and writes nothing. For attach_parcels, pass a WGS84 GeoJSON polygon (up to 500 selected parcels), or copy lot.parcelExternalId from getFeasibilitySnapshot. Polygon cannot be combined with parcelExternalIds or radiusM. Results report source truncation and attached count. preview=true returns the diff and writes nothing. A write returns a receipt. Not reversible on this surface.

NameRequiredDescriptionDefault
latNoLatitude from getFeasibilitySnapshot. Supplied coordinates are never re-geocoded.
lngNoLongitude from getFeasibilitySnapshot.
nameNo
roleNobuild is the lot being developed; context is surrounding land. Default build.
actionYescreate: new project from a site. attach_parcels: attach lots to an existing project (use lot.parcelExternalId from getFeasibilitySnapshot). attach_reference: link a knowledge section to an existing project.
addressNoStreet address of the site. On `create` this is geocoded server-side when lat/lng are not supplied, and is what gets recorded as the project address.
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
polygonNoWGS84 GeoJSON Polygon for attach_parcels. Attach the parcels selected by the product area flow, up to 500. Interior rings exclude parcels. Use polygon instead of parcelExternalIds and radiusM. Maximum 512 coordinates.
previewNoWhen true, return the field-level diff and write nothing.
projectNoProject name to match instead of a UUID, for attach_parcels and attach_reference. Matching more than one lists the candidates instead of guessing. Ignored by create.
radiusMNoSearch half-width in metres when resolving parcel ids. Default 150.
projectIdNoExisting project UUID. Required by attach_parcels and attach_reference unless you pass `project`; ignored by create.
externalRefNoProvenance of an imported project. Canonical form is `<system>:<id>` (e.g. `notion:<page-id>`). Unique per creator when set. Returned on getProjectContext. Distinct from idempotencyKey.
sectionUuidNo
idempotencyKeyNo
parcelExternalIdsNoSource parcel ids to attach. Copy lot.parcelExternalId from getFeasibilitySnapshot. If they are not in the current area, pass a larger radiusM on attach_parcels.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already establish readOnly=false, destructive=false, idempotent=false, openWorld=true, but the description adds real value beyond them: preview returns a field-level diff and writes nothing, a write returns a receipt, results report source truncation and attached count, and changes are not reversible on this surface. The 'not reversible' caveat sits in mild tension with destructiveHint=false without quite contradicting it (attaching parcels adds rather than destroys data). Permission or auth requirements and failure modes are not disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded: the action enum and ID routing come first, then mode-specific constraints, then preview and return behavior. Every sentence carries facts, though the middle section packs polygon, parcelExternalIds, radiusM, truncation, preview, and receipts into a single run-on stretch that is harder to scan than the opening.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter mutation with no output schema, the description covers the critical call paths and return signals (diff, receipt, attached count, truncation). Remaining gaps are per-action parameter applicability and error behavior, which for openWorld=true calls an agent would want spelled out.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 81% schema coverage the schema carries most of the load, but the description still adds meaning: polygon vs parcelExternalIds vs radiusM are explicitly exclusive, the 500-parcel selection cap is stated, and parcelExternalIds are sourced from lot.parcelExternalId on getFeasibilitySnapshot. It does not explain which of the sixteen parameters belong to which action (name, address, externalRef, sectionUuid, idempotencyKey are left to the schema).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description immediately names the three concrete operations (create, attach_parcels, attach_reference) and what each touches, so the agent knows exactly what resource is being acted on. It falls short of a 5 because it never distinguishes itself from the write-side siblings (updateProject, createSavedFolder), leaving the agent to infer boundary cases such as modifying an existing project.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

It gives explicit routing rules: pass projectId or project, and with neither the call degrades to listing projects and writing nothing. It also names mutually exclusive parameter combinations (polygon cannot be combined with parcelExternalIds or radiusM) and offers preview=true as the non-writing alternative. This is when/when-not guidance with alternatives, not just context.

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

screenLotsFind lots that match a listAInspect

Find the lots in one live Bucky city that match a list. Pass city or geoDivisionId with thesis (plain words), criteria (square feet, dollars), or both; or pass a saved profileId. Returns countOutcome (exact, partial, at_least, estimate, or unavailable), screeningRunId, and selected lots ranked largest first with a pass, fail, or not_available verdict per filter. totalMatches is a compatibility value and can be returned-page size when the total is unavailable. Report a not_available filter; never present the count as filtered by it. The execution preserves selection for optional candidate assessment; assessment candidate counts are separate from search totals. Returns candidates, counted suggestions and savedMatches. Candidate/suggestion criteria use the same square-foot boundary as the input, including canonical registry values and strategies. Present these alternatives before asking to save. Pass the selected criteria with save=true only after explicit approval, without re-reading the thesis. Each lot has lotId for saveLot, address for getFeasibilitySnapshot and parcelExternalId for saveToProject. Assembly lots carry the same ids. At most 25 lots per call (limit, default 10). page says which matches these are (offset, returned, total, truncated); when truncated, call screenLots with page.next for the next lots. Paging reads only: it saves nothing and uses no list quota. save=true saves the list (write scope, counts against the plan list limit) and returns a CSV link of every match; the CSV needs a saved list, so links.csv is null without one.

NameRequiredDescriptionDefault
cityNoCity as the user said it, e.g. "Laval" or "Bedford, MA". Omit when you pass geoDivisionId or profileId.
saveNotrue saves the list to the account. Default false. Search execution history is recorded.
sortNoOrder of the returned lots across every match. Default lot_area_desc (largest first). land_value_per_buildable_asc / assessed_value_per_buildable_asc: lowest assessed land (or total) value per buildable sq ft first, for "cheapest land per buildable foot". Lots with no cited FSR or usable assessment come last.
limitNoLots to return. Default 10, at most 25 per call; page.next reads the next lots. countOutcome states whether the total is exact, partial, at_least (a lower bound), estimate (about), or unavailable.
cursorNoNext page of the same box. Copy page.next from the prior result: it carries the cursor with the box. Do not combine with thesis. Reads only; nothing is saved.
thesisNoThe list in plain words, e.g. "industrial lots over half an acre outside the floodplain".
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
hygieneNoDefault true. Ad-hoc lists leave out public owners (owner_class), cap lot size at 5 acres and ignore assessed values under $100,000 where the city stores them, unless criteria set the same field. Each default is named in notes. false skips them. Ignored with profileId: a saved list runs as saved.
assemblyNoAssembly mode: also return candidate assemblies, 2 to maxLots adjacent lots that each pass criteria and together meet minCombinedAreaSqft and/or minCombinedFrontageFt. Use for "two or three adjacent lots that combine to 10,000 sf"; put per-lot limits in criteria and the combined size here, not in minAreaSqft.
criteriaNoStructured criteria. A field set here replaces the same field read from thesis.
saveNameNoName for a saved list.
profileIdNoSaved list id. Runs the saved city and criteria. Do not combine with city, thesis, or criteria.
geoDivisionIdNoDivision id, from an earlier screenLots or cityInventory result.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the annotations, it discloses that save=true writes a saved list, counts against the plan list limit, and returns a CSV link; paging is read-only and saves nothing; search execution history is recorded; hygiene defaults apply; and not_available filters must be reported. These are meaningful behavioral details that annotations alone do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose, but it then becomes a dense, run-on block covering returns, candidate assessment, save workflow, paging, IDs, and quotas. Most sentences carry information, but the lack of paragraph breaks and the cryptic clauses make it harder to scan than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 13-parameter tool with no output schema, the description does a good job describing the returned fields (countOutcome, screeningRunId, verdicts, totalMatches, candidates, suggestions, savedMatches, CSV link) and the save/paging behaviors. Some return structures remain only loosely specified, but the core behavioral contract is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds valuable cross-parameter workflow semantics: city/geoDivisionId must be paired with thesis or criteria, profileId is an alternative saved-list mode, save requires explicit approval, and page.next drives paging. It stops short of fully explaining every nested criteria interaction, but it meaningfully exceeds the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource (find lots) and scope (one live Bucky city matching a list). It is clearly a screening/search tool, and the cross-references to saveLot, getFeasibilitySnapshot and saveToProject further distinguish it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

The description gives clear invocation context: pass city or geoDivisionId with thesis, criteria, or both; or pass profileId; save only after explicit approval; use page.next when truncated. It does not explicitly name when to choose this over sibling tools like cityInventory or findPlacesByMarket, so it lacks exclusions/alternatives for a 5.

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

setProjectMapListingList or unlist a project on the public mapA
Idempotent
Inspect

Put a project on the public Bucky map, or take it off. Pass projectId, or project with the name the user said; with neither, the result lists their projects and nothing is published. Listing publishes the build-lot centroid, the project name, its zone category, typology and lifecycle status to anyone — signed in or not. Nothing else about the project is published. The project must have a build lot with a centroid; a project that has only an address and no attached build parcel cannot be pinned. Ask the human before listing a site that is not already public knowledge. A client, a friend, or a private residence is theirs to publish, not yours. preview=true returns the current state, the exact pin that would be published, and any privacy warning, and writes nothing. Unlisting removes the pin but does not un-share anything already collected while it was public. To undo, call again with listed set to the opposite value (listed: false after listing); the result repeats this as undo.

NameRequiredDescriptionDefault
listedYestrue lists the project on the public map; false removes it. Listing publishes the build-lot centroid and the project name to anyone, signed in or not.
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoWhen true, return the current listing state, the pin that would be published, and any privacy warning, and write nothing.
projectNoProject name to match, when you do not have the UUID. Case-insensitive; an exact name wins over a partial one. Matching more than one lists the candidates instead of guessing.
projectIdNoProject UUID. Omit if you pass `project`.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only say openWorld and idempotent; the description goes well beyond them by naming the exact fields made public, the prerequisite (a build lot with a centroid, not address-only), and the asymmetry that unlisting 'does not un-share anything already collected while it was public.' That last point is a real irreversibility caveat an agent cannot get from destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then scope, prerequisites, safety gate, and undo — a sensible order. It is dense rather than padded, though lines like 'A client, a friend, or a private residence is theirs to publish, not yours' spend words on tone that a shorter imperative could carry.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still tells the agent what to expect back: preview returns current state, the exact pin, and privacy warnings; the result carries an `undo` field. Combined with the publish-set and undo semantics, an agent can invoke this correctly and interpret the response.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds semantics the schema lacks: the neither-identifier behavior (list projects, publish nothing) and the preview/write-nothing contract. It restates `project` and `projectId` matching rules already in the schema, which caps it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb pair and resource ('Put a project on the public Bucky map, or take it off') that no sibling tool shares — none of the saved-folder, feasibility, or report tools touch public publication. It also defines the publishing scope (centroid, name, zone, typology, lifecycle) so an agent knows exactly what the operation changes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Explicit routing between `projectId` and `project`, an explicit no-identifier fallback ('with neither, the result lists their projects and nothing is published'), an explicit preview-first path, a human-approval gate for non-public sites, and an explicit undo path ('call again with `listed` set to the opposite value'). This is when-to-use and when-not guidance at a high standard.

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

submitBuckyFeedbackSubmit feedback to BuckyAInspect

Open a human-reviewed feedback form and submit it to the Bucky product team. Call only when the user explicitly asks to send feedback, report a problem, suggest an improvement, or praise something. The server asks the MCP client to show the form; nothing is saved unless the human accepts it. Do not use for silent agent self-reporting.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
submissionIdNoOptional. A UUID for this submission; generated server-side when omitted. Pass the same UUID when retrying this exact feedback so it is not recorded twice.
affectedToolNameNoTool the user is commenting on, when already known

TDQS

A4.5/5.0
Behavior4/5

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

Annotations declare readOnlyHint=false, destructiveHint=false, openWorldHint=false and idempotentHint=false, but the description adds genuinely non-obvious behavior: the server asks the MCP client to render the form, and nothing persists unless the human accepts it. That is the key safety fact an agent needs. It stops short of covering retry/deduplication behavior, which is stranded in the submissionId parameter instead.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences: what it does, when to call it, what happens on the server, and the exclusion. The exclusion is placed last as a guard rather than buried mid-paragraph, and nothing is repeated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter tool with complete schema coverage and no output schema, the description covers purpose, trigger conditions, the human-in-the-loop flow, and the no-persistence guarantee. An agent has everything needed to decide to call it and what to expect afterward.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented in structured form, and the description adds nothing about them. Baseline 3 applies since the schema carries the full burden, including the idempotency semantics for submissionId.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Open a human-reviewed feedback form and submit it to the Bucky product team.' No sibling tool does anything similar, and the human-reviewed framing distinguishes it from any programmatic reporting path.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Gives explicit activation conditions ('only when the user explicitly asks to send feedback, report a problem, suggest an improvement, or praise something') and an explicit exclusion ('Do not use for silent agent self-reporting'). Both the when and the when-not are stated, not inferred.

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

uiGetAnalysisStatusGet analysis statusA
Read-onlyIdempotent
Inspect

Return only the analysis agentStatus for a project. Cheap enough to poll. Used by the Bucky app view; the model should call getProjectContext instead.

NameRequiredDescriptionDefault
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
projectIdYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely new behavioral information the annotations cannot carry: it returns a single field, and it is cheap enough to poll. It stops short of saying what values agentStatus can take or what happens for a project with no analysis.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero filler, with the return scope and the cost hint front-loaded ahead of the routing instruction. Every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a trivial two-parameter read tool, the definition covers purpose, cost, output shape and the correct alternative, and the annotations cover safety. The remaining gap is minor: no indication of the possible `agentStatus` values or behavior on a project without an analysis run.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: `context` is fully documented in the schema, while `projectId` has only a UUID format. The description's 'for a project' weakly signals projectId's role but adds no format or selection guidance. Baseline 3 is appropriate since the schema does half the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (return only the analysis `agentStatus` for a project) plus an explicit scope limit ('only'). It also names the sibling it should not be confused with (getProjectContext), so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Provides an explicit when-not/alternative: it is 'Used by the Bucky app view; the model should call getProjectContext instead.' The polling cost cue ('cheap enough to poll') gives an additional condition under which this tool is appropriate.

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

unsaveLotunsave LotA
DestructiveIdempotent
Inspect

Unsave one parcel by lotId. This also removes that saved lot from every folder. Projects are kept. Use preview=true first; this MCP tool does not provide Undo.

NameRequiredDescriptionDefault
lotIdYes
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoUse true to inspect the request without writing.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the destructiveHint=true and idempotentHint=true annotations, the description discloses three important facts: the unsave cascades to every saved folder, projects are preserved, and the action is irreversible because there is no undo. As a result, the agent knows the extent of the side effects and the data that survives.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is three short sentences with no filler. The scope and cascade effect come first, then the recommended preview workflow. Every sentence adds new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with no output schema and annotations that already cover safety, the description supplies the missing impact details and the preview-first requirement. The only gap is post-condition behavior on invalid or already-unsaved lotIds, which the description does not cover.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%: context and preview are already documented in the schema, so the description's only contribution is behavioral framing, not parameter meaning. The description does not explain what a lotId identifies or what happens when it is unknown or already unsaved, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Unsave one parcel by lotId', which makes it clear this is the inverse of saveLot. It also makes clear that the operation only affects the saved-lot entry, not the project, so an agent can distinguish it from saveToProject or removeSavedFolderItem.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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

It states a concrete prerequisite workflow: 'Use preview=true first', and it states an exclusion: 'this MCP tool does not provide Undo'. This is strong guidance, though it never names or explicitly routes to a sibling such as removeSavedFolderItem when the agent only wants to detach from a folder.

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

updateProjectUpdate project fieldsA
Idempotent
Inspect

Patch project metadata (name, lifecycle status, externalRef). Pass projectId, or project with the name the user said; with neither, the result lists their projects and nothing is written. preview=true returns the field-level diff and writes nothing. A write returns a receipt; undoOperationId restores the captured prior fields. Does not archive or delete.

NameRequiredDescriptionDefault
nameNo
contextYesExplain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution."
previewNoWhen true, return the field-level diff and write nothing. Combined with undoOperationId, returns the stored receipt.
projectNoProject name to match, when you do not have the UUID. Case-insensitive; an exact name wins over a partial one. Matching more than one lists the candidates instead of guessing.
projectIdNoProject UUID. Omit if you pass `project`.
externalRefNoProvenance of an imported project. Canonical form is `<system>:<id>` (e.g. `notion:<page-id>`). Unique per creator when set. Pass null to clear.
lifecycleStatusNoProject stage. getProjectContext returns it as lifecycleStatus.
undoOperationIdNoReceipt id from a prior updateProject write. Restores the captured prior fields. With preview=true, inspects the receipt instead.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already flag non-readonly, non-destructive, idempotent, open-world; the description adds real behavior beyond them: preview returns a field-level diff and writes nothing, a write returns a receipt, undoOperationId restores captured prior fields, and ambiguous name matches list candidates rather than guessing. That is exactly the mutation-safety context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the patched fields, then identification rules, then preview/undo semantics. No filler and no repetition of schema text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With eight parameters, no output schema, and a mutation entry point, the description still covers identification, dry-run, receipt/undo, and return shape ('a write returns a receipt'). Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 88%, so the baseline is 3; the description additionally explains the projectId-vs-project decision, the preview-plus-undoOperationId interaction, and the no-identifier listing fallback. Minor gap: it does not say whether name/lifecycleStatus/externalRef are partial-patch optional or wholesale replacements.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource plus the exact patchable fields (name, lifecycleStatus, externalRef), and adds an explicit scope exclusion ('Does not archive or delete'). An agent can tell this apart from renameSavedFolder/deleteSavedFolder/saveToProject style siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

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

Gives explicit routing rules: use `projectId`, or `project` with the spoken name, and states the fallback behavior when neither is supplied (lists projects, writes nothing). Also states preview=true and undoOperationId call conditions and the archive/delete exclusion.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updates
    • ChangedgetFeasibilitySnapshot1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "address",
        -  "source",
        -  "context"
        -]New value: +[
        +  "address",
        +  "context"
        +]
    • ChangedgetProjectContext1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "documentsLimit",
        -  "evidenceLimit",
        -  "include",
        -  "context"
        -]New value: +[
        +  "context"
        +]
    • ChangedproduceProjectReport1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "audience",
        -  "detail",
        -  "preview",
        -  "confirm",
        -  "context"
        -]New value: +[
        +  "context"
        +]
    • AddedproposeResultFlags
    • ChangedsaveToProject2 fields changed
      • removedInput schema / properties / polygon / additionalProperties
        Removed value: -false
      • changedInput schema / required
        Previous value: -[
        -  "action",
        -  "preview",
        -  "context"
        -]New value: +[
        +  "action",
        +  "context"
        +]
    • ChangedscreenLots4 fields changed
      • changedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / typology / description
        Previous value: -"Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match."New value: +"Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match any_of. none_of keeps lots whose typology is unknown."
      • changedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / use_sector / description
        Previous value: -"Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments."New value: +"Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments. none_of keeps lots whose sector is unknown."
      • changedInput schema / properties / criteria / properties / typology / description
        Previous value: -"Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match."New value: +"Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match any_of. none_of keeps lots whose typology is unknown."
      • changedInput schema / properties / criteria / properties / use_sector / description
        Previous value: -"Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments."New value: +"Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments. none_of keeps lots whose sector is unknown."
    • ChangedsetProjectMapListing1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "listed",
        -  "preview",
        -  "context"
        -]New value: +[
        +  "listed",
        +  "context"
        +]
    • ChangedupdateProject1 field changed
      • changedInput schema / required
        Previous value: -[
        -  "preview",
        -  "context"
        -]New value: +[
        +  "context"
        +]
  2. 4 tool updates
    • ChangedfindPlacesByMarket2 fields changed
      • changedInput schema / properties / country / description
        Previous value: -"ISO country code. CA has market data today; US follows."New value: +"ISO country code. Places are filtered and ranked only within this country."
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Matched places to skip. Copy truncation.places.nextOffset for the next page.",
        +  "maximum": 10000,
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • ChangedgetBylawSection1 field changed
      • addedInput schema / properties / textOffset
        Added value: +{
        +  "description": "Character to start each section at. Default 0. Copy nextOffset from a truncated section to read the rest.",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • ChangedscreenLots18 fields changed
      • addedInput schema / properties / assembly
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assembly mode: also return candidate assemblies, 2 to maxLots adjacent lots that each pass criteria and together meet minCombinedAreaSqft and/or minCombinedFrontageFt. Use for \"two or three adjacent lots that combine to 10,000 sf\"; put per-lot limits in criteria and the combined size here, not in minAreaSqft.",
        +  "properties": {
        +    "maxLots": {
        +      "description": "Most lots in one assembly, 2 to 5. Default 3.",
        +      "maximum": 5,
        +      "minimum": 2,
        +      "type": "integer"
        +    },
        +    "minCombinedAreaSqft": {
        +      "description": "Combined lot area the assembly must reach, in square feet.",
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "minCombinedFrontageFt": {
        +      "description": "Combined frontage the assembly must reach, in feet: the sum of derived lot widths, an estimate.",
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "sameZone": {
        +      "description": "same (default): every lot in one zone code. family: one zone family. any: zones may differ.",
        +      "enum": [
        +        "same",
        +        "family",
        +        "any"
        +      ],
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / assessed_value_per_buildable
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assessed total value (land and buildings) divided by the buildable floor area (lot area x the zone’s cited maximum FSR), in currency per square metre of floor area, inclusive bounds ($150 per sq ft = 1,614.59 per m²). Lots without a cited FSR or a usable assessment never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / assessed_value_per_buildable
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assessed total value (land and buildings) divided by the buildable floor area (lot area x the zone’s cited maximum FSR), in currency per square metre of floor area, inclusive bounds ($150 per sq ft = 1,614.59 per m²). Lots without a cited FSR or a usable assessment never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / dwelling_count
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Dwellings on the lot, as the assessment roll states them (Montréal: nombre de logements). \"A single-family house\" is { min: 1, max: 1 }; \"duplex or triplex\" is { min: 2, max: 3 }. Lots whose roll states no count never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / land_value_per_buildable
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assessed land value divided by the buildable floor area (lot area x the zone’s cited maximum FSR), in currency per square metre of floor area, inclusive bounds ($150 per sq ft = 1,614.59 per m²). Lots without a cited FSR, a land/improvement split or a usable assessment never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / lot_depth
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres. A frontage the city publishes, else the side of the lot outline's oriented bounding rectangle.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / lot_width
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres. A frontage the city publishes, else the side of the lot outline's oriented bounding rectangle.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / owner_class / description
        Previous value: -"Owner class of the titled parcels on the lot, from ParcelMap BC owner type: private, municipal, provincial, federal, crown_agency, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency). A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search."New value: +"Owner class of the lot, from ParcelMap BC owner type or an open assessment roll: private, municipal, provincial (or state), federal, crown_agency (or public agency), public_other, institutional (religious, charitable, education, health), first_nations, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency, public_other). Institutional and First Nations land is not public. A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search."
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / tax_exempt
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "true: the assessment roll classes the property as exempt from property tax (public, religious, charitable and similar owners). { is: false } keeps taxable lots only. Read from rolls that state both values; personal exemptions (senior, veteran) do not count.",
        +  "properties": {
        +    "is": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "is"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / dwelling_count
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Dwellings on the lot, as the assessment roll states them (Montréal: nombre de logements). \"A single-family house\" is { min: 1, max: 1 }; \"duplex or triplex\" is { min: 2, max: 3 }. Lots whose roll states no count never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / land_value_per_buildable
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assessed land value divided by the buildable floor area (lot area x the zone’s cited maximum FSR), in currency per square metre of floor area, inclusive bounds ($150 per sq ft = 1,614.59 per m²). Lots without a cited FSR, a land/improvement split or a usable assessment never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / lot_depth
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres. A frontage the city publishes, else the side of the lot outline's oriented bounding rectangle.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / lot_width
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres. A frontage the city publishes, else the side of the lot outline's oriented bounding rectangle.",
        +  "properties": {
        +    "max": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 10000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / criteria / properties / owner_class / description
        Previous value: -"Owner class of the titled parcels on the lot, from ParcelMap BC owner type: private, municipal, provincial, federal, crown_agency, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency). A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search."New value: +"Owner class of the lot, from ParcelMap BC owner type or an open assessment roll: private, municipal, provincial (or state), federal, crown_agency (or public agency), public_other, institutional (religious, charitable, education, health), first_nations, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency, public_other). Institutional and First Nations land is not public. A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search."
      • addedInput schema / properties / criteria / properties / tax_exempt
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "true: the assessment roll classes the property as exempt from property tax (public, religious, charitable and similar owners). { is: false } keeps taxable lots only. Read from rolls that state both values; personal exemptions (senior, veteran) do not count.",
        +  "properties": {
        +    "is": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "is"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "Next page of the same box. Copy page.next from the prior result: it carries the cursor with the box. Do not combine with thesis. Reads only; nothing is saved.",
        +  "maxLength": 1024,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Lots to return. Default 10. countOutcome states whether the total is exact, partial, at_least (a lower bound), estimate (about), or unavailable."New value: +"Lots to return. Default 10, at most 25 per call; page.next reads the next lots. countOutcome states whether the total is exact, partial, at_least (a lower bound), estimate (about), or unavailable."
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "Order of the returned lots across every match. Default lot_area_desc (largest first). land_value_per_buildable_asc / assessed_value_per_buildable_asc: lowest assessed land (or total) value per buildable sq ft first, for \"cheapest land per buildable foot\". Lots with no cited FSR or usable assessment come last.",
        +  "enum": [
        +    "lot_area_desc",
        +    "lot_area_asc",
        +    "land_value_per_buildable_asc",
        +    "assessed_value_per_buildable_asc"
        +  ],
        +  "type": "string"
        +}
    • ChangedupdateProject2 fields changed
      • addedInput schema / properties / lifecycleStatus / description
        Added value: +"Project stage. getProjectContext returns it as lifecycleStatus."
      • addedInput schema / properties / lifecycleStatus / enum
        Added value: +[
        +  "exploring",
        +  "planning_budgeting",
        +  "permits",
        +  "ready_to_build",
        +  "in_construction"
        +]
  3. 2 tool updates
    • AddedfindPlacesByMarket
    • ChangedscreenLots4 fields changed
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / tract_rent_2br
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "CMHC Rental Market Survey average monthly rent for a 2-bedroom purpose-built rental unit in the census tract holding the lot centre, CAD, inclusive bounds. Lots in tracts CMHC does not publish never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / tract_rental_vacancy
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "CMHC Rental Market Survey vacancy rate, all bedroom types, purpose-built rental, in the census tract holding the lot centre, percent (1.5 = 1.5%), inclusive bounds. Lots in tracts CMHC does not publish never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 100,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / tract_rent_2br
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "CMHC Rental Market Survey average monthly rent for a 2-bedroom purpose-built rental unit in the census tract holding the lot centre, CAD, inclusive bounds. Lots in tracts CMHC does not publish never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 100000,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / tract_rental_vacancy
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "CMHC Rental Market Survey vacancy rate, all bedroom types, purpose-built rental, in the census tract holding the lot centre, percent (1.5 = 1.5%), inclusive bounds. Lots in tracts CMHC does not publish never match.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 100,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
  4. 1 tool update
    • ChangedscreenLots1 field changed
      • changedInput schema / properties / limit / description
        Previous value: -"Lots to return. Default 10. countOutcome states whether the total is exact, partial, or unavailable."New value: +"Lots to return. Default 10. countOutcome states whether the total is exact, partial, at_least (a lower bound), estimate (about), or unavailable."
  5. 24 tool updates
    • ChangedaddSavedFolderItem2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "folderId",
        -  "target",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "folderId",
        +  "target",
        +  "context"
        +]
    • ChangedcityInventory2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedcreateSavedFolder2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "name",
        +  "context"
        +]
    • ChangeddeleteSavedFolder2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "folderId",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "folderId",
        +  "context"
        +]
    • ChangedexplainFeasibilityStatus2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "status",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "status",
        +  "context"
        +]
    • ChangedgetBuckyMcpGuide2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedgetBylawSection2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedgetFeasibilitySnapshot2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "address",
        -  "source",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "address",
        +  "source",
        +  "context"
        +]
    • ChangedgetProjectContext2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentsLimit",
        -  "evidenceLimit",
        -  "include",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "documentsLimit",
        +  "evidenceLimit",
        +  "include",
        +  "context"
        +]
    • ChangedlistSaved2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedlistSavedFolders2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedpreviewSiteCoverage2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "address",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "address",
        +  "context"
        +]
    • ChangedproduceProjectReport2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "audience",
        -  "detail",
        -  "preview",
        -  "confirm",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "audience",
        +  "detail",
        +  "preview",
        +  "confirm",
        +  "context"
        +]
    • ChangedremoveSavedFolderItem2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "folderId",
        -  "target",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "folderId",
        +  "target",
        +  "context"
        +]
    • ChangedrenameSavedFolder2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "name",
        -  "folderId",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "name",
        +  "folderId",
        +  "context"
        +]
    • ChangedrunFeasibilityAnalysis2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedsaveLot2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "lotId",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "lotId",
        +  "context"
        +]
    • ChangedsaveToProject2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "action",
        -  "preview",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "action",
        +  "preview",
        +  "context"
        +]
    • ChangedscreenLots5 fields changed
      • addedInput schema / properties / criteria / properties / branches / items / properties / criteria / properties / owner_class
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Owner class of the titled parcels on the lot, from ParcelMap BC owner type: private, municipal, provincial, federal, crown_agency, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency). A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / owner_class
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Owner class of the titled parcels on the lot, from ParcelMap BC owner type: private, municipal, provincial, federal, crown_agency, mixed_ownership (as the source states), unclassified, and public (any of municipal, provincial, federal, crown_agency). A lot with parcels of several classes holds all of them, so none_of [\"public\"] also drops a lot that is partly public and any_of [\"private\"] keeps it. \"Not public land\" is { none_of: [\"public\"] }, which keeps lots whose owner class is unknown; any_of drops them. \"Private\" is the registered owner type, not a title search.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / hygiene
        Added value: +{
        +  "description": "Default true. Ad-hoc lists leave out public owners (owner_class), cap lot size at 5 acres and ignore assessed values under $100,000 where the city stores them, unless criteria set the same field. Each default is named in notes. false skips them. Ignored with profileId: a saved list runs as saved.",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangedsetProjectMapListing2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "listed",
        -  "preview",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "listed",
        +  "preview",
        +  "context"
        +]
    • ChangedsubmitBuckyFeedback2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "context"
        +]
    • ChangeduiGetAnalysisStatus2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "projectId",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "projectId",
        +  "context"
        +]
    • ChangedunsaveLot2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "lotId",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "lotId",
        +  "context"
        +]
    • ChangedupdateProject2 fields changed
      • removedInput schema / properties / llm_model
        Removed value: -{
        -  "description": "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" — never guess.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "preview",
        -  "context",
        -  "llm_model"
        -]New value: +[
        +  "preview",
        +  "context"
        +]
  6. 1 tool update
    • ChangedscreenLots5 fields changed
      • addedInput schema / properties / criteria / properties / branches
        Added value: +{
        +  "description": "Alternative strategies; nested registry values stay in canonical units.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "criteria": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "assessed_value": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "max": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "building_use": {
        +            "additionalProperties": false,
        +            "description": "What the lot is used for today, read from the assessor's use code: office, mixed_use, retail, hospitality, industrial, multifamily, two_to_four_family, single_family, institutional, civic, religious, parking, vacant_land, other. \"Commercial buildings, not houses or churches\" is { any_of: [\"office\", \"mixed_use\", \"retail\"] } or { none_of: [\"single_family\", \"two_to_four_family\", \"religious\", \"civic\"] }.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 20,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 20,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "contamination_risk": {
        +            "additionalProperties": false,
        +            "description": "true: a gas station or auto-service business (repair, body shop, car wash) is mapped on the lot. { is: false } excludes those lots. A risk flag from OpenStreetMap and city business licences, not a site investigation: it misses former and unmapped businesses.",
        +            "properties": {
        +              "is": {
        +                "type": "boolean"
        +              }
        +            },
        +            "required": [
        +              "is"
        +            ],
        +            "type": "object"
        +          },
        +          "existing_coverage_pct": {
        +            "additionalProperties": false,
        +            "description": "Building footprint area on the lot as a percentage of lot area, 0-100. An underbuilt screen is { max: 20 }. Footprints can be years old: check the city honesty note.",
        +            "properties": {
        +              "max": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "existing_use_class": {
        +            "additionalProperties": false,
        +            "description": "What stands on the lot: place_of_worship (church, temple, mosque, synagogue…), fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }; \"church sites\" is { any_of: [\"place_of_worship\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. Québec lots without footprints use the assessment roll land-use code (CUBF 9100 = vacant). A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "exterior_material": {
        +            "additionalProperties": false,
        +            "description": "The assessor's primary exterior wall as a family: masonry, wood, siding, stucco, concrete, metal, glass, other. \"Brick buildings\" is { any_of: [\"masonry\"] }.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "frequent_transit_distance": {
        +            "additionalProperties": false,
        +            "description": "Metres from the lot line to the nearest frequent bus stop or rapid-transit station.",
        +            "properties": {
        +              "max": {
        +                "maximum": 5000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "maximum": 5000,
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "hydrant_distance": {
        +            "additionalProperties": false,
        +            "description": "Metres from the lot line to the nearest fire hydrant.",
        +            "properties": {
        +              "max": {
        +                "maximum": 5000,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "maximum": 5000,
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "improvement_land_ratio": {
        +            "additionalProperties": false,
        +            "description": "Building (improvement) value divided by land value, assessed or appraised, as a ratio: 0.25 = the building is worth a quarter of the land. A teardown screen is { max: 0.25 }.",
        +            "properties": {
        +              "max": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "lot_area": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "max": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "min_homes": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "min": {
        +                "maximum": 1000,
        +                "minimum": 1,
        +                "type": "integer"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "named_area": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        +                  "type": "string"
        +                },
        +                "maxItems": 200,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "ocp_above_zoning": {
        +            "additionalProperties": false,
        +            "description": "true: the lot's Official Community Plan designation allows more housing than its current zone (both ranked 1 rural, 2 low density, 3 medium density, 4 high density or mixed-use centre): a rezoning candidate. { is: false } keeps lots where both are ranked and the OCP is not higher. Lots with an unranked zone or designation, no zone, or no designation match neither. A planning signal: a rezoning consistent with the OCP is more likely to be supported, but this is not a rezoning approval or the density zoning permits today.",
        +            "properties": {
        +              "is": {
        +                "type": "boolean"
        +              }
        +            },
        +            "required": [
        +              "is"
        +            ],
        +            "type": "object"
        +          },
        +          "overlay": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 20,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 20,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "ownership_form": {
        +            "additionalProperties": false,
        +            "description": "Ownership form: fee_simple (land title), strata_condo, co_op, leasehold, mixed. \"Land title only\" is { none_of: [\"strata_condo\", \"co_op\", \"leasehold\", \"mixed\"] }, which keeps lots whose form is unknown; any_of drops them.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "permitted_use": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "place_of_worship": {
        +            "additionalProperties": false,
        +            "description": "true: a church, temple, mosque, synagogue or other place of worship is mapped on the lot (OpenStreetMap, city heritage registers). { is: false } excludes those lots. Same lots as existing_use_class place_of_worship.",
        +            "properties": {
        +              "is": {
        +                "type": "boolean"
        +              }
        +            },
        +            "required": [
        +              "is"
        +            ],
        +            "type": "object"
        +          },
        +          "register_status": {
        +            "additionalProperties": false,
        +            "description": "Historic register status: individually_listed, contributing, non_contributing, in_district (inside a register district, building not yet mapped), not_listed. \"On the register\" is { any_of: [\"individually_listed\", \"contributing\"] }. Register status is a research lead, not tax-credit eligibility. The federal 20% credit needs a certified historic structure; building age alone qualifies for nothing (the 10% pre-1936 credit was repealed in 2017).",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "stories": {
        +            "additionalProperties": false,
        +            "description": "Above-grade stories: the assessor count where recorded (half stories are decimals, 1.5), otherwise estimated from building height at 3 m per storey. \"1-2 story\" is { max: 2 }.",
        +            "properties": {
        +              "max": {
        +                "maximum": 200,
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "maximum": 200,
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "street": {
        +            "additionalProperties": false,
        +            "description": "Street names as the lot address carries them, upper case with the suffix abbreviated: \"STATE ST\", \"BANK ST\". { any_of: [...] } keeps lots on those streets. Matches the lot's address, not every street it touches: a corner lot counts once.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "subdivision_yield": {
        +            "additionalProperties": false,
        +            "description": "Lot area divided by the zone's minimum lot area: how many minimum-size lots the parcel could hold by area. \"Could be subdivided\" is { min: 2 }; \"into 3 lots\" is { min: 3 }. Ignores frontage, streets and lot shape: a candidate, not a subdivision approval.",
        +            "properties": {
        +              "max": {
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "min": {
        +                "minimum": 0,
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "titled_unit_count": {
        +            "additionalProperties": false,
        +            "description": "Titled units on the parcel: 1 for a land-title lot, the strata unit count otherwise.",
        +            "properties": {
        +              "max": {
        +                "maximum": 100000,
        +                "minimum": 1,
        +                "type": "integer"
        +              },
        +              "min": {
        +                "maximum": 100000,
        +                "minimum": 1,
        +                "type": "integer"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "typology": {
        +            "additionalProperties": false,
        +            "description": "Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "use_sector": {
        +            "additionalProperties": false,
        +            "description": "Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "year_built": {
        +            "additionalProperties": false,
        +            "description": "Year the main building was built, inclusive bounds.",
        +            "properties": {
        +              "max": {
        +                "maximum": 2100,
        +                "minimum": 1600,
        +                "type": "integer"
        +              },
        +              "min": {
        +                "maximum": 2100,
        +                "minimum": 1600,
        +                "type": "integer"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "zone_code": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 50,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "zone_family": {
        +            "additionalProperties": false,
        +            "description": "The zone's dominant use: residential, mixed, commercial, industrial, public, recreation, agricultural, forest. \"Zoned residential or mixed\" is { any_of: [\"residential\", \"mixed\"] }. Québec zones read the zone letter (H, M, C, I, P/U, R, A, F); other zones a family classified from the zone name and purpose. The family names the dominant use; the bylaw still decides which uses are permitted.",
        +            "properties": {
        +              "any_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              },
        +              "none_of": {
        +                "items": {
        +                  "maxLength": 256,
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "maxItems": 10,
        +                "type": "array"
        +              }
        +            },
        +            "type": "object"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "key": {
        +        "pattern": "^[a-z][a-z0-9_]{0,39}$",
        +        "type": "string"
        +      },
        +      "label": {
        +        "maxLength": 60,
        +        "minLength": 1,
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "key",
        +      "label",
        +      "criteria"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 6,
        +  "type": "array"
        +}
      • changedInput schema / properties / profileId / description
        Previous value: -"Saved buy box id. Runs the saved city and criteria. Do not combine with city, thesis, or criteria."New value: +"Saved list id. Runs the saved city and criteria. Do not combine with city, thesis, or criteria."
      • changedInput schema / properties / save / description
        Previous value: -"true saves the buy box to the account. Default false. Search execution history is recorded."New value: +"true saves the list to the account. Default false. Search execution history is recorded."
      • changedInput schema / properties / saveName / description
        Previous value: -"Name for a saved box."New value: +"Name for a saved list."
      • changedInput schema / properties / thesis / description
        Previous value: -"The buy box in plain words, e.g. \"industrial lots over half an acre outside the floodplain\"."New value: +"The list in plain words, e.g. \"industrial lots over half an acre outside the floodplain\"."
  7. 5 tool updates
    • ChangedaddSavedFolderItem2 fields changed
      • removedInput schema / properties / folderId / format
        Removed value: -"uuid"
      • changedInput schema / properties / folderId / pattern
        Previous value: -"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"New value: +"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    • ChangeddeleteSavedFolder2 fields changed
      • removedInput schema / properties / folderId / format
        Removed value: -"uuid"
      • changedInput schema / properties / folderId / pattern
        Previous value: -"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"New value: +"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    • ChangedlistSaved2 fields changed
      • removedInput schema / properties / folderId / format
        Removed value: -"uuid"
      • changedInput schema / properties / folderId / pattern
        Previous value: -"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"New value: +"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    • ChangedremoveSavedFolderItem2 fields changed
      • removedInput schema / properties / folderId / format
        Removed value: -"uuid"
      • changedInput schema / properties / folderId / pattern
        Previous value: -"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"New value: +"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    • ChangedrenameSavedFolder2 fields changed
      • removedInput schema / properties / folderId / format
        Removed value: -"uuid"
      • changedInput schema / properties / folderId / pattern
        Previous value: -"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"New value: +"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
  8. 10 tool updates
    • AddedaddSavedFolderItem
    • AddedcreateSavedFolder
    • AddeddeleteSavedFolder
    • AddedlistSaved
    • AddedlistSavedFolders
    • AddedremoveSavedFolderItem
    • AddedrenameSavedFolder
    • AddedsaveLot
    • ChangedscreenLots2 fields changed
      • addedInput schema / properties / criteria / properties / typology
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Current site use from site_typologies, not what can be built. Exact typology IDs; sector-only lots do not match.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / use_sector
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Current site use from site_typologies, not what can be built. Sector IDs; includes sector-only assignments.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • AddedunsaveLot
  9. 1 tool update
    • ChangedscreenLots2 fields changed
      • changedInput schema / properties / criteria / properties / namedAreaIds / maxItems
        Previous value: -50New value: +200
      • addedInput schema / properties / criteria / properties / ocp_above_zoning
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "true: the lot's Official Community Plan designation allows more housing than its current zone (both ranked 1 rural, 2 low density, 3 medium density, 4 high density or mixed-use centre): a rezoning candidate. { is: false } keeps lots where both are ranked and the OCP is not higher. Lots with an unranked zone or designation, no zone, or no designation match neither. A planning signal: a rezoning consistent with the OCP is more likely to be supported, but this is not a rezoning approval or the density zoning permits today.",
        +  "properties": {
        +    "is": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "is"
        +  ],
        +  "type": "object"
        +}
  10. 1 tool update
    • ChangedscreenLots1 field changed
      • addedInput schema / properties / criteria / properties / permitted_use
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
  11. 1 tool update
    • ChangedgetFeasibilitySnapshot1 field changed
      • changedInput schema / properties / source / enum
        Previous value: -[
        -  "zoning_lookup",
        -  "lot_dimensions",
        -  "setback_lookup",
        -  "height_limit_lookup",
        -  "full"
        -]New value: +[
        +  "zoning_lookup",
        +  "lot_dimensions",
        +  "setback_lookup",
        +  "height_limit_lookup",
        +  "lot_split_lookup",
        +  "full"
        +]
  12. 15 tool updates
    • ChangedcityInventory1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedexplainFeasibilityStatus1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedgetBuckyMcpGuide1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedgetBylawSection1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedgetFeasibilitySnapshot1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedgetProjectContext1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedpreviewSiteCoverage1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedproduceProjectReport1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedrunFeasibilityAnalysis1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedsaveToProject2 fields changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
      • addedInput schema / properties / polygon
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "WGS84 GeoJSON Polygon for attach_parcels. Attach the parcels selected by the product area flow, up to 500. Interior rings exclude parcels. Use polygon instead of parcelExternalIds and radiusM. Maximum 512 coordinates.",
        +  "properties": {
        +    "coordinates": {
        +      "items": {
        +        "items": {
        +          "items": {
        +            "type": "number"
        +          },
        +          "maxItems": 2,
        +          "minItems": 2,
        +          "type": "array"
        +        },
        +        "maxItems": 512,
        +        "minItems": 4,
        +        "type": "array"
        +      },
        +      "maxItems": 128,
        +      "minItems": 1,
        +      "type": "array"
        +    },
        +    "type": {
        +      "const": "Polygon",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "type",
        +    "coordinates"
        +  ],
        +  "type": "object"
        +}
    • ChangedscreenLots3 fields changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
      • changedInput schema / properties / limit / description
        Previous value: -"Lots to return. Default 10. The total match count is always returned."New value: +"Lots to return. Default 10. countOutcome states whether the total is exact, partial, or unavailable."
      • changedInput schema / properties / save / description
        Previous value: -"true saves the buy box to the account. Default false: nothing is written."New value: +"true saves the buy box to the account. Default false. Search execution history is recorded."
    • ChangedsetProjectMapListing1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedsubmitBuckyFeedback1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangeduiGetAnalysisStatus1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
    • ChangedupdateProject1 field changed
      • removedInput schema / properties / conversation_id
        Removed value: -{
        -  "description": "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.",
        -  "type": "string"
        -}
  13. 1 tool update
    • ChangedscreenLots2 fields changed
      • addedInput schema / properties / criteria / properties / hydrant_distance
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres from the lot line to the nearest fire hydrant.",
        +  "properties": {
        +    "max": {
        +      "maximum": 5000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 5000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / criteria / properties / stories / description
        Previous value: -"Above-grade stories of the main building as the assessor records them; half stories are decimals (1.5). \"1-2 story\" is { max: 2 }."New value: +"Above-grade stories: the assessor count where recorded (half stories are decimals, 1.5), otherwise estimated from building height at 3 m per storey. \"1-2 story\" is { max: 2 }."
  14. 1 tool update
    • ChangedscreenLots6 fields changed
      • addedInput schema / properties / criteria / properties / building_use
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "What the lot is used for today, read from the assessor's use code: office, mixed_use, retail, hospitality, industrial, multifamily, two_to_four_family, single_family, institutional, civic, religious, parking, vacant_land, other. \"Commercial buildings, not houses or churches\" is { any_of: [\"office\", \"mixed_use\", \"retail\"] } or { none_of: [\"single_family\", \"two_to_four_family\", \"religious\", \"civic\"] }.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 20,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 20,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / exterior_material
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "The assessor's primary exterior wall as a family: masonry, wood, siding, stucco, concrete, metal, glass, other. \"Brick buildings\" is { any_of: [\"masonry\"] }.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / register_status
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Historic register status: individually_listed, contributing, non_contributing, in_district (inside a register district, building not yet mapped), not_listed. \"On the register\" is { any_of: [\"individually_listed\", \"contributing\"] }. Register status is a research lead, not tax-credit eligibility. The federal 20% credit needs a certified historic structure; building age alone qualifies for nothing (the 10% pre-1936 credit was repealed in 2017).",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / stories
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Above-grade stories of the main building as the assessor records them; half stories are decimals (1.5). \"1-2 story\" is { max: 2 }.",
        +  "properties": {
        +    "max": {
        +      "maximum": 200,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 200,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / street
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Street names as the lot address carries them, upper case with the suffix abbreviated: \"STATE ST\", \"BANK ST\". { any_of: [...] } keeps lots on those streets. Matches the lot's address, not every street it touches: a corner lot counts once.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 50,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / thesis / maxLength
        Previous value: -500New value: +1500
  15. 1 tool update
    • ChangedscreenLots2 fields changed
      • addedInput schema / properties / criteria / properties / frequent_transit_distance
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Metres from the lot line to the nearest frequent bus stop or rapid-transit station.",
        +  "properties": {
        +    "max": {
        +      "maximum": 5000,
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "maximum": 5000,
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / criteria / properties / zone_family / description
        Previous value: -"The zone's dominant use from the Québec zone letter: residential (H), mixed (M), commercial (C), industrial (I), public (P, U), recreation (R), agricultural (A), forest (F). \"Zoned residential or mixed\" is { any_of: [\"residential\", \"mixed\"] }. Québec cities only. The letter names the dominant use; the zone grid still decides which uses are permitted."New value: +"The zone's dominant use: residential, mixed, commercial, industrial, public, recreation, agricultural, forest. \"Zoned residential or mixed\" is { any_of: [\"residential\", \"mixed\"] }. Québec zones read the zone letter (H, M, C, I, P/U, R, A, F); other zones a family classified from the zone name and purpose. The family names the dominant use; the bylaw still decides which uses are permitted."
  16. 1 tool update
    • ChangedscreenLots3 fields changed
      • changedInput schema / properties / criteria / properties / improvement_land_ratio / description
        Previous value: -"Assessed building (improvement) value divided by land value, as a ratio: 0.25 = the building is worth a quarter of the land. A teardown screen is { max: 0.25 }."New value: +"Building (improvement) value divided by land value, assessed or appraised, as a ratio: 0.25 = the building is worth a quarter of the land. A teardown screen is { max: 0.25 }."
      • changedInput schema / properties / criteria / properties / overlayExcludeKinds / description
        Previous value: -"Overlay kinds a lot must be outside."New value: +"Overlay kinds a lot must not overlap. A lot passes only if it was evaluated for every excluded kind; an unevaluated kind is reported not_available."
      • changedInput schema / properties / criteria / properties / overlayKinds / description
        Previous value: -"Overlay kinds a lot must be inside."New value: +"Overlay kinds a lot must overlap by at least 1 m². A kind the city has not evaluated is reported not_available, never applied."
  17. 1 tool update
    • ChangedscreenLots3 fields changed
      • changedInput schema / properties / criteria / properties / existing_use_class / description
        Previous value: -"What stands on the lot: place_of_worship (church, temple, mosque, synagogue…), fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }; \"church sites\" is { any_of: [\"place_of_worship\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation."New value: +"What stands on the lot: place_of_worship (church, temple, mosque, synagogue…), fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }; \"church sites\" is { any_of: [\"place_of_worship\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. Québec lots without footprints use the assessment roll land-use code (CUBF 9100 = vacant). A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation."
      • addedInput schema / properties / criteria / properties / subdivision_yield
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Lot area divided by the zone's minimum lot area: how many minimum-size lots the parcel could hold by area. \"Could be subdivided\" is { min: 2 }; \"into 3 lots\" is { min: 3 }. Ignores frontage, streets and lot shape: a candidate, not a subdivision approval.",
        +  "properties": {
        +    "max": {
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / zone_family
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "The zone's dominant use from the Québec zone letter: residential (H), mixed (M), commercial (C), industrial (I), public (P, U), recreation (R), agricultural (A), forest (F). \"Zoned residential or mixed\" is { any_of: [\"residential\", \"mixed\"] }. Québec cities only. The letter names the dominant use; the zone grid still decides which uses are permitted.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
  18. 1 tool update
    • ChangedscreenLots2 fields changed
      • changedInput schema / properties / criteria / properties / existing_use_class / description
        Previous value: -"What stands on the lot: fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation."New value: +"What stands on the lot: place_of_worship (church, temple, mosque, synagogue…), fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }; \"church sites\" is { any_of: [\"place_of_worship\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation."
      • addedInput schema / properties / criteria / properties / place_of_worship
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "true: a church, temple, mosque, synagogue or other place of worship is mapped on the lot (OpenStreetMap, city heritage registers). { is: false } excludes those lots. Same lots as existing_use_class place_of_worship.",
        +  "properties": {
        +    "is": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "is"
        +  ],
        +  "type": "object"
        +}
  19. 1 tool update
    • ChangedscreenLots7 fields changed
      • addedInput schema / properties / criteria / properties / contamination_risk
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "true: a gas station or auto-service business (repair, body shop, car wash) is mapped on the lot. { is: false } excludes those lots. A risk flag from OpenStreetMap and city business licences, not a site investigation: it misses former and unmapped businesses.",
        +  "properties": {
        +    "is": {
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "is"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / existing_coverage_pct
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Building footprint area on the lot as a percentage of lot area, 0-100. An underbuilt screen is { max: 20 }. Footprints can be years old: check the city honesty note.",
        +  "properties": {
        +    "max": {
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / existing_use_class
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "What stands on the lot: fuel_station, auto_service (repair, body, car wash), auto_sales (car dealer), else vacant, surface_parking or built. \"Vacant lots or surface parking\" is { any_of: [\"vacant\", \"surface_parking\"] }; \"gas stations\" is { any_of: [\"fuel_station\"] }. Vacant means no building over 20 m² in any footprint source and no assessed building worth over 20% of the land. A mapped business on the lot wins over the footprint class. Fuel and auto-service sites are a contamination risk flag, not a site investigation.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / improvement_land_ratio
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Assessed building (improvement) value divided by land value, as a ratio: 0.25 = the building is worth a quarter of the land. A teardown screen is { max: 0.25 }.",
        +  "properties": {
        +    "max": {
        +      "minimum": 0,
        +      "type": "number"
        +    },
        +    "min": {
        +      "minimum": 0,
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / ownership_form
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Ownership form: fee_simple (land title), strata_condo, co_op, leasehold, mixed. \"Land title only\" is { none_of: [\"strata_condo\", \"co_op\", \"leasehold\", \"mixed\"] }, which keeps lots whose form is unknown; any_of drops them.",
        +  "properties": {
        +    "any_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    },
        +    "none_of": {
        +      "items": {
        +        "maxLength": 256,
        +        "minLength": 1,
        +        "type": "string"
        +      },
        +      "maxItems": 10,
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / titled_unit_count
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Titled units on the parcel: 1 for a land-title lot, the strata unit count otherwise.",
        +  "properties": {
        +    "max": {
        +      "maximum": 100000,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 100000,
        +      "minimum": 1,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / criteria / properties / year_built
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Year the main building was built, inclusive bounds.",
        +  "properties": {
        +    "max": {
        +      "maximum": 2100,
        +      "minimum": 1600,
        +      "type": "integer"
        +    },
        +    "min": {
        +      "maximum": 2100,
        +      "minimum": 1600,
        +      "type": "integer"
        +    }
        +  },
        +  "type": "object"
        +}
  20. 2 tool updates
    • AddedgetBylawSection
    • AddedscreenLots

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Instant U.S. property intelligence for AI agents. Zoning, Buildability™ Score, ADU eligibility, flood risk, and more from 20+ government sources. Pay-as-you-go: $5 per analysis (prepaid credits). Free Score available at buildability.us. Get a key at buildability.us/api.
    5
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to look up US and Canadian parcel records either by full address string or by lat/lon point, returning parcel number, owner, mailing address, land use, zoning, acreage, and boundary geometry. It can be run as a local stdio server or reached through a hosted gateway endpoint.
    13 npm
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides free property and parcel intelligence using official US government data APIs, county assessor records, and live listings, with tools for hazard risk checks, affordability calculations, and parcel ranking.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Property intelligence API for US real estate. Returns 16+ data points for any US address: noise levels, wetlands, slope, natural light, powerline proximity, crime rates, property facing direction, zoning, public record, radon risk, natural hazards (earthquake, flood, wildfire), neighborhood demographics, falling tree risk, RF/cell tower exposure, and nearby school.
    -
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.