Plan Comply — SANS 10400 Building Plan Pre-Screening AI
Server Details
SANS 10400 architectural building plan compliance checks, municipal checklists, and SLA lookups.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 7 tools
The two calculators (fenestration, stairs) and the two lookup tools (SANS rules, municipal requirements) target clearly different resources, and pricing is obviously separate. The main overlap is that pre_check_building_plan aggregates the same checks the individual calculators and municipal tool perform, and check_municipal_requirements claims to return 'common rejection delay factors' which duplicates get_common_rejection_pitfalls. Descriptions do flag these distinctions, so misselection is unlikely but possible.
All seven tools use a consistent snake_case verb_noun pattern: calculate_*, check_*, get_*, and pre_check_*. Verb choice maps predictably to operation type (calculate = compute, get/check = retrieve), so an agent can infer behavior from the name alone.
Seven tools is well within the sweet spot and each one earns its place: two focused calculators, two reference lookups, one pitfalls lookup, one pricing lookup, and one aggregate pre-check. Nothing feels redundant at the count level and there is no filler.
Core pre-screening workflows are covered: rule lookup, two statutory calculators, municipal checklists, pitfalls, pricing, and a multi-point aggregate audit. However, calculable SANS parts beyond O and M (fire, drainage/rodding, XA energy) exist only as parameters inside pre_check or as text via get_sans_rules, and there is no path to actually submit a plan or purchase credits despite pricing being exposed — minor gaps an agent can route around.
Available Tools
7 toolscalculate_sans_fenestrationCalculate Sans FenestrationARead-onlyIdempotentInspect
Calculate SANS 10400-O statutory natural lighting (min. 10% floor area) and natural ventilation (min. 5% openable sash area) compliance for habitable rooms. When to use: Call this tool when you specifically need to execute 'calculate_sans_fenestration' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'check_municipal_requirements' or 'get_common_rejection_pitfalls' for their respective operations). Parameters: room_name (optional), floor_area_m2 (required), actual_glazed_area_m2 (optional), actual_openable_area_m2 (optional). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| room_name | No | Name or label of the habitable room (e.g. "Bedroom 1", "Living Room", "Study"). [Optional: omit to use server default filter]. | |
| floor_area_m2 | Yes | Internal floor area of the habitable room in square metres (m²). [Required: non-empty valid value must be supplied]. | |
| actual_glazed_area_m2 | No | Total installed window glazed area in square metres (m²). [Optional: omit to use server default filter]. | |
| actual_openable_area_m2 | No | Total installed clear openable window sash ventilation area in square metres (m²). [Optional: omit to use server default filter]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so safety is covered. The description earns credit beyond that by adding a concrete rate limit (60 req/min per IP), unauthenticated public access, and the shape of the response (status, matched records/metrics, canonical action URLs).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and thresholds are front-loaded and useful, but the 'When to use' sentence is a tautology about executing this same tool, and the parameter enumeration duplicates the schema. Roughly a third of the text does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing the return, which it does reasonably well (structured JSON with status, metrics, action URLs). Safety, auth, and rate limit are all covered, leaving only minor gaps such as how optional parameters default on the server.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains all four parameters including units (m²) and examples. The description only restates the parameter list with required/optional markers, adding no new semantic meaning — baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (calculate SANS 10400-O natural lighting/ventilation compliance) with concrete thresholds (10% floor area, 5% openable sash), and scopes it to habitable rooms. An agent can distinguish it from the sibling calculators (stairs, municipal, pre-check) 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names alternatives ('get_sans_rules', 'check_municipal_requirements', 'get_common_rejection_pitfalls') but only says to use them 'for their respective operations' — no condition that tells the agent when one actually wins. The positive guidance is circular: 'Call this tool when you specifically need to execute calculate_sans_fenestration.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_stair_complianceCalculate Stair ComplianceARead-onlyIdempotentInspect
Evaluate stairway geometry and life safety against SANS 10400-M standards (riser max 200 mm, going min 250 mm, 2R + G formula 570-650 mm, headroom min 2,100 mm). When to use: Call this tool when you specifically need to execute 'calculate_stair_compliance' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'check_municipal_requirements' or 'get_common_rejection_pitfalls' for their respective operations). Parameters: riser_mm (required), going_mm (required), headroom_mm (optional), balustrade_height_mm (optional), baluster_gap_mm (optional). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| going_mm | Yes | Stair tread horizontal going in millimetres excluding nosing (must not be less than 250 mm). [Required: non-empty valid value must be supplied]. | |
| riser_mm | Yes | Stair riser vertical height in millimetres (must not exceed 200 mm). [Required: non-empty valid value must be supplied]. | |
| headroom_mm | No | Vertical headroom clearance in millimetres measured vertically from the nosing pitch line (must be min. 2,100 mm). [Optional: omit to use server default filter]. | |
| baluster_gap_mm | No | Maximum clear gap between vertical balusters in millimetres (must not exceed 100 mm). [Optional: omit to use server default filter]. | |
| balustrade_height_mm | No | Height of balustrade in millimetres (min. 1,000 mm on landings, 850 mm on flights). [Optional: omit to use server default filter]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing rate limiting (60 requests/min per IP), unauthenticated public access, idempotency with zero state mutation, and the general shape of the response. These are exactly the operational details an agent cannot derive from readOnlyHint/destructiveHint alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the standard and thresholds, which is good, but the labeled sections include filler: the 'When to use' sentence restates the tool name and the parameter list duplicates the schema. Roughly a third of the text does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description does compensate with a return summary plus thresholds and side effects. However, for a compliance check the return description ('status, matched records or computed metrics') never says whether pass/fail violations and the governing clause are reported, which is the main thing an agent needs to interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already carries its constraint and required/optional status in the schema, so the description's parameter list is essentially a restatement. It adds no unit-conversion hints, interaction rules (e.g. how 2R+G is applied across riser/going), or default values for the optional fields beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('evaluate stairway geometry and life safety') and pins it to a named standard (SANS 10400-M) with the actual numeric limits. This clearly separates it from sibling tools such as calculate_sans_fenestration or get_sans_rules without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The negative routing ('do NOT use ... use get_sans_rules or check_municipal_requirements or get_common_rejection_pitfalls') gives real exclusions, but the positive guidance is circular boilerplate: 'Call this tool when you specifically need to execute calculate_stair_compliance'. It also omits the two most similar siblings, calculate_sans_fenestration and pre_check_building_plan, so the agent must infer how this differs from those.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_municipal_requirementsCheck Municipal RequirementsARead-onlyIdempotentInspect
Retrieve submission document checklists, statutory forms (Form 1/2), geotechnical/dolomite rules, and common rejection delay factors for South African metropolitan municipalities. When to use: Call this tool when you specifically need to execute 'check_municipal_requirements' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'get_common_rejection_pitfalls' or 'calculate_sans_fenestration' for their respective operations). Parameters: municipality (required). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| municipality | Yes | Municipality name or abbreviation (e.g. "City of Johannesburg", "COJ", "Tshwane", "Pretoria", "City of Cape Town", "COCT", "Ekurhuleni", "eThekwini", "Durban"). [Required: non-empty valid value must be supplied]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the description's job is to add context — and it does: 60 requests/min per IP rate limit, unauthenticated public access, and the shape of the JSON response. These are operational facts an agent cannot get from the annotation block 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The Behavior and Parameters sections are tightly front-loaded and earn their space, but the 'When to use' sentence contains a self-referential clause and a marketing domain reference (plancomply.co.za) that do not help tool selection. Roughly a third of the text is recoverable padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only tool with no output schema, the definition covers selection, side effects, access constraints and return shape — enough to call it correctly. The only residual gap is the unresolved overlap with get_common_rejection_pitfalls, which the description lists both as content this tool returns and as a reason not to use it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single municipality parameter already documents accepted name and abbreviation forms with examples. The description only restates 'municipality (required)', adding no matching, fallback, or normalization semantics beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb plus concrete resource list (checklists, Form 1/2 statutory forms, geotechnical/dolomite rules) scoped to South African metropolitan municipalities, so an agent can tell it apart from generic rule tools. The claim that it returns 'common rejection delay factors' while the usage section defers that topic to get_common_rejection_pitfalls slightly muddies the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names three alternatives (get_sans_rules, get_common_rejection_pitfalls, calculate_sans_fenestration) and a 'do NOT use' condition, which is genuine routing guidance. However the positive 'when to use' clause is circular filler ('when you specifically need to execute check_municipal_requirements') and adds no selection criteria of its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_common_rejection_pitfallsGet Common Rejection PitfallsBRead-onlyIdempotentInspect
Retrieve top 25 common reasons municipal building control examiners reject building plans in South Africa, accompanied by verified remediation steps. When to use: Call this tool when you specifically need to execute 'get_common_rejection_pitfalls' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'check_municipal_requirements' or 'calculate_sans_fenestration' for their respective operations). Parameters: category (optional). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Optional category filter. Defaults to all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive, so the description earns credit for going further: 60 requests/min per IP rate limiting, unauthenticated public access, and an explicit zero-state-mutation statement. Those are real operational facts an agent needs for retry and throttling decisions. The return-value sentence is generic ('status, matched records or computed metrics') but acceptable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The lead sentence is strong and front-loaded, but the following text is template filler ('Behavior & Side Effects', 'Returns: Structured JSON object containing status, matched records or computed metrics') that reads as generated boilerplate. The circular 'when to use' clause occupies space without earning it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter read-only query with no output schema, the description covers access model, rate limits, mutation profile, and return shape. The only genuine gap is that it never explains how category filtering interacts with the 'top 25' cap, which could matter to an agent interpreting results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single category parameter has a fully enumerated value list with a documented default. The description only says 'category (optional)', adding nothing beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a precise verb and resource: retrieving the top 25 municipal building-plan rejection reasons in South Africa with remediation steps. That is specific enough to separate it from get_sans_rules or check_municipal_requirements on subject matter. It stops short of a 5 because the differentiation is never stated in the purpose itself; it is only gestured at in the boilerplate 'when to use' sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The guidance is circular: 'Call this tool when you specifically need to execute get_common_rejection_pitfalls.' That tells an agent nothing about the decision. Sibling tools are listed, but only as names with 'for their respective operations,' so there is no condition under which any alternative should be chosen over this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_credit_pricingGet Credit PricingARead-onlyIdempotentInspect
Retrieve official Plan Comply pre-submission plan audit credit packages, volume discounts, and checkout details. When to use: Call this tool when you specifically need to execute 'get_credit_pricing' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'check_municipal_requirements' or 'get_common_rejection_pitfalls' for their respective operations). Parameters: none required (zero-argument query). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes meaningfully beyond the annotations by disclosing a 60 requests/min per IP rate limit and public unauthenticated access, neither of which appears in the structured hints. It also confirms strictly read-only, idempotent behavior, though that duplicates readOnlyHint and idempotentHint rather than adding new information. The 'Returns' sentence is generic boilerplate ('matched records or computed metrics') and does not describe the actual pricing payload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The substantive purpose is front-loaded in one good sentence, but the remainder is template filler: the circular 'when to use' sentence, the 'Returns' sentence with no pricing-specific content, and redundant restatement of read-only/idempotent facts already in annotations. Roughly half the text does not earn its place for this particular tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-argument read-only query with full annotation coverage, the description supplies what an agent needs to select and invoke it, including auth and rate-limit context. The only gap is the generic return-value description that does not say what a credit-package response actually contains, which is a minor omission given no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4, and the description correctly and explicitly states 'Parameters: none required (zero-argument query)'. There is nothing further to document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource set: pre-submission plan audit credit packages, volume discounts, and checkout details. That distinguishes it well from the sibling tools, which are all technical/compliance calculators rather than commercial lookups. However, the purpose statement is undercut by the boilerplate framing that follows, which treats the tool as a generic query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It attempts an explicit when/when-not structure, but the positive trigger is circular: 'when you specifically need to execute get_credit_pricing' restates the name rather than describing a user need. The named alternatives (get_sans_rules, check_municipal_requirements, get_common_rejection_pitfalls) are dissimilar enough that the routing adds little. For a zero-argument pricing lookup, the implied usage is nonetheless clear enough to be minimally viable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sans_rulesGet Sans RulesBRead-onlyIdempotentInspect
Search and query South African National Building Regulations (SANS 10400) clauses by Part (A to XA) or category (Dimensions, Glazing, Fire, Ventilation, Drainage, Stairs, Walls, Documentation). When to use: Call this tool when you specifically need to execute 'get_sans_rules' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'check_municipal_requirements' or 'get_common_rejection_pitfalls' or 'calculate_sans_fenestration' for their respective operations). Parameters: sans_part (optional), category (optional), query (optional). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional keyword search term to match within rule titles, descriptions, and guidance notes. | |
| category | No | Category filter (e.g. "Dimensions", "Glazing", "Stairways", "Fire Safety", "Drainage", "Walls", "Energy Efficiency"). [Optional: omit to use server default filter]. | |
| sans_part | No | SANS 10400 Part identifier (e.g. "Part A", "Part C", "Part K", "Part M", "Part N", "Part O", "Part P", "Part S", "Part T", "Part XA"). [Optional: omit to use server default filter]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, but the description adds genuinely non-redundant context: public unauthenticated access and a 60 requests/min per-IP rate limit. It also sketches the return envelope (status, matched records, canonical action URLs). The only gap is not saying how multiple filters combine (AND vs OR) or what an empty result looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is well front-loaded, but the "When to use" boilerplate ("Call this tool when you specifically need to execute 'get_sans_rules' on Plan Comply SANS 10400 AI (plancomply.co.za)") is pure padding that consumes space without informing the agent. The Behavior & Side Effects and Returns sections are efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 0-required-parameter read-only lookup with no output schema, the description covers safety, auth, rate limits and return shape, which is largely sufficient. But the category vocabulary mismatch between description and schema, and the silence on whether sans_part and category compose or conflict, leaves an agent able to call it but not to predict filter behavior reliably.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents query, category and sans_part, establishing a baseline of 3. The description merely restates that all three are optional and adds no semantics beyond the schema — and its category list actually conflicts with the schema's, which is a mild negative rather than added meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource: search SANS 10400 clauses by Part (A–XA) or category, which an agent can distinguish from the calculate_* and check_* siblings. However, it undercuts itself slightly by listing categories ("Ventilation", "Stairs", "Documentation") that don't match the schema's category values ("Stairways", "Fire Safety", "Energy Efficiency"), so the resource scope is clear but the accepted values are muddy.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The "When to use" sentence is circular filler — "call this tool when you specifically need to execute 'get_sans_rules'" tells the agent nothing. It does name three alternatives (check_municipal_requirements, get_common_rejection_pitfalls, calculate_sans_fenestration) but gives no decision criteria for choosing between them beyond "their respective operations", so routing still requires guesswork.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pre_check_building_planPre Check Building PlanBRead-onlyIdempotentInspect
Run an automated multi-point regulatory validation on building plan specifications and return a compliance readiness score, defect warnings, and submission checklist. When to use: Call this tool when you specifically need to execute 'pre_check_building_plan' on Plan Comply SANS 10400 AI (plancomply.co.za). Do NOT use this tool when another specialized tool fits better (use 'get_sans_rules' or 'check_municipal_requirements' or 'get_common_rejection_pitfalls' for their respective operations). Parameters: project_name (optional), municipality (required), building_class (optional), habitable_room_height_mm (optional), external_wall_thickness_mm (optional), has_safety_glass_below_800mm (optional), has_sacap_declaration (optional), has_sans_forms (optional), has_renewable_water_heating (optional), has_rodding_eyes_at_bends (optional), gully_height_above_ground_mm (optional). Behavior & Side Effects: Strictly read-only, idempotent query with zero state mutation; public unauthenticated access allowed; rate-limited to 60 requests/min per IP. Returns: Structured JSON object containing status, matched records or computed metrics, and canonical action URLs.
| Name | Required | Description | Default |
|---|---|---|---|
| municipality | Yes | Target South African municipality for plan submission (e.g. "City of Johannesburg", "Tshwane", "City of Cape Town", "Ekurhuleni", "eThekwini"). [Required: non-empty valid value must be supplied]. | |
| project_name | No | Name of the building or architectural project. [Optional: omit to use server default filter]. | |
| building_class | No | Occupancy classification (e.g. "H4 Single Dwelling House", "H3 Multi-Dwelling", "G1 Offices", "F1 Retail"). Default is "H4 Single Dwelling House". | |
| has_sans_forms | No | Whether SANS 10400 Form 1 and Form 2 (if structural work included) are prepared. [Optional: omit to use server default filter]. | |
| has_sacap_declaration | No | Whether the drawing title block contains the registered architectural professional full name, registration number, category, and signature. [Optional: omit to use server default filter]. | |
| habitable_room_height_mm | No | Specified clear finished floor-to-ceiling height in habitable rooms in millimetres (min. 2,400 mm). [Optional: omit to use server default filter]. | |
| has_rodding_eyes_at_bends | No | Whether rodding eyes or inspection chambers are provided at drainage bends > 45° and junctions. [Optional: omit to use server default filter]. | |
| external_wall_thickness_mm | No | External wall thickness in millimetres (standard cavity wall is min. 270 mm). [Optional: omit to use server default filter]. | |
| has_renewable_water_heating | No | Whether min. 50% solar water heating or heat pump is specified as required by SANS 10400-XA. | |
| gully_height_above_ground_mm | No | Height of sewer gully head coping above finished ground level in millimetres (min. 150 mm). [Optional: omit to use server default filter]. | |
| has_safety_glass_below_800mm | No | Whether safety glass (SANS 1263-1) is specified for all glazing with sill < 800 mm from FFL. [Optional: omit to use server default filter]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The Behavior section adds real information beyond the annotations: a 60 requests/min per-IP rate limit and public unauthenticated access. The read-only/idempotent/no-mutation claims merely restate readOnlyHint, idempotentHint and destructiveHint, so they earn no extra credit. Nothing is said about how the optional parameters interact, what score scale is used, or how failures 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose sentence is well front-loaded, but the 'When to use' sentence spends words saying 'call this tool when you need to call this tool', and the parameters sentence duplicates the schema verbatim. The closing 'Returns' sentence is generic template text that also conflicts slightly with the specific outputs claimed in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter tool with no output schema, the description should carry more of the return-value and interpretation burden. It names the outputs (compliance readiness score, defect warnings, submission checklist) but doesn't explain the score's scale, what defects look like, or whether omitted optional fields are simply skipped in the check versus reported as unknowns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, establishing a baseline of 3. The description only re-lists the parameter names (project_name, municipality, building_class, ...) without adding semantics, so it neither helps nor misleads beyond the schema, which already explains units, defaults and SANS context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource ('run an automated multi-point regulatory validation on building plan specifications') plus the outputs, which is far more informative than the tool name alone. However, the sibling differentiation in the 'When to use' block is content-free boilerplate ('use ... for their respective operations'), so the agent learns the siblings exist but not what distinguishes them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than explained: the tool is for a full multi-point compliance pass, and the named alternatives (get_sans_rules, check_municipal_requirements, get_common_rejection_pitfalls) suggest this is the aggregate check. But the exclusion condition is tautological ('Do NOT use when another specialized tool fits better'), giving no actual decision rule such as 'use get_sans_rules to look up a single clause'.
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.
5 tool updates
- Changed
calculate_sans_fenestration4 fields changed- changed
Input schema / properties / actual_glazed_area_m2 / descriptionPrevious value: -"Total installed window glazed area in square metres (m²)."New value: +"Total installed window glazed area in square metres (m²). [Optional: omit to use server default filter]." - changed
Input schema / properties / actual_openable_area_m2 / descriptionPrevious value: -"Total installed clear openable window sash ventilation area in square metres (m²)."New value: +"Total installed clear openable window sash ventilation area in square metres (m²). [Optional: omit to use server default filter]." - changed
Input schema / properties / floor_area_m2 / descriptionPrevious value: -"Internal floor area of the habitable room in square metres (m²)."New value: +"Internal floor area of the habitable room in square metres (m²). [Required: non-empty valid value must be supplied]." - changed
Input schema / properties / room_name / descriptionPrevious value: -"Name or label of the habitable room (e.g. \"Bedroom 1\", \"Living Room\", \"Study\")."New value: +"Name or label of the habitable room (e.g. \"Bedroom 1\", \"Living Room\", \"Study\"). [Optional: omit to use server default filter]."
- Changed
calculate_stair_compliance5 fields changed- changed
Input schema / properties / baluster_gap_mm / descriptionPrevious value: -"Maximum clear gap between vertical balusters in millimetres (must not exceed 100 mm)."New value: +"Maximum clear gap between vertical balusters in millimetres (must not exceed 100 mm). [Optional: omit to use server default filter]." - changed
Input schema / properties / balustrade_height_mm / descriptionPrevious value: -"Height of balustrade in millimetres (min. 1,000 mm on landings, 850 mm on flights)."New value: +"Height of balustrade in millimetres (min. 1,000 mm on landings, 850 mm on flights). [Optional: omit to use server default filter]." - changed
Input schema / properties / going_mm / descriptionPrevious value: -"Stair tread horizontal going in millimetres excluding nosing (must not be less than 250 mm)."New value: +"Stair tread horizontal going in millimetres excluding nosing (must not be less than 250 mm). [Required: non-empty valid value must be supplied]." - changed
Input schema / properties / headroom_mm / descriptionPrevious value: -"Vertical headroom clearance in millimetres measured vertically from the nosing pitch line (must be min. 2,100 mm)."New value: +"Vertical headroom clearance in millimetres measured vertically from the nosing pitch line (must be min. 2,100 mm). [Optional: omit to use server default filter]." - changed
Input schema / properties / riser_mm / descriptionPrevious value: -"Stair riser vertical height in millimetres (must not exceed 200 mm)."New value: +"Stair riser vertical height in millimetres (must not exceed 200 mm). [Required: non-empty valid value must be supplied]."
- Changed
check_municipal_requirements1 field changed- changed
Input schema / properties / municipality / descriptionPrevious value: -"Municipality name or abbreviation (e.g. \"City of Johannesburg\", \"COJ\", \"Tshwane\", \"Pretoria\", \"City of Cape Town\", \"COCT\", \"Ekurhuleni\", \"eThekwini\", \"Durban\")."New value: +"Municipality name or abbreviation (e.g. \"City of Johannesburg\", \"COJ\", \"Tshwane\", \"Pretoria\", \"City of Cape Town\", \"COCT\", \"Ekurhuleni\", \"eThekwini\", \"Durban\"). [Required: non-empty valid value must be supplied]."
- Changed
get_sans_rules2 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Category filter (e.g. \"Dimensions\", \"Glazing\", \"Stairways\", \"Fire Safety\", \"Drainage\", \"Walls\", \"Energy Efficiency\")."New value: +"Category filter (e.g. \"Dimensions\", \"Glazing\", \"Stairways\", \"Fire Safety\", \"Drainage\", \"Walls\", \"Energy Efficiency\"). [Optional: omit to use server default filter]." - changed
Input schema / properties / sans_part / descriptionPrevious value: -"SANS 10400 Part identifier (e.g. \"Part A\", \"Part C\", \"Part K\", \"Part M\", \"Part N\", \"Part O\", \"Part P\", \"Part S\", \"Part T\", \"Part XA\")."New value: +"SANS 10400 Part identifier (e.g. \"Part A\", \"Part C\", \"Part K\", \"Part M\", \"Part N\", \"Part O\", \"Part P\", \"Part S\", \"Part T\", \"Part XA\"). [Optional: omit to use server default filter]."
- Changed
pre_check_building_plan9 fields changed- changed
Input schema / properties / external_wall_thickness_mm / descriptionPrevious value: -"External wall thickness in millimetres (standard cavity wall is min. 270 mm)."New value: +"External wall thickness in millimetres (standard cavity wall is min. 270 mm). [Optional: omit to use server default filter]." - changed
Input schema / properties / gully_height_above_ground_mm / descriptionPrevious value: -"Height of sewer gully head coping above finished ground level in millimetres (min. 150 mm)."New value: +"Height of sewer gully head coping above finished ground level in millimetres (min. 150 mm). [Optional: omit to use server default filter]." - changed
Input schema / properties / habitable_room_height_mm / descriptionPrevious value: -"Specified clear finished floor-to-ceiling height in habitable rooms in millimetres (min. 2,400 mm)."New value: +"Specified clear finished floor-to-ceiling height in habitable rooms in millimetres (min. 2,400 mm). [Optional: omit to use server default filter]." - changed
Input schema / properties / has_rodding_eyes_at_bends / descriptionPrevious value: -"Whether rodding eyes or inspection chambers are provided at drainage bends > 45° and junctions."New value: +"Whether rodding eyes or inspection chambers are provided at drainage bends > 45° and junctions. [Optional: omit to use server default filter]." - changed
Input schema / properties / has_sacap_declaration / descriptionPrevious value: -"Whether the drawing title block contains the registered architectural professional full name, registration number, category, and signature."New value: +"Whether the drawing title block contains the registered architectural professional full name, registration number, category, and signature. [Optional: omit to use server default filter]." - changed
Input schema / properties / has_safety_glass_below_800mm / descriptionPrevious value: -"Whether safety glass (SANS 1263-1) is specified for all glazing with sill < 800 mm from FFL."New value: +"Whether safety glass (SANS 1263-1) is specified for all glazing with sill < 800 mm from FFL. [Optional: omit to use server default filter]." - changed
Input schema / properties / has_sans_forms / descriptionPrevious value: -"Whether SANS 10400 Form 1 and Form 2 (if structural work included) are prepared."New value: +"Whether SANS 10400 Form 1 and Form 2 (if structural work included) are prepared. [Optional: omit to use server default filter]." - changed
Input schema / properties / municipality / descriptionPrevious value: -"Target South African municipality for plan submission (e.g. \"City of Johannesburg\", \"Tshwane\", \"City of Cape Town\", \"Ekurhuleni\", \"eThekwini\")."New value: +"Target South African municipality for plan submission (e.g. \"City of Johannesburg\", \"Tshwane\", \"City of Cape Town\", \"Ekurhuleni\", \"eThekwini\"). [Required: non-empty valid value must be supplied]." - changed
Input schema / properties / project_name / descriptionPrevious value: -"Name of the building or architectural project."New value: +"Name of the building or architectural project. [Optional: omit to use server default filter]."
7 tool updates
- First observed
calculate_sans_fenestration - First observed
calculate_stair_compliance - First observed
check_municipal_requirements - First observed
get_common_rejection_pitfalls - First observed
get_credit_pricing - First observed
get_sans_rules - First observed
pre_check_building_plan
Related MCP Connectors
Building plan approvals, occupancy certificates, and municipal compliance readiness tools.
Built-environment forecasts, public benchmarks, and permit or zoning readiness through remote MCP.
Construction compliance answers for trades: AU, UK, US, Canada and EU codes, RAMS and checklists.
Draw buildings as DXF, IFC and 3D, plus exact French rent and charges calculations.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProfessional building code compliance assistant that interfaces with municipal building codes, helping contractors and builders navigate complex regulatory requirements with precision.1MIT
- FlicenseNot gradedqualityFmaintenanceEnables municipal permit preflight checks for construction and renovation projects, returning evidence-linked, rule-version-aware results without using an LLM.-
- FlicenseNot gradedqualityDmaintenanceExposes Pre-DCR and Auto-DCR building scrutiny workflows as AI-consumable tools, enabling AI assistants to open DXF drawings, validate layers, compute areas, run regulatory checks, and generate compliance reports via natural language.-
- AlicenseNot gradedqualityCmaintenanceConverts architectural PDF plans into dimension-verified millimetre geometry, IFC models, and CPU-rendered views, with built-in validation for boundaries, areas, and overlaps.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.