Servidor MCP

civilquants

com.civilquants/civilquants
Negocio y operaciones Ciencia e ingeniería Público y accesible MCP 2025-11-25

Qué hace este MCP

Calculates parametric civil-engineering quantities and Bills of Quantities for drainage, earthworks, retaining walls, pavements, foundations, and related infrastructure assemblies.

compute_anchored_wall
Compute Anchored Retaining Wall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Anchored retaining wall — the only wall family member that pre-stresses the retained soil mass into the wall via post-tensioned ground anchors per BS EN 1537. Three structural variants: in-situ reinforced concrete (INSITU_RC, economic 5-10m); steel king-post-and-lagging (KING_POST, typical 4-8m, often temporary); driven sheet pile (SHEET_PILED, quays/cofferdams/deep basements). Eight VARIANT_PRESETS exercise the 'one parameter form, eight variants, four standards' moat #1 claim across all three structural variants. The in-situ RC body routes via wall_type='anchored' attribute discrimination: CESMM4 F.6.4, NRM2 11.3.4, MMHW 1700.4.3 (SHW Cl. 1709/1710), SMM7 E10.3.3. Ground anchors and stressing route to new specialist handlers (CESMM4 Class C; NRM2 Group 7; MMHW Series 1600; SMM7 D32). King-post sections to CESMM4 P.5 / NRM2 7.3 / MMHW 1600.3 / SMM7 D32; sheet piles to CESMM4 P.4 / NRM2 7.4 / MMHW 1600.4 / SMM7 D31; timber lagging to CESMM4 O.3 / NRM2 16.4 / MMHW 2500.7 / SMM7 G20.1. Example params: stem_height=6 m (2–15), stem_thickness=0.5 m (0–1.5), wall_length=25 m (5–200). Example call: {"params": {"stem_height": 6, "stem_thickness": 0.5, "wall_length": 25}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier). Pass `freeboard` (clearance below the wall top, m) instead of the retained-height field to set the retained fill by clearance — the engine back-calculates it as stem − freeboard. Supplying both is rejected.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'wall_form': {'enum': ['insitu_rc', 'king_post', 'sheet_piled'], 'type': 'string', 'default': 'insitu_rc', 'description': 'Structural form of the anchored retaining wall.\n\nINSITU_RC   â\x80\x94 Continuous in-situ reinforced concrete stem with a\n              continuous waling beam (typically at the wall head;\n              multi-row anchored walls have a waling at each anchor\n              level). Anchors penetrate the stem and are stressed\n              against the waling. Routes the stem to CESMM4 F.6.4 /\n              NRM2 11.3.4 / MMHW 1700.4.3 / SMM7 E10.3.3.\n\nKING_POST   â\x80\x94 Steel H-section (UC or UB) "king posts" or "soldier\n              piles" driven or socketed at regular centres\n              (typically 2.0-3.0 m c/c), with horizontal timber\n              or precast concrete lagging panels between. A\n              continuous RC waling beam runs at the head (and at\n              each anchor row if multi-row) transferring the anchor\n              loads to the king posts. King posts â\x86\x92 CESMM4 P.5 /\n              NRM2 7.3 / MMHW 1600.3 / SMM7 D32. Lagging â\x86\x92\n              CESMM4 O.3 (timber) or F.6.4 (precast concrete) /\n              NRM2 16.4 (timber) or 13 (precast) / MMHW 2500.7\n              (timber) or 1700.4.3 (precast) / SMM7 G20.1 (timber)\n              or E50 (precast).\n\nSHEET_PILED â\x80\x94 Driven steel sheet piles (Larssen LX, AZ, GU\n              profiles) forming a continuous wall, with a\n              continuous RC waling at the head. Sheet pile toe\n              drives below the excavation formation to provide\n              passive resistance; anchor loads at the head are\n              restrained back. Sheet piles â\x86\x92 CESMM4 P.4 /\n              NRM2 7.4 / MMHW 1600.4 / SMM7 D31.'}, 'toe_length': {'type': 'number', 'default': 0.0}, 'anchor_rows': {'type': 'integer', 'default': 1}, 'stem_height': {'type': 'number', 'default': 6.0}, 'wall_length': {'type': 'number', 'default': 25.0}, 'lagging_type': {'enum': ['timber', 'precast_conc'], 'type': 'string', 'default': 'timber', 'description': 'For KING_POST variant: timber or precast concrete lagging.\n\nTIMBER         â\x80\x94 Horizontal timber boards (C24 or similar) between\n                 king-post flanges. Lower cost; permitted only for\n                 temporary works and certain permanent applications\n                 where durability allows (creosote treatment etc.).\nPRECAST_CONC   â\x80\x94 Precast concrete lagging panels between king-post\n                 flanges. Used for permanent works where timber\n                 is not acceptable. More expensive than timber.\n\nOnly relevant when wall_form == KING_POST. Ignored otherwise.'}, 'backfill_class': {'type': 'string', 'default': 'Class 6N'}, 'base_thickness': {'type': 'number', 'default': 0.0}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'drain_diameter': {'type': 'number', 'default': 0.15}, 'stem_thickness': {'type': 'number', 'default': 0.5}, 'king_post_grade': {'type': 'string', 'default': 'S355'}, 'retained_height': {'type': 'number', 'default': 5.5}, 'anchor_test_type': {'type': 'string', 'default': 'proof'}, 'include_drainage': {'type': 'boolean', 'default': True}, 'sheet_pile_grade': {'type': 'string', 'default': 'S355GP'}, 'anchor_permanence': {'enum': ['permanent', 'temporary'], 'type': 'string', 'default': 'permanent', 'description': 'Permanent or temporary anchor classification per BS EN 1537.\n\nPERMANENT â\x80\x94 Design life >= 2 years; tendons require double\n            corrosion protection (DCP) per BS EN 1537 Table 1.\n            Stressing forces locked off and retained for life.\nTEMPORARY â\x80\x94 Design life < 2 years (typically supporting basement\n            excavation until permanent structure is built).\n            Single corrosion protection (SCP) acceptable.\n            Often de-stressed and tendons cropped on completion.'}, 'excavation_batter': {'type': 'number', 'default': 0.0}, 'king_post_section': {'type': 'string', 'default': 'UC 305Ã\x97305Ã\x9797'}, 'anchor_tendon_type': {'type': 'string', 'default': 'strand'}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'vertical', 'description': 'Excavation support strategy for below-ground assemblies.\n\nConsumed by retaining walls (cantilever, gravity, counterfort,\nanchored, bored pile), foundation assemblies, and drainage chambers\nthat involve a battered or vertical-supported pit. The enum value is\nsurfaced in the description text of the relevant excavation BoQ line\nand in some standards (CESMM4 E.4.4 et seq.) drives a separate code.'}, 'include_geotextile': {'type': 'boolean', 'default': True}, 'sheet_pile_profile': {'type': 'string', 'default': 'Larssen LX-20'}, 'king_post_spacing_m': {'type': 'number', 'default': 2.5}, 'anchor_free_length_m': {'type': 'number', 'default': 6.0}, 'formation_below_base': {'type': 'number', 'default': 0.15}, 'lagging_preservative': {'type': 'string', 'default': 'creosote'}, 'lagging_thickness_mm': {'type': 'integer', 'default': 75}, 'lagging_timber_grade': {'type': 'string', 'default': 'C24'}, 'anchor_fixed_length_m': {'type': 'number', 'default': 4.0}, 'lagging_precast_grade': {'type': 'string', 'default': 'C40/50'}, 'waling_concrete_grade': {'type': 'string', 'default': 'C40/50'}, 'anchor_inclination_deg': {'type': 'number', 'default': 20.0}, 'anchor_working_load_kN': {'type': 'number', 'default': 300.0}, 'waling_section_width_m': {'type': 'number', 'default': 0.4}, 'anchor_test_load_factor': {'type': 'number', 'default': 1.25}, 'king_post_penetration_m': {'type': 'number', 'default': 3.0}, 'reinforcement_kg_per_m3': {'type': 'number', 'default': 150.0}, 'waling_section_height_m': {'type': 'number', 'default': 0.5}, 'anchor_drill_diameter_mm': {'type': 'integer', 'default': 150}, 'excavation_working_space': {'type': 'number', 'default': 0.6}, 'sheet_pile_total_length_m': {'type': 'number', 'default': 10.0}, 'anchor_corrosion_protection': {'enum': ['single', 'double'], 'type': 'string', 'default': 'single', 'description': 'Anchor corrosion protection level per BS EN 1537.\n\nSINGLE â\x80\x94 Grease-and-sheath protection of free length;\n         grouted-only fixed length. Acceptable for temporary\n         anchors and benign permanent environments.\nDOUBLE â\x80\x94 Grease-and-sheath PLUS a continuous corrugated plastic\n         duct over the full free length, AND a corrugated duct\n         over the fixed length. Mandatory for permanent anchors\n         in aggressive ground per BS EN 1537 Table 1.'}, 'anchor_horizontal_spacing_m': {'type': 'number', 'default': 2.5}, 'anchor_row_levels_below_top_m': {'type': 'array', 'items': {'type': 'number'}, 'default': [1.0]}, 'waling_reinforcement_kg_per_m3': {'type': 'number', 'default': 180.0}}, 'description': 'Parameter form for an anchored retaining wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields and the\n``wall_form`` discriminator â\x80\x94 produces all eight VARIANT_PRESETS plus\narbitrary user-specified geometries across all three structural\nvariants (INSITU_RC, KING_POST, SHEET_PILED). Sensible defaults\nyield a 6m in-situ RC wall with a single row of permanent anchors.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'freeboard': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_attenuation_tank
Compute Stormwater Attenuation Tank BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. Stormwater attenuation tank supporting two configurations: modular geocellular crates (high void ratio, compact footprint) or large-bore pipe arrays (1.5m+ ID concrete pipes in parallel runs). Excavation may be open-battered or vertical-sided with sheet pile support. Example params: tank_length=30 m (2–200), crate_width=6 m (1–20), crate_height=1.2 m (0.4–3.6). Example call: {"params": {"tank_length": 30, "crate_width": 6, "crate_height": 1.2}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'tank_type': {'enum': ['crate', 'pipes'], 'type': 'string', 'default': 'crate'}, 'pipe_count': {'type': 'integer', 'default': 3}, 'crate_width': {'type': 'number', 'default': 6.0}, 'tank_length': {'type': 'number', 'default': 30.0}, 'crate_height': {'type': 'number', 'default': 1.2}, 'pipe_diameter': {'type': 'number', 'default': 1.5}, 'crate_void_ratio': {'type': 'number', 'default': 0.95}, 'bedding_thickness': {'type': 'number', 'default': 0.15}, 'cover_to_tank_top': {'type': 'number', 'default': 0.8}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'surround_material': {'type': 'string', 'default': '20mm single-size aggregate'}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'pipe_clear_spacing': {'type': 'number', 'default': 0.4}, 'pipe_wall_thickness': {'type': 'number', 'default': 0.11}, 'cover_material_class': {'type': 'string', 'default': 'Class 6N'}, 'geotextile_full_wrap': {'type': 'boolean', 'default': True}, 'working_space_each_side': {'type': 'number', 'default': 0.6}, 'formation_prep_thickness': {'type': 'number', 'default': 0.15}, 'granular_surround_thickness': {'type': 'number', 'default': 0.3}, 'sheet_pile_depth_below_formation': {'type': 'number', 'default': 1.5}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_bored_pile_wall
Compute Bored Pile Retaining Wall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Cast-in-place bored concrete pile retaining wall, the SEVENTH member of the wall family and the FIFTH of the retaining_walls L1 leaf. The SIXTH structural system in the retaining / earth-structures domain (after mass concrete / RC / steel / mesh-and-stone / reinforced-soil-with-facing). Four structural forms via the bored_pile_form discriminator: CONTIGUOUS (clear-spaced piles, shotcrete face), SECANT_HARD_SOFT (alternating soft/hard overlapping piles, intermediate watertightness), SECANT_HARD_HARD (overlapping RC piles, maximum watertightness; deep basements), and KING_POST_AND_LAGGING_RC (widely-spaced RC king posts with lagging panels). 18th use of the classed-then-legacy attribute discrimination pattern, applied via the CONCRETE_REINFORCED handler's new wall_type='bored_pile' branch for the capping beam (when included). Routes via five new WorkCategory entries (BORED_PILE_CONCRETE, BORED_PILE_BORE, BORED_PILE_NR, BORED_PILE_HEAD_PREP, BORED_PILE_INTERLOCK) covering the CESMM4 Class P §P.8 three-line cast-in-place pile measurement convention plus the Class Q ancillaries head-prep line and the secant-specific interlock line. Codes: CESMM4 P.8.1-4 + Q.1.1, NRM2 7.6.1-4 + 7.5.1, MMHW 1600.5-6 (SHW Cl. 1602/1603), and SMM7 D30.1-5 — D30 (Cast in place piling) is OPENED at this session as the conventional UK QS named home. Capping beam routes via CONCRETE_REINFORCED with wall_type='bored_pile' to F.6.5 / 11.3.5 / 1700.4.4 / E10.3.4. Reinforcement billed itemised (separate audit line per BS 8666:2020 cage) on top of the pile rate by S31 decision. Eight variant presets exercise all four BoredPileForm values (2/2/2/2 split). Example params: wall_length_m=20 m (5–200), retained_height_m=6 m (2–20), embedment_below_formation_m=4 m (1–15). Example call: {"params": {"wall_length_m": 20, "retained_height_m": 6, "embedment_below_formation_m": 4}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'overlap_mm': {'type': 'integer', 'default': 100}, 'basement_use': {'enum': ['basement_below_ground', 'highway_cutting', 'rail_box', 'shaft_lining', 'cofferdam', 'utility_trench'], 'type': 'string', 'default': 'basement_below_ground', 'description': 'Intended use of the wall (drives concrete cover and crack-width\nrequirements, not the geometry).'}, 'cage_cover_mm': {'type': 'integer', 'default': 75}, 'wall_length_m': {'type': 'number', 'default': 20.0}, 'face_treatment': {'enum': ['shotcrete_and_mesh', 'precast_lagging_panels', 'exposed', 'architectural_finish'], 'type': 'string', 'default': 'shotcrete_and_mesh', 'description': 'Face treatment between / over piles.'}, 'bored_pile_form': {'enum': ['contiguous', 'secant_hard_soft', 'secant_hard_hard', 'king_post_and_lagging_rc'], 'type': 'string', 'default': 'contiguous', 'description': 'Structural form of the bored pile retaining wall.'}, 'cut_off_depth_mm': {'type': 'integer', 'default': 400}, 'pile_diameter_mm': {'type': 'integer', 'default': 600}, 'retained_height_m': {'type': 'number', 'default': 6.0}, 'cage_link_pitch_mm': {'type': 'integer', 'default': 200}, 'cage_main_bar_count': {'type': 'integer', 'default': 12}, 'cage_mass_kg_per_m3': {'type': 'number', 'default': 220.0}, 'pile_concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'capping_beam_width_m': {'type': 'number', 'default': 0.8}, 'include_capping_beam': {'type': 'boolean', 'default': True}, 'shotcrete_mesh_grade': {'type': 'string', 'default': 'A142 mesh per BS 4483'}, 'cage_link_diameter_mm': {'type': 'integer', 'default': 12}, 'capping_beam_cover_mm': {'type': 'integer', 'default': 50}, 'capping_beam_height_m': {'type': 'number', 'default': 0.9}, 'working_space_width_m': {'type': 'number', 'default': 1.0}, 'pile_spacing_centres_m': {'type': 'number', 'default': 0.9}, 'shotcrete_thickness_mm': {'type': 'integer', 'default': 100}, 'soft_pile_concrete_grade': {'type': 'string', 'default': 'C8/10'}, 'cage_main_bar_diameter_mm': {'type': 'integer', 'default': 25}, 'capping_beam_link_pitch_mm': {'type': 'integer', 'default': 200}, 'capping_beam_main_bars_top': {'type': 'integer', 'default': 4}, 'capping_beam_concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'embedment_below_formation_m': {'type': 'number', 'default': 4.0}, 'capping_beam_link_diameter_mm': {'type': 'integer', 'default': 12}, 'capping_beam_main_bars_bottom': {'type': 'integer', 'default': 4}, 'include_working_space_excavation': {'type': 'boolean', 'default': False}, 'capping_beam_main_bar_diameter_mm': {'type': 'integer', 'default': 25}, 'capping_beam_reinforcement_kg_per_m3': {'type': 'number', 'default': 180.0}}, 'description': 'Parameter form for a bored pile retaining wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields and\nthe ``bored_pile_form`` discriminator â\x80\x94 produces all eight\nVARIANT_PRESETS plus arbitrary user-specified geometries across\nall four BoredPileForm options. Sensible defaults yield a 6m\nbasement-wall CONTIGUOUS bored pile wall.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_box_culvert
Compute Precast Concrete Box Culvert BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Precast concrete box culvert run (Marshalls / FP McCann / CPM ranges, BS EN 14844 / BS 5911-3) of one of eight catalogue sizes from BC_600 (600 × 600mm) to BC_3000x2000 (3000 × 2000mm). Composes the precast units (N per run), concrete blinding bedding, geotextile separator, selected granular surround per SHW Cl. 503, and foundation excavation with optional sheet pile support. Optional headwall_attenuation_outlet (2nd use of S21) at each termination with independently parameter-selectable scour protection (rock armour, gabion mattress, concrete apron, or none). Routes BOX_CULVERT_UNIT via CESMM4 H.7.3/.4/.5 (precast concrete, size banded), NRM2 33.8.1/.2/.3, MMHW 500.12.1/.2/.3 (with Series 2500 signpost for large units per Volume 4 NG 25), and SMM7 R12.4.5/.6/.7. Example params: total_length_m=12 m (1–200), invert_depth_m=2.5 m (0.5–15), invert_gradient=0.005 (0–0.08). Example call: {"params": {"total_length_m": 12, "invert_depth_m": 2.5, "invert_gradient": 0.005}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['BC_600', 'BC_900', 'BC_1200', 'BC_1500x1200', 'BC_1800x1500', 'BC_2400x1800', 'BC_2400x2000', 'BC_3000x2000'], 'type': 'string', 'default': 'BC_1500x1200', 'description': 'Standard UK precast concrete box culvert sizes. Drawn from the\nMarshalls / FP McCann / CPM published ranges; values are the\nnominal clear span Ã\x97 clear height in millimetres. BS EN 14844 /\nBS 5911-3.\n\nEight catalogue sizes spanning the practical range:\n\n  BC_600          â\x80\x94  600 Ã\x97  600 (smallest; small watercourses)\n  BC_900          â\x80\x94  900 Ã\x97  900 (small; minor streams)\n  BC_1200         â\x80\x94 1200 Ã\x97 1200 (small; agricultural)\n  BC_1500x1200    â\x80\x94 1500 Ã\x97 1200 (medium; equine / accommodation)\n  BC_1800x1500    â\x80\x94 1800 Ã\x97 1500 (medium; main watercourses)\n  BC_2400x1800    â\x80\x94 2400 Ã\x97 1800 (large; pedestrian / livestock subway)\n  BC_2400x2000    â\x80\x94 2400 Ã\x97 2000 (large; pedestrian subway)\n  BC_3000x2000    â\x80\x94 3000 Ã\x97 2000 (largest practical without bespoke\n                                 order; vehicular accommodation\n                                 culvert / small bridge alternative)'}, 'span_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'integer', 'default': 1}, 'height_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'project_ref': {'type': 'string', 'default': 'Box culvert'}, 'unit_mass_t': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit_length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'chainage_label': {'type': 'string', 'default': ''}, 'invert_depth_m': {'type': 'number', 'default': 2.5}, 'total_length_m': {'type': 'number', 'default': 12.0}, 'invert_gradient': {'type': 'number', 'default': 0.005}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'surround_material': {'type': 'string', 'default': 'Class 6N selected granular fill'}, 'wall_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'bedding_overhang_m': {'type': 'number', 'default': 0.15}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support method. OPEN_BATTER assumes side slopes per the\n``excavation_batter`` parameter (H:V); VERTICAL_SUPPORTED assumes\nsheet piles or trench boxes and emits EXCAVATION_SUPPORT m² items.'}, 'has_upstream_headwall': {'type': 'boolean', 'default': True}, 'bedding_blinding_grade': {'type': 'string', 'default': 'C20/25'}, 'upstream_headwall_size': {'enum': ['PHW_300', 'PHW_375', 'PHW_450', 'PHW_600', 'PHW_750', 'PHW_900', 'PHW_1050', 'PHW_1200', 'PHW_1500'], 'type': 'string', 'default': 'PHW_900', 'description': 'Standard UK precast headwall sizes, by outfall pipe internal diameter.\n\nThese bracket the offerings from Marshalls CPM, FP McCann, and\nStanton Bonna. The unit size determines the CESMM4 Class H sub-code\n(H.7.1 â\x89¤ 1200mm, H.7.2 > 1200mm), the typical mass for handling\nplant requirements, and the bedding footprint.'}, 'upstream_stone_size_mm': {'type': 'integer', 'default': 200}, 'has_downstream_headwall': {'type': 'boolean', 'default': True}, 'downstream_headwall_size': {'enum': ['PHW_300', 'PHW_375', 'PHW_450', 'PHW_600', 'PHW_750', 'PHW_900', 'PHW_1050', 'PHW_1200', 'PHW_1500'], 'type': 'string', 'default': 'PHW_900', 'description': 'Standard UK precast headwall sizes, by outfall pipe internal diameter.\n\nThese bracket the offerings from Marshalls CPM, FP McCann, and\nStanton Bonna. The unit size determines the CESMM4 Class H sub-code\n(H.7.1 â\x89¤ 1200mm, H.7.2 > 1200mm), the typical mass for handling\nplant requirements, and the bedding footprint.'}, 'downstream_stone_size_mm': {'type': 'integer', 'default': 200}, 'cover_to_top_of_culvert_m': {'type': 'number', 'default': 0.6}, 'upstream_headwall_bedding': {'enum': ['concrete_bed', 'granular_bed'], 'type': 'string', 'default': 'concrete_bed', 'description': 'Bedding type beneath a precast headwall.\n\nCONCRETE_BED uses mass concrete blinding (typically C8/10 or C16/20)\nunder the unit, providing a level rigid surface and tying the unit\nto the formation. Common for soft cohesive ground and where flow\nerosion under the unit is a risk.\n\nGRANULAR_BED uses imported Class 6N or 6P granular material per\nSHW Cl. 803, compacted and levelled. Common for non-erodible\ngranular soils where a concrete bed is unnecessary.'}, 'upstream_scour_protection': {'enum': ['rock_armour', 'gabion_mattress', 'concrete_apron', 'none'], 'type': 'string', 'default': 'rock_armour', 'description': 'Scour protection variant downstream of the headwall outfall.\n\nROCK_ARMOUR is the existing headwall_precast variant (granular fill,\nrock armour blanket). GABION_MATTRESS and CONCRETE_APRON are the\nnew S21 extensions for higher-energy or longer-lasting requirements.\nNONE skips scour protection entirely (rare; only suitable for\ndischarge into a robust receiving channel like a piled concrete\nweir basin).'}, 'working_space_each_side_m': {'type': 'number', 'default': 0.6}, 'geotextile_separator_grade': {'type': 'string', 'default': '200 g/m²'}, 'downstream_headwall_bedding': {'enum': ['concrete_bed', 'granular_bed'], 'type': 'string', 'default': 'concrete_bed', 'description': 'Bedding type beneath a precast headwall.\n\nCONCRETE_BED uses mass concrete blinding (typically C8/10 or C16/20)\nunder the unit, providing a level rigid surface and tying the unit\nto the formation. Common for soft cohesive ground and where flow\nerosion under the unit is a risk.\n\nGRANULAR_BED uses imported Class 6N or 6P granular material per\nSHW Cl. 803, compacted and levelled. Common for non-erodible\ngranular soils where a concrete bed is unnecessary.'}, 'downstream_scour_protection': {'enum': ['rock_armour', 'gabion_mattress', 'concrete_apron', 'none'], 'type': 'string', 'default': 'rock_armour', 'description': 'Scour protection variant downstream of the headwall outfall.\n\nROCK_ARMOUR is the existing headwall_precast variant (granular fill,\nrock armour blanket). GABION_MATTRESS and CONCRETE_APRON are the\nnew S21 extensions for higher-energy or longer-lasting requirements.\nNONE skips scour protection entirely (rare; only suitable for\ndischarge into a robust receiving channel like a piled concrete\nweir basin).'}, 'include_outlet_flow_control': {'type': 'boolean', 'default': False}, 'upstream_apron_thickness_mm': {'type': 'integer', 'default': 300}, 'upstream_scour_apron_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'bedding_blinding_thickness_mm': {'type': 'integer', 'default': 150}, 'downstream_apron_thickness_mm': {'type': 'integer', 'default': 300}, 'upstream_scour_apron_length_m': {'type': 'number', 'default': 2.0}, 'downstream_scour_apron_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'surround_thickness_each_side_m': {'type': 'number', 'default': 0.3}, 'downstream_scour_apron_length_m': {'type': 'number', 'default': 2.5}, 'upstream_headwall_bedding_grade': {'type': 'string', 'default': 'C8/10'}, 'downstream_headwall_bedding_grade': {'type': 'string', 'default': 'C8/10'}, 'sheet_pile_depth_below_formation_m': {'type': 'number', 'default': 1.0}}, 'description': "Parameter form for a precast concrete box culvert run.\n\nCatalogue-driven: pick a ``size`` and the section's nominal\nspan / height / mass / wall thickness are read from ``_CATALOGUE``.\nOverride individual fields if a specific manufacturer differs.\n\nThe run is composed of ``ceil(total_length_m / unit_length_m)``\nprecast sections of the chosen size. Headwalls at each end are\noptional and each independently selectable, with the\nheadwall_attenuation_outlet sub-assembly owning its size, bedding,\noutlet ironmongery, and scour protection. Per the S23 spec, the\nheadwalls are emitted as fully separate sub-assemblies â\x80\x94 their\nWorkItems carry their own ``source_assembly`` tag."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_cantilever_wall
Compute Cantilever Retaining Wall BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. In-situ reinforced concrete cantilever retaining wall with toe, heel, and stem. Includes excavation, blinding, drainage, and backfill quantities. Example params: stem_height=4 m (2–8), stem_thickness_top=0.3 m (0.2–0.6), stem_thickness_bottom=0.45 m (0.25–0.9). Example call: {"params": {"stem_height": 4, "stem_thickness_top": 0.3, "stem_thickness_bottom": 0.45}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier). Pass `freeboard` (clearance below the wall top, m) instead of the retained-height field to set the retained fill by clearance — the engine back-calculates it as stem − freeboard. Supplying both is rejected.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'toe_length': {'type': 'number', 'default': 0.8}, 'heel_length': {'type': 'number', 'default': 1.7}, 'stem_height': {'type': 'number', 'default': 4.0}, 'wall_length': {'type': 'number', 'default': 25.0}, 'backfill_class': {'type': 'string', 'default': 'Class 6N'}, 'base_thickness': {'type': 'number', 'default': 0.5}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'drain_diameter': {'type': 'number', 'default': 0.15}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'stem_thickness_top': {'type': 'number', 'default': 0.3}, 'drain_surround_width': {'type': 'number', 'default': 0.4}, 'formation_below_base': {'type': 'number', 'default': 0.15}, 'drain_surround_height': {'type': 'number', 'default': 0.4}, 'stem_thickness_bottom': {'type': 'number', 'default': 0.45}, 'reinforcement_kg_per_m3': {'type': 'number', 'default': 130.0}, 'excavation_working_space': {'type': 'number', 'default': 0.6}, 'backfill_height_above_base': {'type': 'number', 'default': 3.8}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'freeboard': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_carrier_pipe_run
Compute Carrier Pipe Run (banded) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Linear carrier-pipe measurement assembly with full four-standard depth-banded rendering. CESMM4 Class I (I.{material}.{bore}.{depth}, 9 depth bands), NRM2 Group 33 (33.1.{bore}.{depth}, equivalent banding), MMHW Series 500 (500.1.{bore}.{depth}, 11 depth bands extending to 6 m for highway-scale carriers per SHW Cl. 501), SMM7 R12 (R12.1.{bore}.{depth}, 10 depth bands starting at 1 m for housing-scale carriers). Twelve variant presets exercise all 9 CESMM4 Class I depth bands and all 5 carrier materials (vitrified clay / concrete / HDPE / ductile iron / uPVC) — 12 × 4 = 48 distinguishable BoQ rows from a single parameter form. 19th use of the classed-then-legacy attribute discrimination pattern, FIRST applied to a Class I (Pipework) category — discriminator here is `material` itself, with the CESMM4 handler routing through the 5 Class I material sub-class digits while NRM2/MMHW/SMM7 stay within their respective groups but distinguish material in the description. Companion assembly: connection_to_existing (S32 sibling pair) — the enumerated extra-over connection line that ties a carrier run into an adopted asset. Example params: diameter_mm=225 mm (100–2400), invert_depth_m=1.8 m (0.5–10), run_length_m=30 m (1–2000). Example call: {"params": {"diameter_mm": 225, "invert_depth_m": 1.8, "run_length_m": 30}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'use': {'enum': ['housing lateral', 'estate carrier', 'site carrier', 'district trunk', 'urban trunk', 'combined sewer main', 'rising main'], 'type': 'string', 'default': 'estate carrier', 'description': 'Functional use of the carrier pipe â\x80\x94 informs description text.\nDoes NOT change the BoQ code (the codes are governed by material,\nbore and depth only). Use is reflected in the description so the\nQS reading the priced bill can see which run is which.'}, 'jointing': {'enum': ['flexible elastomeric', 'electrofusion', 'push-fit gasket', 'solvent weld'], 'type': 'string', 'default': 'flexible elastomeric', 'description': 'How sections of the run are jointed end-to-end.'}, 'material': {'enum': ['vitrified clay', 'concrete', 'hdpe', 'ductile iron', 'upvc'], 'type': 'string', 'default': 'vitrified clay', 'description': 'Carrier pipe material families per BS EN standards. Maps to the\nClass I material sub-class digits 1-6 in the CESMM4 renderer\n(see _CESMM4_CLASS_I_MATERIAL_DIGIT).'}, 'diameter_mm': {'type': 'integer', 'default': 225}, 'run_length_m': {'type': 'number', 'default': 30.0}, 'invert_depth_m': {'type': 'number', 'default': 1.8}, 'description_override': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}}, 'description': 'Parameters for a carrier pipe run.\n\nGeometric defaults yield a DN225 vitrified clay carrier at 1.8 m\naverage invert depth over a 30 m run â\x80\x94 the textbook small-civils\nfoul carrier described in the QS measurement examples.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_catchpit
Compute Precast Concrete Catchpit / Silt Trap BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Precast concrete catchpit / silt trap to BS 5911-3 comprising factory-cast monolithic base with integral silt sump (600-900mm below outlet invert), stacked precast chamber rings, precast cover slab, ductile-iron frame and cover (BS EN 124 loading classes), optional step irons, granular or concrete bedding, granular surround, geotextile separator, and excavation. Catalogue-driven sizing from CP_900 (900mm ID) to CP_1800 (1800mm ID). Routes via chamber_type='catchpit' attribute discrimination through CESMM4 K.1.6.x, NRM2 33.7.14, MMHW 500.5.16 (SHW Cl. 511 silt traps), and SMM7 R12.3.13. Distinct from manholes by the silt-sump-below-channel geometry; typical position upstream of petrol/oil interceptor (S24) in a forecourt or service-area drainage train. Example params: invert_depth=2.5 m (0.5–10), bedding_thickness_mm=150 mm (100–300), bedding_overhang_m=0.15 m (0.1–0.3). Example call: {"params": {"invert_depth": 2.5, "bedding_thickness_mm": 150, "bedding_overhang_m": 0.15}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['CP_900', 'CP_1050', 'CP_1200', 'CP_1350', 'CP_1500', 'CP_1800'], 'type': 'string', 'default': 'CP_1200', 'description': 'Standard UK precast catchpit chamber internal diameters per\nBS 5911-3. Catalogued by CPM, FP McCann, Stanton Bonna, and\nCPM Group. CP_900 is the smallest commonly stocked precast\ncatchpit; CP_1800 is the largest practical without bespoke\norder (used for industrial heavy-silt loading or where the\ncatchpit also serves as a silt-removal pre-treatment chamber\nupstream of a Class 1 petrol interceptor).'}, 'quantity': {'type': 'integer', 'default': 1}, 'access_type': {'enum': ['step_irons', 'ladder', 'none'], 'type': 'string', 'default': 'step_irons'}, 'project_ref': {'type': 'string', 'default': ''}, 'ring_mass_t': {'type': 'number', 'default': None}, 'bedding_type': {'enum': ['granular', 'concrete'], 'type': 'string', 'default': 'granular', 'description': 'Bedding layer beneath a precast catchpit base.'}, 'invert_depth': {'type': 'number', 'default': 2.5}, 'cover_loading': {'enum': ['A15', 'B125', 'C250', 'D400', 'E600', 'F900'], 'type': 'string', 'default': 'D400', 'description': 'BS EN 124 cover-and-frame loading classes.'}, 'ring_height_m': {'type': 'number', 'default': None}, 'chainage_label': {'type': 'string', 'default': ''}, 'wall_thickness': {'type': 'number', 'default': None}, 'base_unit_mass_t': {'type': 'number', 'default': None}, 'cover_slab_grade': {'type': 'string', 'default': 'C40/50'}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'internal_diameter': {'type': 'number', 'default': None}, 'silt_sump_depth_m': {'type': 'number', 'default': None}, 'step_iron_spacing': {'type': 'number', 'default': 0.3}, 'surround_material': {'type': 'string', 'default': '20mm single-size aggregate'}, 'base_unit_height_m': {'type': 'number', 'default': None}, 'bedding_overhang_m': {'type': 'number', 'default': 0.15}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'surround_thickness': {'type': 'number', 'default': 0.15}, 'cover_clear_opening': {'type': 'number', 'default': 0.6}, 'bedding_thickness_mm': {'type': 'integer', 'default': 150}, 'cover_slab_thickness': {'type': 'number', 'default': 0.2}, 'cover_to_top_of_slab': {'type': 'number', 'default': 0.075}, 'geotextile_full_wrap': {'type': 'boolean', 'default': True}, 'seating_rings_height': {'type': 'number', 'default': 0.15}, 'bedding_concrete_grade': {'type': 'string', 'default': 'C8/10'}, 'bedding_granular_class': {'type': 'string', 'default': '6N'}, 'working_space_each_side': {'type': 'number', 'default': 0.5}, 'is_pretreatment_for_interceptor': {'type': 'boolean', 'default': False}, 'sheet_pile_depth_below_formation': {'type': 'number', 'default': 1.0}}, 'description': "Parameter form for a precast concrete catchpit / silt trap.\n\nCatalogue-driven: pick a ``size`` and the chamber's nominal\ndimensions, masses, and silt-sump depth are read from\n``_CATALOGUE``. Override individual fields if a specific\nmanufacturer differs.\n\nThe catchpit is treated as a **manhole-family chamber** (same\nWorkCategory.MANHOLE) discriminated on chamber_type='catchpit'."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_combined_services_trench
Compute Combined Services Trench BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Shared utility trench carrying multiple services side by side, each at its own cover depth (water, gas, electricity, telecoms) per NJUG Volume 1. One excavation envelope sized from the services, one disposal, one backfill column, with per-service lane-width bedding, surround, pipe/duct, and warning tape. Renders through CESMM4 Class I, NRM2 Group 41, MMHW Series 1300 and SMM7 Group T for the services, with the shared envelope routing through the existing earthworks/drainage handlers. Example params: trench_length_m=50 m (1–2000), service_spacing_mm=100 mm (50–500), working_space_below_bed_mm=100 mm (0–500). Example call: {"params": {"trench_length_m": 50, "service_spacing_mm": 100, "working_space_below_bed_mm": 100}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'services': {'type': 'array', 'items': {'type': 'object', 'required': ['service_type'], 'properties': {'cover_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'material': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pipe_od_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'njug_colour': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'service_type': {'enum': ['water', 'gas_lp', 'gas_mp', 'electricity_lv', 'electricity_hv', 'telecoms', 'fibre', 'street_lighting'], 'type': 'string', 'description': 'Utility service categories per NJUG Volume 1.'}, 'warning_tape': {'type': 'boolean', 'default': True}, 'bedding_class': {'enum': ['N', 'F', 'B', 'S', 'A', 'Z'], 'type': 'string', 'default': 'S', 'description': 'Geometric bedding class per HA 40/01 / BS EN 1610.\n\nListed in ascending order of structural support.'}, 'bedding_thickness_m': {'type': 'number', 'default': 0.1}, 'surround_above_crown_m': {'type': 'number', 'default': 0.15}, 'tape_height_above_crown_m': {'type': 'number', 'default': 0.3}}, 'description': 'One utility within the shared trench. The QS specifies the service\ntype; the assembly resolves NJUG defaults for cover, colour, OD and\nmaterial. Any of these can be overridden.'}}, 'project_ref': {'type': 'string', 'default': 'Combined Services Trench'}, 'support_type': {'enum': ['none', 'trench_box', 'sheet_pile', 'timber_board'], 'type': 'string', 'default': 'none', 'description': 'How the trench sides are supported during installation.'}, 'chainage_label': {'type': 'string', 'default': ''}, 'trench_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'bedding_context': {'enum': ['highway', 'building'], 'type': 'string', 'default': 'highway', 'description': 'Specification context for pipe bedding measurement.\n\nHIGHWAY  â\x80\x94 MMHW Series 500 / HA 40/01. Bedding clause references\n           SHW Cl. 503. Class N/F/B/A common; Class S less so.\nBUILDING â\x80\x94 NRM2 §33 / BS EN 1610. Class S is the typical default;\n           Class A and Z used for deep or structural locations.'}, 'trench_length_m': {'type': 'number', 'default': 50.0}, 'geotextile_grade': {'type': 'string', 'default': '200 g/m² non-woven'}, 'service_spacing_mm': {'type': 'integer', 'default': 100}, 'use_geotextile_separators': {'type': 'boolean', 'default': False}, 'working_space_below_bed_mm': {'type': 'integer', 'default': 100}, 'surface_reinstatement_thickness_m': {'type': 'number', 'default': 0.0}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_connection_to_existing
Compute Connection to Existing (drainage) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Enumerated extra-over connection of a new drainage carrier pipe into an existing asset: existing manhole / inspection chamber, existing sewer or drain (via saddle / wye / cut-in junction), or existing outfall / watercourse / surface system. Routes via CESMM4 I.7.1/2/3 (Class I §I.7 Pipework Ancillaries — Connections), NRM2 33.6.1/2/3, MMHW 500.5.1/2/3 (SHW Cl. 506 Connections to existing sewers, drains and service runs), SMM7 R12.4.1/2/3, with a bore-size digit suffix appended in all four. The connection_type attribute is the discriminator that routes to the right sub-code; the bore digit refines within. Six variant presets cover all three connection types × two characteristic bores. Unit: Nr. Opens the new `drainage_ancillaries` L2 leaf (reserved for ditch, hard-material extra-over, CCTV testing, etc. in future sessions). Sibling assembly: carrier_pipe_run — the S32 pair that delivers a complete tender drainage line. Example params: diameter_mm=225 mm (100–2400). Example call: {"params": {"diameter_mm": 225}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'method': {'enum': ['saddle connection', 'wye junction fitting', 'cut-in junction', 'core-drilled breakthrough', 'level outfall'], 'type': 'string', 'default': 'core-drilled breakthrough', 'description': 'How the physical connection is made â\x80\x94 informs the description\nbut does not change the BoQ code (the code is governed by the\nconnection_type discriminator + bore digit).'}, 'diameter_mm': {'type': 'integer', 'default': 225}, 'connection_type': {'enum': ['existing_manhole', 'existing_pipeline', 'existing_outfall'], 'type': 'string', 'default': 'existing_manhole', 'description': "The type of existing asset the new pipe run connects to.\n\nThe discriminator that routes through to the four standards'\nsub-codes:\n    existing_manhole   â\x86\x92 CESMM4 I.7.1 / NRM2 33.6.1 / MMHW 500.5.1\n                          / SMM7 R12.4.1\n    existing_pipeline  â\x86\x92 CESMM4 I.7.2 / NRM2 33.6.2 / MMHW 500.5.2\n                          / SMM7 R12.4.2\n    existing_outfall   â\x86\x92 CESMM4 I.7.3 / NRM2 33.6.3 / MMHW 500.5.3\n                          / SMM7 R12.4.3"}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}}, 'description': 'Parameters for a single connection-to-existing extra-over item.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_counterfort_wall
Compute Counterfort Retaining Wall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. In-situ reinforced concrete counterfort retaining wall. Discrete RC counterforts on the retained face enhance moment capacity, making the wall economic for 4-10m retained heights (above cantilever-economic range, below anchored-wall range). Includes base slab, thin curtain wall, counterforts at configurable centres, drainage, and backfill. Eight VARIANT_PRESETS exercise the 'one parameter form, eight variants, four standards' moat #1 claim. Routes via wall_type='counterfort' attribute discrimination: CESMM4 F.6.3, NRM2 11.3.3, MMHW 1700.4.2 (SHW Cl. 1704), SMM7 E10.3.2. Example params: stem_height=5 m (3–12), curtain_thickness=0.35 m (0.2–0.6), toe_length=0.6 m (0–3). Example call: {"params": {"stem_height": 5, "curtain_thickness": 0.35, "toe_length": 0.6}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier). Pass `freeboard` (clearance below the wall top, m) instead of the retained-height field to set the retained fill by clearance — the engine back-calculates it as stem − freeboard. Supplying both is rejected.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'toe_length': {'type': 'number', 'default': 0.6}, 'heel_length': {'type': 'number', 'default': 3.0}, 'stem_height': {'type': 'number', 'default': 5.0}, 'wall_length': {'type': 'number', 'default': 25.0}, 'backfill_class': {'type': 'string', 'default': 'Class 6N'}, 'base_thickness': {'type': 'number', 'default': 0.6}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'drain_diameter': {'type': 'number', 'default': 0.15}, 'counterfort_shape': {'enum': ['parallel', 'tapered'], 'type': 'string', 'default': 'parallel', 'description': 'Counterfort fin shape in elevation (side view).\n\nPARALLEL â\x80\x94 counterfort thickness constant from base to top of stem.\nTAPERED  â\x80\x94 counterfort tapers from full thickness at base to a\n           fraction (default 0.5) of full thickness at top. The\n           mass-efficient form; the structural moment at the top is\n           small, so the section can taper.'}, 'curtain_thickness': {'type': 'number', 'default': 0.35}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'shear_key_depth_m': {'type': 'number', 'default': 0.0}, 'shear_key_width_m': {'type': 'number', 'default': 0.0}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support strategy for below-ground assemblies.\n\nConsumed by retaining walls (cantilever, gravity, counterfort,\nanchored, bored pile), foundation assemblies, and drainage chambers\nthat involve a battered or vertical-supported pit. The enum value is\nsurfaced in the description text of the relevant excavation BoQ line\nand in some standards (CESMM4 E.4.4 et seq.) drives a separate code.'}, 'foundation_profile': {'enum': ['level', 'stepped'], 'type': 'string', 'default': 'level', 'description': 'Foundation formation profile â\x80\x94 level or stepped.\n\nConsumed by retaining walls and foundation assemblies built on\nsloping ground. STEPPED foundation reuses the v10 cross-cutting\nEXCAVATION_FOUNDATION stepping discrimination upgrade (originally\nadded for strip_foundation S8). The stepping branch in the standards\nhandlers detects ``is_stepped=True`` on EXCAVATION_FOUNDATION items\nand routes to the stepped-foundation codes.'}, 'include_geotextile': {'type': 'boolean', 'default': True}, 'counterfort_spacing': {'type': 'number', 'default': 4.0}, 'drain_surround_width': {'type': 'number', 'default': 0.4}, 'formation_below_base': {'type': 'number', 'default': 0.15}, 'counterfort_thickness': {'type': 'number', 'default': 0.4}, 'drain_surround_height': {'type': 'number', 'default': 0.4}, 'foundation_step_count': {'type': 'integer', 'default': 0}, 'counterfort_taper_ratio': {'type': 'number', 'default': 0.5}, 'reinforcement_kg_per_m3': {'type': 'number', 'default': 145.0}, 'excavation_working_space': {'type': 'number', 'default': 0.6}, 'foundation_step_height_m': {'type': 'number', 'default': 0.0}, 'backfill_height_above_base': {'type': 'number', 'default': 4.7}}, 'description': 'Parameter form for an in-situ RC counterfort retaining wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields â\x80\x94\nproduces all eight VARIANT_PRESETS plus arbitrary user-specified\ngeometries. Sensible defaults yield a 5 m high standard highway\ncounterfort wall with counterforts at 4.0 m centres.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'freeboard': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_ditch
Compute Open Ditch (drainage channel) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Linear primary measurement of an open earthwork drainage channel — trapezoidal cross-section, four lining variants (unlined / geotextile / granular / concrete). Routes via CESMM4 Class E.4 (excavation for cuttings), NRM2 Group 34.10 (site works: open drains and ditches), MMHW Series 500.4 (SHW Cl. 514 Earthwork ditches and drains), SMM7 R13.4 (Land Drainage — ditches). Eight variant presets cover all four lining types x two characteristic size scenarios each. Unit: M. Second member of the drainage_ancillaries L2 leaf (opened at S32 with connection_to_existing). 20th use of the classed-then-legacy attribute discrimination pattern via the lining_type discriminator. The four standards genuinely diverge on which work-section heading owns ditches (Class E vs Group 34 vs Series 500 vs R13) — the platform renders all four honestly from one source WorkItem. Example params: run_length_m=100 m (1–1000), top_width_mm=1700 mm (200–10000), bottom_width_mm=500 mm (100–5000). Example call: {"params": {"run_length_m": 100, "top_width_mm": 1700, "bottom_width_mm": 500}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'depth_mm': {'type': 'integer', 'default': 600}, 'lining_type': {'enum': ['unlined', 'geotextile', 'granular', 'concrete'], 'type': 'string', 'default': 'unlined', 'description': "The lining material of the ditch (or unlined).\n\nThe discriminator that routes through to the four standards'\nsub-codes:\n    unlined     -> CESMM4 E.4.x.1 / NRM2 34.10.1 / MMHW 500.4.1\n                    / SMM7 R13.4.1\n    geotextile  -> CESMM4 E.4.x.2 / NRM2 34.10.2 / MMHW 500.4.2\n                    / SMM7 R13.4.2\n    granular    -> CESMM4 E.4.x.3 / NRM2 34.10.3 / MMHW 500.4.3\n                    / SMM7 R13.4.3\n    concrete    -> CESMM4 E.4.x.4 / NRM2 34.10.4 / MMHW 500.4.4\n                    / SMM7 R13.4.4"}, 'run_length_m': {'type': 'number', 'default': 100.0}, 'top_width_mm': {'type': 'integer', 'default': 1700}, 'bottom_width_mm': {'type': 'integer', 'default': 500}, 'side_slope_h_per_v': {'type': 'number', 'default': 1.0}, 'lining_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}}, 'description': 'Parameters for a single open-ditch primary measurement.\n\nThe geometry is a trapezoidal cross-section run linearly along the\nditch alignment. side_slope_h_per_v is the side slope expressed as\nhorizontal-per-vertical (1.0 = 45 deg, 1.5 = ~34 deg, 0.5 = ~63 deg).'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_edge_drain
Compute Highway Pavement Edge Drain (HD 33/16) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Highway pavement edge drain per HD 33/16. Perforated carrier in a granular-filled trench with filter geotextile wrap; optional top separator under the pavement build-up. Highway-specific defaults: Type B filter aggregate, 200 g/m² geotextile, supported excavation. Headline standard mapping: MMHW 500.7 (filter drain with perforated pipe). Renders cleanly across all four standards with HA 40/01 references. Example params: pipe_internal_diameter_mm=150 mm (80–300), pipe_wall_thickness_mm=25 mm (5–50), drain_length=100 m (1–1000). Example call: {"params": {"pipe_internal_diameter_mm": 150, "pipe_wall_thickness_mm": 25, "drain_length": 100}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'pipe_type': {'enum': ['hdpe_twin_wall', 'clay_perforated'], 'type': 'string', 'default': 'hdpe_twin_wall', 'description': 'Perforated carrier â\x80\x94 same enum as French drain for consistency.'}, 'drain_length': {'type': 'number', 'default': 100.0}, 'invert_depth': {'type': 'number', 'default': 0.8}, 'has_filter_wrap': {'type': 'boolean', 'default': True}, 'cover_above_crown': {'type': 'number', 'default': 0.35}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'has_top_separator': {'type': 'boolean', 'default': True}, 'trench_width_extra': {'type': 'number', 'default': 0.3}, 'top_separator_grade': {'type': 'string', 'default': '200 g/m² non-woven separator (SHW Cl. 624)'}, 'filter_aggregate_type': {'enum': ['type_b_6f2', 'type_a_6f1'], 'type': 'string', 'default': 'type_b_6f2', 'description': 'Filter aggregate per SHW Series 500 / SHW Cl. 513.'}, 'pipe_wall_thickness_mm': {'type': 'integer', 'default': 25}, 'filter_geotextile_grade': {'type': 'string', 'default': '200 g/m² non-woven (SHW Cl. 513)'}, 'working_space_each_side': {'type': 'number', 'default': 0.1}, 'pipe_internal_diameter_mm': {'type': 'integer', 'default': 150}, 'excavation_support_required': {'type': 'boolean', 'default': True}, 'bedding_thickness_below_pipe': {'type': 'number', 'default': 0.15}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_embankment_cross_section
Compute Embankment Cross-Section BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Geometry-driven embankment per MMHW Series 600 — trapezoidal cross-section with crest width, asymmetric side slopes (h:v), and per-chainage height profile. Auto-generates the CrossSection series and delegates volume integration + mass-haul + standards routing to the end_area_earthworks engine, inheriting the four-standard rendering invariant. Auto-computes topsoil strip footprint from toe-to-toe envelope and supports an optional founding-strip excavation below ground level. Example params: crest_width_m=10 m (3–30), side_slope_h_per_v=2 (1–4), strip_envelope_offset_m=0.5 m (0–2). Example call: {"params": {"crest_width_m": 10, "side_slope_h_per_v": 2, "strip_envelope_offset_m": 0.5}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'method': {'enum': ['simpsons', 'trapezoidal', 'prismoidal'], 'type': 'string', 'default': 'simpsons', 'description': 'Integration method preference. The actual method applied may\ndiffer â\x80\x94 see VolumeResult.method_used.'}, 'bulking': {'anyOf': [{'type': 'object', 'properties': {'bulk_factor': {'type': 'number', 'default': 1.2}, 'shrink_factor': {'type': 'number', 'default': 0.9}}, 'description': 'SHW Series 600 Cl. 605 bulking/shrinkage factors.\n\nbulk_factor â\x80\x94 multiplier applied to the in-situ cut volume to get\n              the loose volume that needs haulage. Typical values:\n                1.10 for granular (Class 1x)\n                1.20 for cohesive (Class 2x)\n                1.30 for chalk (Class 3)\n                1.50 for rock (Class 8)\n              Default = 1.20 (conservative average for mixed cut).\nshrink_factor â\x80\x94 multiplier applied to the in-situ fill volume to\n              get the volume of cut required to produce it.\n              Typical values:\n                0.95 for granular\n                0.85 for cohesive\n                0.80 for stabilised\n              Default = 0.90 (conservative average for mixed fill).'}, {'type': 'null'}], 'default': None}, 'cut_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '2C', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'fill_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'reach_name': {'type': 'string', 'default': 'Embankment Ch 0+000 to Ch 0+200'}, 'capping_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '6F2', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'crest_width_m': {'type': 'number', 'default': 10.0}, 'height_profile': {'type': 'array', 'items': {'type': 'object', 'required': ['chainage', 'height_m'], 'properties': {'chainage': {'type': 'number'}, 'height_m': {'type': 'number'}}, 'description': 'A single point on the embankment height profile.\n\n`height_m` is the embankment height above the existing ground at this\nchainage. Zero means the embankment has zero height (the alignment\nhas reached existing ground level â\x80\x94 the embankment toe).'}}, 'sub_base_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'topsoil_source': {'type': 'string', 'default': 'site-won'}, 'topsoil_replace': {'type': 'boolean', 'default': True}, 'left_slope_h_per_v': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'side_slope_h_per_v': {'type': 'number', 'default': 2.0}, 'right_slope_h_per_v': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'method_statement_ref': {'type': 'string', 'default': ''}, 'selected_import_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'topsoil_strip_depth_m': {'type': 'number', 'default': 0.15}, 'strip_envelope_offset_m': {'type': 'number', 'default': 0.5}, 'unacceptable_proportion': {'type': 'number', 'default': 0.0}, 'topsoil_replace_depth_mm': {'type': 'integer', 'default': 150}, 'founding_depth_below_ground_m': {'type': 'number', 'default': 0.0}}, 'description': 'Inputs for a geometry-driven embankment cross-section assembly.\n\nThe assembly generates a `CrossSection` list from the profile +\ngeometry parameters, builds an `EndAreaEarthworksParameters` from\nthe result + the material/method parameters carried here, and\ndelegates compute to `EndAreaEarthworks.compute(...)`.\n\nPer Session 12 Q2 decision: left and right slopes are exposed\nseparately, both defaulting to `side_slope_h_per_v` so the common\nsymmetric case is a single-parameter call.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_end_area_earthworks
Compute End-Area Earthworks BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. Linear earthworks reach measured by the end-area method per MMHW Series 600 — Simpson's Rule with UK-QS even-ordinate trapezoidal-boundary fallback, with full SHW Series 600 Table 6/1 class tagging, mass-haul diagram (bulking + shrinkage per SHW Cl. 605), cut/fill balance, DISPOSAL vs FILL_GENERAL routing, capping and sub-base build-up, and topsoil strip + replacement. Renders identically across CESMM4 / NRM2 / MMHW / SMM7 with per-class line distinction. Example params: unacceptable_proportion=0 (0–1), topsoil_strip_depth_m=0.15 m (0–1), topsoil_replace_depth_mm=150 mm (0–500). Example call: {"params": {"unacceptable_proportion": 0, "topsoil_strip_depth_m": 0.15, "topsoil_replace_depth_mm": 150}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'method': {'enum': ['simpsons', 'trapezoidal', 'prismoidal'], 'type': 'string', 'default': 'simpsons', 'description': 'Integration method preference. The actual method applied may\ndiffer â\x80\x94 see VolumeResult.method_used.'}, 'bulking': {'anyOf': [{'type': 'object', 'properties': {'bulk_factor': {'type': 'number', 'default': 1.2}, 'shrink_factor': {'type': 'number', 'default': 0.9}}, 'description': 'SHW Series 600 Cl. 605 bulking/shrinkage factors.\n\nbulk_factor â\x80\x94 multiplier applied to the in-situ cut volume to get\n              the loose volume that needs haulage. Typical values:\n                1.10 for granular (Class 1x)\n                1.20 for cohesive (Class 2x)\n                1.30 for chalk (Class 3)\n                1.50 for rock (Class 8)\n              Default = 1.20 (conservative average for mixed cut).\nshrink_factor â\x80\x94 multiplier applied to the in-situ fill volume to\n              get the volume of cut required to produce it.\n              Typical values:\n                0.95 for granular\n                0.85 for cohesive\n                0.80 for stabilised\n              Default = 0.90 (conservative average for mixed fill).'}, {'type': 'null'}], 'default': None}, 'cut_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '2C', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'fill_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '2C', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'reach_name': {'type': 'string', 'default': 'Mainline cutting Ch 0+000 to Ch 0+100'}, 'capping_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '6F2', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'cross_sections': {'type': 'array', 'items': {'type': 'object', 'required': ['chainage'], 'properties': {'notes': {'type': 'string', 'default': ''}, 'cap_area': {'type': 'number', 'default': 0.0}, 'chainage': {'type': 'number'}, 'cut_area': {'type': 'number', 'default': 0.0}, 'fill_area': {'type': 'number', 'default': 0.0}, 'attributes': {'type': 'object', 'additionalProperties': True}, 'sub_base_area': {'type': 'number', 'default': 0.0}, 'topsoil_strip_area': {'type': 'number', 'default': 0.0}}, 'description': 'A single surveyed cross-section at a known chainage.\n\nAll areas are in m² (the planar cross-section area). The chainage\nis in m along the centreline.\n\nThe optional `notes` field carries any inspector commentary that\nshould appear in the audit trail (e.g. "soft spot, U2 material\nexpected below formation"). The optional `attributes` carries any\nfurther structured data that downstream consumers may want (per-class\ncut splits, designer\'s identifier, etc.).'}}, 'sub_base_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'topsoil_source': {'type': 'string', 'default': 'site-won'}, 'topsoil_replace': {'type': 'boolean', 'default': True}, 'method_statement_ref': {'type': 'string', 'default': ''}, 'selected_import_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'topsoil_strip_depth_m': {'type': 'number', 'default': 0.15}, 'unacceptable_proportion': {'type': 'number', 'default': 0.0}, 'topsoil_replace_depth_mm': {'type': 'integer', 'default': 150}, 'typical_excavation_depth_m': {'type': 'number', 'default': 2.0}}, 'description': 'Inputs for a linear earthworks reach measured by the end-area method.\n\nThe five area streams in each `CrossSection` are integrated independently\nalong the chainage axis. `topsoil_strip_area` is the planar (m²)\nstrip area at each section; the volume is computed as\n`trap-integrate(topsoil_strip_area) Ã\x97 topsoil_strip_depth_m / strip_area_mean`\nâ\x80\x94 i.e. we multiply the integrated planar strip area by the strip depth\nto get a volume in m³. Conventionally `topsoil_strip_area` per the\ndesigner is planar in m² per running metre (m² of plan area per metre\nof chainage = m of width), but to keep CrossSection symmetric with the\nother four area streams we treat it as a true area (m²) at that station\nand apply the depth multiplication here.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_flexible_pavement
Compute Flexible (Bituminous) Pavement Build-Up BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Flexible pavement build-up: optional capping (Class 6F) + Type 1 (Class 1A) granular sub-base + asphalt concrete base (AC) + binder course (AC/HRA) + optional tack coat + surface course (AC/HRA/SMA/TSCS). Routes the bound layers through PAVEMENT_BASE/BINDER/SURFACE handlers with pavement_family discrimination across all four standards. Sub-base and capping route through the v8 FILL_SUB_BASE/FILL_CAPPING SHW-class-aware handlers. Four traffic-category defaults (domestic/light/medium/heavy) per DMRB CD 226. All four standards render (CESMM4 R.1-R.4, NRM2 34.4-34.6, MMHW 700, SMM7 Q20+Q22). Example params: length=100 m (0.5–2000), width=6 m (0.5–30), sub_base_thickness_mm=150 mm (100–500). Example call: {"params": {"length": 100, "width": 6, "sub_base_thickness_mm": 150}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'width': {'type': 'number', 'default': 6.0}, 'length': {'type': 'number', 'default': 100.0}, 'base_material': {'anyOf': [{'enum': ['HRA_30/14F', 'SMA_10_surf', 'SMA_14_surf', 'AC_10_close_surf', 'AC_6_dense_surf', 'TSCS', 'surf_dress', 'AC_20_dense_bin', 'AC_32_dense_bin', 'HRA_60/20', 'AC_32_dense_base', 'AC_20_dense_base', 'HRA_60/32', 'CBGM_A_C8/10', 'CBGM_B_C12/15', 'PBP_concrete_block', 'PA_open_graded', 'PC_no_fines'], 'type': 'string', 'description': 'Canonical UK flexible pavement materials. The enum value is the\nBS EN 13108 designation; legacy SHW Cl. names are carried as the\n`legacy_designation` field in PavementInfo.'}, {'type': 'null'}], 'default': None}, 'capping_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '6F2', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'sub_base_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'tack_coat_type': {'type': 'string', 'default': 'cationic bitumen emulsion C40B4'}, 'binder_material': {'anyOf': [{'enum': ['HRA_30/14F', 'SMA_10_surf', 'SMA_14_surf', 'AC_10_close_surf', 'AC_6_dense_surf', 'TSCS', 'surf_dress', 'AC_20_dense_bin', 'AC_32_dense_bin', 'HRA_60/20', 'AC_32_dense_base', 'AC_20_dense_base', 'HRA_60/32', 'CBGM_A_C8/10', 'CBGM_B_C12/15', 'PBP_concrete_block', 'PA_open_graded', 'PC_no_fines'], 'type': 'string', 'description': 'Canonical UK flexible pavement materials. The enum value is the\nBS EN 13108 designation; legacy SHW Cl. names are carried as the\n`legacy_designation` field in PavementInfo.'}, {'type': 'null'}], 'default': None}, 'include_capping': {'type': 'boolean', 'default': False}, 'surface_material': {'anyOf': [{'enum': ['HRA_30/14F', 'SMA_10_surf', 'SMA_14_surf', 'AC_10_close_surf', 'AC_6_dense_surf', 'TSCS', 'surf_dress', 'AC_20_dense_bin', 'AC_32_dense_bin', 'HRA_60/20', 'AC_32_dense_base', 'AC_20_dense_base', 'HRA_60/32', 'CBGM_A_C8/10', 'CBGM_B_C12/15', 'PBP_concrete_block', 'PA_open_graded', 'PC_no_fines'], 'type': 'string', 'description': 'Canonical UK flexible pavement materials. The enum value is the\nBS EN 13108 designation; legacy SHW Cl. names are carried as the\n`legacy_designation` field in PavementInfo.'}, {'type': 'null'}], 'default': None}, 'traffic_category': {'enum': ['domestic', 'light', 'medium', 'heavy'], 'type': 'string', 'default': 'medium', 'description': 'Coarse traffic category for QS-level pavement build-up defaults.\n\nMaps to typical DMRB CD 226 design traffic ranges:\n  DOMESTIC â\x89\x88 < 0.3 msa     (driveways, courtyards)\n  LIGHT    â\x89\x88 0.3â\x80\x932.5 msa   (estate roads, footways w/ vehicle access)\n  MEDIUM   â\x89\x88 2.5â\x80\x9310 msa    (urban access, minor distributors)\n  HEAVY    â\x89\x88 10â\x80\x9330 msa     (urban distributors, light industrial)\n\nFor design traffic > 30 msa or > category 4 subgrade, a full pavement\ndesign per DMRB CD 226 is required and the parametric defaults here\nare not sufficient â\x80\x94 the user must specify thicknesses and materials\nexplicitly.'}, 'base_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'include_tack_coat': {'type': 'boolean', 'default': True}, 'binder_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'capping_thickness_mm': {'type': 'integer', 'default': 350}, 'surface_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'tack_coat_rate_kg_m2': {'type': 'number', 'default': 0.35}, 'sub_base_thickness_mm': {'type': 'integer', 'default': 150}, 'include_formation_prep': {'type': 'boolean', 'default': True}, 'excavation_extra_each_side_mm': {'type': 'integer', 'default': 0}}, 'description': 'Input parameters for a flexible pavement assembly.\n\nGeometric defaults match a 100m Ã\x97 6m urban access road (medium\ntraffic) per DMRB CD 226 starting build-up: 150mm Type 1 sub-base,\n150mm AC 32 base, 60mm AC 20 binder, 40mm SMA 10 surface.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_french_drain
Compute French (Filter) Drain BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Perforated land drain in a granular-filled trench with non-woven filter geotextile wrap. Composes the bedding primitive at Class S geometry (full granular envelope) with three additions: perforated carrier, filter geotextile wrap, and optional top seal. Renders cleanly across CESMM4 / NRM2 / MMHW (Series 500 filter drain) and SMM7. Example params: pipe_internal_diameter_mm=150 mm (80–600), pipe_wall_thickness_mm=25 mm (5–80), drain_length=50 m (1–500). Example call: {"params": {"pipe_internal_diameter_mm": 150, "pipe_wall_thickness_mm": 25, "drain_length": 50}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'pipe_type': {'enum': ['hdpe_twin_wall', 'clay_perforated', 'upvc_slotted'], 'type': 'string', 'default': 'hdpe_twin_wall', 'description': 'Perforated carrier pipe type.'}, 'drain_length': {'type': 'number', 'default': 50.0}, 'has_top_seal': {'type': 'boolean', 'default': False}, 'invert_depth': {'type': 'number', 'default': 1.0}, 'bedding_context': {'enum': ['highway', 'building'], 'type': 'string', 'default': 'highway', 'description': 'Specification context for pipe bedding measurement.\n\nHIGHWAY  â\x80\x94 MMHW Series 500 / HA 40/01. Bedding clause references\n           SHW Cl. 503. Class N/F/B/A common; Class S less so.\nBUILDING â\x80\x94 NRM2 §33 / BS EN 1610. Class S is the typical default;\n           Class A and Z used for deep or structural locations.'}, 'has_filter_wrap': {'type': 'boolean', 'default': True}, 'filter_aggregate': {'type': 'string', 'default': 'Type B filter (20-40mm)'}, 'cover_above_crown': {'type': 'number', 'default': 0.45}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'top_seal_thickness': {'type': 'number', 'default': 0.15}, 'trench_width_extra': {'type': 'number', 'default': 0.3}, 'filter_aggregate_class': {'type': 'string', 'default': 'Class 6N'}, 'pipe_wall_thickness_mm': {'type': 'integer', 'default': 25}, 'filter_geotextile_grade': {'type': 'string', 'default': '150 g/m² non-woven'}, 'working_space_each_side': {'type': 'number', 'default': 0.15}, 'pipe_internal_diameter_mm': {'type': 'integer', 'default': 150}, 'excavation_support_required': {'type': 'boolean', 'default': False}, 'bedding_thickness_below_pipe': {'type': 'number', 'default': 0.15}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_gabion_wall
Compute Gabion Retaining Wall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Modular gabion retaining wall built from welded or hexagonal-mesh wire baskets filled with hard angular graded stone (SHW Cl. 622). The first non-concrete retaining structure in the platform and the FIRST member of the earth_structures L1 leaf — opening Phase E. Spans four structural forms via the gabion_form discriminator: STACKED_RECTANGULAR (standard highway boundary), STACKED_STEPPED (architectural / heritage), BATTERED (tall walls with back batter), and FACING_MATTRESS (Reno-type mattresses for slope facing / scour protection). Eight variant presets exercise the parameter form covering all four gabion_form values: highway boundary, landscape, stepped front, heritage stepped, battered, river training, scour apron, and tall battered. Routes via three new WorkCategory entries (GABION_BASKET, GABION_FACING_MATTRESS, STONE_FILL) — the first session where the classed-then-legacy discriminator pattern is applied to fundamentally new measurement vocabulary rather than to existing concrete categories. Codes: CESMM4 E.8.1-3 (Class E — Earthworks), NRM2 5.20-22 (Group 5 — Excavating and filling), MMHW 600.12-14 (Series 600 — Earthworks; SHW Cl. 622/623), and SMM7 D41.1/D41.2/D20.20 (D41 — Crib walls / gabions / reinforced earth — the only standard with a NAMED home). 16th use of the discriminator pattern, first applied to new WorkCategories rather than legacy ones. Example params: wall_height=3 m (0.1–8), wall_length=25 m (5–200), basket_length_m=2 m (1–3). Example call: {"params": {"wall_height": 3, "wall_length": 25, "basket_length_m": 2}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'mesh_grade': {'enum': ['galvanised_hexagonal', 'pvc_coated_galfan', 'galvanised_welded'], 'type': 'string', 'default': 'galvanised_hexagonal', 'description': 'Wire mesh grade per BS EN 10223-3 (woven) or BS EN 10218-2\n(welded).\n\nGALVANISED_HEXAGONAL â\x80\x94 Heavily galvanised double-twisted hexagonal\n                       woven wire mesh. Standard for non-aggressive\n                       environments. Wire diameter 2.7mm typical.\n                       Lifespan 30-60 years depending on environment.\nPVC_COATED_GALFAN   â\x80\x94 Galfan (Zn-Al alloy) coated wire with\n                       polymer (PVC or PA6) outer coating. For\n                       aggressive environments (saline coastal,\n                       contaminated land, brackish water). Lifespan\n                       60-120 years. Standard for permanent\n                       highway works on coastal alignments.\nGALVANISED_WELDED   â\x80\x94 Welded rectangular wire mesh; stiffer\n                       baskets, sharper edges, less flexible.\n                       Sometimes preferred for architectural\n                       contexts where straight edges matter.'}, 'gabion_form': {'enum': ['stacked_rectangular', 'stacked_stepped', 'battered', 'facing_mattress'], 'type': 'string', 'default': 'stacked_rectangular', 'description': 'Structural form of the gabion retaining wall.\n\nSTACKED_RECTANGULAR â\x80\x94 Straight-faced stacked baskets; the most\n                      common practical form. Both front and back\n                      faces vertical. Each course is the same\n                      horizontal dimension. Typical for highway\n                      boundary walls 2-3m tall, garden/landscape\n                      walls, and small revetment walls.\n\nSTACKED_STEPPED     â\x80\x94 Front-face stepped. Each successive course\n                      (from bottom up) is offset back from the\n                      one below. Used for architectural / heritage\n                      contexts where the visible face needs visual\n                      interest, and for taller walls where stability\n                      is improved by stepping the cg backwards.\n                      Step offset typically 0.25-0.50m per course.\n\nBATTERED            â\x80\x94 Back-battered profile (front face vertical,\n                      back face battered inwards). Used for taller\n                      walls (4-6m+) where the increased base width\n                      per unit height improves overturning\n                      stability. Batter angle typically 6-15° from\n                      vertical (1:10 to 1:4 H:V).\n\nFACING_MATTRESS     â\x80\x94 Thin (typically 150-300mm) face-mounted gabion\n                      mattresses (Reno-type) applied to a backing\n                      fill or natural slope. Used for slope facing,\n                      river-bank revetment, scour protection\n                      aprons. Routes the primary measurement line\n                      to GABION_FACING_MATTRESS (m²) rather than\n                      GABION_BASKET (m³). Includes both inclined\n                      slope-face mattresses and horizontal scour\n                      aprons.'}, 'wall_height': {'type': 'number', 'default': 3.0}, 'wall_length': {'type': 'number', 'default': 25.0}, 'course_count': {'type': 'integer', 'default': 3}, 'backfill_class': {'type': 'string', 'default': 'Class 6N'}, 'basket_width_m': {'type': 'number', 'default': 1.0}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'basket_height_m': {'type': 'number', 'default': 1.0}, 'basket_length_m': {'type': 'number', 'default': 2.0}, 'retained_height': {'type': 'number', 'default': 2.7}, 'backfill_width_m': {'type': 'number', 'default': 0.5}, 'batter_angle_deg': {'type': 'number', 'default': 8.0}, 'geotextile_grade': {'type': 'string', 'default': '200 g/m²'}, 'include_blinding': {'type': 'boolean', 'default': True}, 'stone_fill_grade': {'enum': ['hard_angular_60_150', 'hard_angular_100_200', 'hard_angular_150_300', 'dressed_sandstone'], 'type': 'string', 'default': 'hard_angular_100_200', 'description': 'Stone fill specification per SHW Cl. 622 (gabions) or Cl. 623\n(rockfill).\n\nHARD_ANGULAR_60_150  â\x80\x94 60-150mm grade. Used for mattresses (thinner\n                       sections need smaller stone to fill properly)\n                       and small landscape walls.\nHARD_ANGULAR_100_200 â\x80\x94 100-200mm grade. The most common UK highway\n                       specification for standard 1m-cube gabion\n                       baskets.\nHARD_ANGULAR_150_300 â\x80\x94 150-300mm grade. Used for larger baskets\n                       (1.5m or 2m courses) and where larger stone\n                       is locally available economically.\nDRESSED_SANDSTONE    â\x80\x94 Hand-dressed natural stone (typically\n                       sandstone or local stone matching heritage\n                       context). Architectural premium product.'}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support strategy for below-ground assemblies.\n\nConsumed by retaining walls (cantilever, gravity, counterfort,\nanchored, bored pile), foundation assemblies, and drainage chambers\nthat involve a battered or vertical-supported pit. The enum value is\nsurfaced in the description text of the relevant excavation BoQ line\nand in some standards (CESMM4 E.4.4 et seq.) drives a separate code.'}, 'foundation_profile': {'enum': ['level', 'stepped'], 'type': 'string', 'default': 'level', 'description': 'Foundation formation profile â\x80\x94 level or stepped.\n\nConsumed by retaining walls and foundation assemblies built on\nsloping ground. STEPPED foundation reuses the v10 cross-cutting\nEXCAVATION_FOUNDATION stepping discrimination upgrade (originally\nadded for strip_foundation S8). The stepping branch in the standards\nhandlers detects ``is_stepped=True`` on EXCAVATION_FOUNDATION items\nand routes to the stepped-foundation codes.'}, 'include_geotextile': {'type': 'boolean', 'default': True}, 'blinding_thickness_m': {'type': 'number', 'default': 0.1}, 'mattress_thickness_mm': {'type': 'integer', 'default': 300}, 'mattress_apron_width_m': {'type': 'number', 'default': 4.0}, 'excavation_working_space': {'type': 'number', 'default': 0.3}, 'mattress_slope_angle_deg': {'type': 'number', 'default': 33.7}, 'step_offset_per_course_m': {'type': 'number', 'default': 0.3}}, 'description': 'Parameter form for a gabion retaining wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields and\nthe ``gabion_form`` discriminator â\x80\x94 produces all eight\nVARIANT_PRESETS plus arbitrary user-specified geometries across\nall four GabionForm options. Sensible defaults yield a 3m\nhighway-boundary STACKED_RECTANGULAR wall with 1m Ã\x97 1m Ã\x97 2m\ngalvanised hexagonal baskets filled with 100-200mm graded stone.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_gravity_wall
Compute Mass Concrete Gravity Retaining Wall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. In-situ mass concrete gravity retaining wall (typical C20/25 to C25/30) with trapezoidal cross-section, retaining soil by self-weight rather than structural action. Eight variant presets exercise the parameter form — landscape, highway boundary, trapezoidal, stepped-front, toe-projection, keyed-base, stepped-foundation, and battered-back-vertical-front. Routes via wall_type='gravity' attribute discrimination through CESMM4 F.5.3, NRM2 11.2.3, MMHW 1700.5 (SHW Cl. 1704 structural concrete), and SMM7 E10.2.3. Reinforcement default zero (gravity walls are nominally unreinforced); optional nominal face mesh available via nominal_face_reinforcement_kg_per_m3 parameter. Includes excavation (battered or supported, level or stepped foundation), blinding, drainage system (subsoil drain + granular surround + geotextile separator), Class 6N backfill, disposal, and formwork to vertical and battered faces. 13th use of the classed-then-legacy attribute discrimination pattern, and first use in the retaining wall family — opening the wall moat for subsequent counterfort (S30), anchored (S31) and bored pile (S32) variants. Example params: stem_height=3 m (1.5–6), stem_thickness_top=0.4 m (0.2–1), stem_thickness_bottom=1.3 m (0.4–2.5). Example call: {"params": {"stem_height": 3, "stem_thickness_top": 0.4, "stem_thickness_bottom": 1.3}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'toe_length': {'type': 'number', 'default': 0.0}, 'heel_length': {'type': 'number', 'default': 0.0}, 'stem_height': {'type': 'number', 'default': 3.0}, 'wall_length': {'type': 'number', 'default': 25.0}, 'back_profile': {'enum': ['vertical', 'battered'], 'type': 'string', 'default': 'battered', 'description': 'Back (retained) face profile.'}, 'front_profile': {'enum': ['vertical', 'battered', 'stepped'], 'type': 'string', 'default': 'vertical', 'description': 'Front (exposed) face profile.'}, 'backfill_class': {'type': 'string', 'default': 'Class 6N'}, 'base_thickness': {'type': 'number', 'default': 0.45}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C25/30'}, 'drain_diameter': {'type': 'number', 'default': 0.15}, 'front_step_count': {'type': 'integer', 'default': 0}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'shear_key_depth_m': {'type': 'number', 'default': 0.0}, 'shear_key_width_m': {'type': 'number', 'default': 0.0}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support strategy for below-ground assemblies.\n\nConsumed by retaining walls (cantilever, gravity, counterfort,\nanchored, bored pile), foundation assemblies, and drainage chambers\nthat involve a battered or vertical-supported pit. The enum value is\nsurfaced in the description text of the relevant excavation BoQ line\nand in some standards (CESMM4 E.4.4 et seq.) drives a separate code.'}, 'foundation_profile': {'enum': ['level', 'stepped'], 'type': 'string', 'default': 'level', 'description': 'Foundation formation profile â\x80\x94 level or stepped.\n\nConsumed by retaining walls and foundation assemblies built on\nsloping ground. STEPPED foundation reuses the v10 cross-cutting\nEXCAVATION_FOUNDATION stepping discrimination upgrade (originally\nadded for strip_foundation S8). The stepping branch in the standards\nhandlers detects ``is_stepped=True`` on EXCAVATION_FOUNDATION items\nand routes to the stepped-foundation codes.'}, 'include_geotextile': {'type': 'boolean', 'default': True}, 'stem_thickness_top': {'type': 'number', 'default': 0.4}, 'drain_surround_width': {'type': 'number', 'default': 0.4}, 'formation_below_base': {'type': 'number', 'default': 0.15}, 'drain_surround_height': {'type': 'number', 'default': 0.4}, 'foundation_step_count': {'type': 'integer', 'default': 0}, 'stem_thickness_bottom': {'type': 'number', 'default': 1.3}, 'excavation_working_space': {'type': 'number', 'default': 0.6}, 'foundation_step_height_m': {'type': 'number', 'default': 0.0}, 'backfill_height_above_base': {'type': 'number', 'default': 2.8}, 'nominal_face_reinforcement_kg_per_m3': {'type': 'number', 'default': 0.0}}, 'description': 'Parameter form for a mass concrete gravity retaining wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields â\x80\x94\nproduces all eight VARIANT_PRESETS plus arbitrary user-specified\ngeometries. Sensible defaults yield a 3 m high standard highway\nboundary wall.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_gully
Compute Highway / Curtilage Gully with Connection BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. Composite drainage inlet: precast gully pot with trap, ductile-iron grating, optional kerb outlet, and a short connection drain to the carrier sewer. The connection drain re-uses the bedding primitive. Four-standard rendering with component-aware sub-codes (CESMM4 K.6.x, NRM2 33.8.x, MMHW 500.7.x, SMM7 R12.3.6.x). Example params: pot_internal_diameter_mm=450 mm (300–750), pot_depth_m=0.9 m (0.45–2.5), pot_wall_thickness_mm=60 mm (50–100). Example call: {"params": {"pot_internal_diameter_mm": 450, "pot_depth_m": 0.9, "pot_wall_thickness_mm": 60}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'gully_type': {'enum': ['trapped_road_gully', 'untrapped_road_gully', 'yard_gully', 'kerb_inlet_gully'], 'type': 'string', 'default': 'trapped_road_gully', 'description': 'Style of gully.'}, 'pot_depth_m': {'type': 'number', 'default': 0.9}, 'grating_type': {'type': 'string', 'default': 'hinged ductile iron'}, 'bedding_grade': {'type': 'string', 'default': 'C20/25'}, 'grating_loading': {'enum': ['A15', 'B125', 'C250', 'D400', 'E600'], 'type': 'string', 'default': 'D400', 'description': 'BS EN 124 loading class.'}, 'has_kerb_outlet': {'type': 'boolean', 'default': False}, 'haunching_grade': {'type': 'string', 'default': 'C20/25'}, 'connection_length_m': {'type': 'number', 'default': 2.5}, 'connection_material': {'type': 'string', 'default': 'vitrified clay'}, 'formation_below_pot': {'type': 'number', 'default': 0.15}, 'pot_wall_thickness_mm': {'type': 'integer', 'default': 60}, 'connection_diameter_mm': {'type': 'integer', 'default': 150}, 'working_space_each_side': {'type': 'number', 'default': 0.3}, 'connection_bedding_class': {'enum': ['N', 'F', 'B', 'S', 'A', 'Z'], 'type': 'string', 'default': 'B', 'description': 'Geometric bedding class per HA 40/01 / BS EN 1610.\n\nListed in ascending order of structural support.'}, 'grating_clear_opening_mm': {'type': 'integer', 'default': 425}, 'pot_internal_diameter_mm': {'type': 'integer', 'default': 450}, 'connection_bedding_context': {'enum': ['highway', 'building'], 'type': 'string', 'default': 'highway', 'description': 'Specification context for pipe bedding measurement.\n\nHIGHWAY  â\x80\x94 MMHW Series 500 / HA 40/01. Bedding clause references\n           SHW Cl. 503. Class N/F/B/A common; Class S less so.\nBUILDING â\x80\x94 NRM2 §33 / BS EN 1610. Class S is the typical default;\n           Class A and Z used for deep or structural locations.'}, 'connection_invert_at_gully_m': {'type': 'number', 'default': 0.85}, 'connection_wall_thickness_mm': {'type': 'integer', 'default': 25}, 'connection_invert_at_carrier_m': {'type': 'number', 'default': 1.25}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_hard_material_in_trench
Compute Hard Material in Trench (extra-over) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Linear extra-over measurement of hard material encountered during drainage trench excavation. Discriminates between natural rock (CESMM4 E.6 / NRM2 5.6.1 / MMHW 500.6.1 / SMM7 R12.6.1) and artificial hard material — buried concrete / masonry / obstructions (CESMM4 E.7 / NRM2 5.6.2 / MMHW 500.6.2 / SMM7 R12.6.2). The platform's first dual-quantity WorkItem: carries both length_m and volume_m3 so CESMM4/NRM2 (m³) and MMHW/SMM7 (m) each render with their correct unit per the standards' rules. Eight variant presets cover both hard-material types × four depth bands. SMM7 R12 deems trench excavation (including hard material) included in the pipe-run rate — the SMM7 handler emits a zero-priceable annotated line for tender transparency (third use of the deemed-included extra-over annotation pattern). Closes the drainage_ancillaries L2 leaf at 4/4 members. Sibling assemblies: connection_to_existing (S32), ditch (S33), pipework_testing (S33). Example params: length_m=10 m (0.5–500), max_depth_m=1.5 m (0.3–10), trench_width_m=0.7 m (0.3–3). Example call: {"params": {"length_m": 10, "max_depth_m": 1.5, "trench_width_m": 0.7}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'length_m': {'type': 'number', 'default': 10.0}, 'max_depth_m': {'type': 'number', 'default': 1.5}, 'trench_width_m': {'type': 'number', 'default': 0.7}, 'pipe_diameter_mm': {'type': 'integer', 'default': 225}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'hard_material_type': {'enum': ['natural_rock', 'artificial_hard_material'], 'type': 'string', 'default': 'natural_rock', 'description': 'The type of hard material encountered.\n\nThe discriminator that routes through the four standards\' hard-\nmaterial codes:\n  natural_rock  -> CESMM4 E.6, NRM2 5.6.1, MMHW 500.6.1, SMM7 R12.6.1\n  artificial    -> CESMM4 E.7, NRM2 5.6.2, MMHW 500.6.2, SMM7 R12.6.2\n\nNatural rock = igneous/metamorphic/strongly cemented sedimentary\nrequiring blasting or heavy mechanical breaking; the UK industry\nthreshold is broadly "material with a UCS > 20 MPa or visibly\nintact rock requiring more than ripper-mounted tracked plant".\n\nArtificial hard material = man-made obstructions encountered\nduring excavation â\x80\x94 mass concrete, reinforced concrete bases,\nmasonry walls, buried foundations, kerbs and gully bases below\nfinished surface, redundant utility chambers.\n\nThese are the two materially-different operations that the four\nUK standards uniformly distinguish.'}, 'height_of_hard_material_m': {'type': 'number', 'default': 0.5}}, 'description': "Parameters for a single hard-material extra-over scenario.\n\nGeometry interpretation:\n  - `length_m` is the chainage extent of the hard-material zone\n    (i.e. how many metres of pipe-run encounter hard material).\n    This is the MMHW/SMM7 quantity directly.\n  - `trench_width_m` is the trench plan width at the level of the\n    hard material â\x80\x94 used (with height_of_hard_material_m and\n    length_m) to compute the volumetric quantity used by\n    CESMM4/NRM2.\n  - `height_of_hard_material_m` is the vertical extent of hard\n    material within the trench section â\x80\x94 the bottom of the\n    trench wraps the pipe envelope, so the hard-material height\n    is typically less than the full trench depth. This is the\n    QS's judgment, informed by site investigation.\n  - `max_depth_m` is the depth (from finished ground level) to\n    the bottom of the hard-material zone â\x80\x94 drives the depth\n    banding in all four handlers.\n  - `pipe_diameter_mm` is descriptive only â\x80\x94 propagated to the\n    WorkItem for cross-referencing the carrier pipe.\n\nVolume = length_m Ã\x97 trench_width_m Ã\x97 height_of_hard_material_m."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_headwall
Compute Reinforced Concrete Outfall Headwall BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. Composite RC outfall headwall: back wall pierced by the outfall pipe, splayed wing walls flaring downstream, apron slab, and rock-armour scour protection. In-situ or precast construction; BS 8666:2020 bar schedule composed across back wall, apron and wing walls. Four-standard rendering across CESMM4 / NRM2 / MMHW / SMM7. Example params: pipe_internal_diameter_mm=300 mm (100–1800), pipe_wall_thickness_mm=50 mm (15–120), invert_below_apron_m=0 m (0–1.5). Example call: {"params": {"pipe_internal_diameter_mm": 300, "pipe_wall_thickness_mm": 50, "invert_below_apron_m": 0}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'cover_mm': {'type': 'integer', 'default': 50}, 'quantity': {'type': 'integer', 'default': 1}, 'apron_length': {'type': 'number', 'default': 2.0}, 'headwall_type': {'enum': ['in_situ', 'precast'], 'type': 'string', 'default': 'in_situ', 'description': 'Construction method for the headwall.'}, 'apron_overhang': {'type': 'number', 'default': 0.3}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'apron_thickness': {'type': 'number', 'default': 0.25}, 'back_wall_height': {'type': 'number', 'default': 1.5}, 'back_wall_length': {'type': 'number', 'default': 2.5}, 'wing_wall_height': {'type': 'number', 'default': 1.5}, 'wing_wall_length': {'type': 'number', 'default': 1.5}, 'scour_apron_width': {'type': 'number', 'default': 4.0}, 'scour_apron_length': {'type': 'number', 'default': 2.0}, 'back_wall_thickness': {'type': 'number', 'default': 0.3}, 'scour_stone_size_mm': {'type': 'integer', 'default': 200}, 'wing_wall_splay_deg': {'type': 'number', 'default': 30.0}, 'wing_wall_thickness': {'type': 'number', 'default': 0.25}, 'has_scour_protection': {'type': 'boolean', 'default': True}, 'invert_below_apron_m': {'type': 'number', 'default': 0.0}, 'wing_wall_tip_height': {'type': 'number', 'default': 0.3}, 'apron_main_bar_dia_mm': {'type': 'integer', 'default': 12}, 'formation_below_apron': {'type': 'number', 'default': 0.075}, 'pipe_wall_thickness_mm': {'type': 'integer', 'default': 50}, 'apron_main_bar_pitch_mm': {'type': 'integer', 'default': 200}, 'scour_blanket_thickness': {'type': 'number', 'default': 0.3}, 'working_space_each_side': {'type': 'number', 'default': 0.45}, 'back_wall_main_bar_dia_mm': {'type': 'integer', 'default': 16}, 'pipe_internal_diameter_mm': {'type': 'integer', 'default': 300}, 'wing_wall_main_bar_dia_mm': {'type': 'integer', 'default': 12}, 'back_wall_main_bar_pitch_mm': {'type': 'integer', 'default': 200}, 'wing_wall_main_bar_pitch_mm': {'type': 'integer', 'default': 200}, 'apron_distribution_bar_dia_mm': {'type': 'integer', 'default': 12}, 'apron_distribution_bar_pitch_mm': {'type': 'integer', 'default': 200}, 'back_wall_distribution_bar_dia_mm': {'type': 'integer', 'default': 12}, 'back_wall_distribution_bar_pitch_mm': {'type': 'integer', 'default': 200}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_headwall_attenuation_outlet
Compute Headwall — Attenuation Outlet BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_headwall. Controlled attenuation outlet: precast concrete headwall plus outlet-control ironmongery (orifice plate, optional flap valve, weir overflow, penstock) and downstream scour protection. 2nd use of the bundle-with-shared-envelope pattern (template: combined_services_trench S14). Composes headwall_precast for the structural unit and bedding; emits ironmongery items as CONTRACTOR_INSTALL_PC_SUPPLY by default (3rd commercially significant PC-supply emitter after utility_chamber and utility_kiosk_base). Scour protection extended to three variants: rock armour, gabion mattress, concrete apron. Example params: orifice_diameter_mm=150 mm (20–600), orifice_target_discharge_ls=5 l/s (0.1–200), flap_valve_size_mm=0 mm (0–1200). Example call: {"params": {"orifice_diameter_mm": 150, "orifice_target_discharge_ls": 5, "flap_valve_size_mm": 0}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['PHW_300', 'PHW_375', 'PHW_450', 'PHW_600', 'PHW_750', 'PHW_900', 'PHW_1050', 'PHW_1200', 'PHW_1500'], 'type': 'string', 'default': 'PHW_600', 'description': 'Standard UK precast headwall sizes, by outfall pipe internal diameter.\n\nThese bracket the offerings from Marshalls CPM, FP McCann, and\nStanton Bonna. The unit size determines the CESMM4 Class H sub-code\n(H.7.1 â\x89¤ 1200mm, H.7.2 > 1200mm), the typical mass for handling\nplant requirements, and the bedding footprint.'}, 'quantity': {'type': 'integer', 'default': 1}, 'project_ref': {'type': 'string', 'default': 'Attenuation Outlet'}, 'bedding_type': {'enum': ['concrete_bed', 'granular_bed'], 'type': 'string', 'default': 'concrete_bed', 'description': 'Bedding type beneath a precast headwall.\n\nCONCRETE_BED uses mass concrete blinding (typically C8/10 or C16/20)\nunder the unit, providing a level rigid surface and tying the unit\nto the formation. Common for soft cohesive ground and where flow\nerosion under the unit is a risk.\n\nGRANULAR_BED uses imported Class 6N or 6P granular material per\nSHW Cl. 803, compacted and levelled. Common for non-erodible\ngranular soils where a concrete bed is unnecessary.'}, 'has_penstock': {'type': 'boolean', 'default': False}, 'supply_route': {'anyOf': [{'enum': ['contractor_full', 'contractor_install_pc_supply', 'provisional_sum', 'utility_provider_supply', 'employer_direct'], 'type': 'string'}, {'type': 'null'}], 'default': None}, 'chainage_label': {'type': 'string', 'default': ''}, 'has_flap_valve': {'type': 'boolean', 'default': False}, 'penstock_size_mm': {'type': 'integer', 'default': 0}, 'gabion_mesh_grade': {'type': 'string', 'default': 'Type A galfan PVC-coated mesh to BS EN 10223-3'}, 'has_weir_overflow': {'type': 'boolean', 'default': False}, 'flap_valve_size_mm': {'type': 'integer', 'default': 0}, 'orifice_diameter_mm': {'type': 'integer', 'default': 150}, 'scour_apron_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'scour_stone_size_mm': {'type': 'integer', 'default': 200}, 'concrete_apron_grade': {'type': 'string', 'default': 'C32/40'}, 'orifice_manufacturer': {'type': 'string', 'default': 'generic'}, 'scour_apron_length_m': {'type': 'number', 'default': 2.0}, 'scour_protection_type': {'enum': ['rock_armour', 'gabion_mattress', 'concrete_apron', 'none'], 'type': 'string', 'default': 'rock_armour', 'description': 'Scour protection variant downstream of the headwall outfall.\n\nROCK_ARMOUR is the existing headwall_precast variant (granular fill,\nrock armour blanket). GABION_MATTRESS and CONCRETE_APRON are the\nnew S21 extensions for higher-energy or longer-lasting requirements.\nNONE skips scour protection entirely (rare; only suitable for\ndischarge into a robust receiving channel like a piled concrete\nweir basin).'}, 'concrete_bedding_grade': {'type': 'string', 'default': 'C8/10'}, 'scour_blanket_thickness_m': {'type': 'number', 'default': 0.3}, 'orifice_target_discharge_ls': {'type': 'number', 'default': 5.0}, 'weir_overflow_crest_height_m': {'type': 'number', 'default': 0.5}, 'weir_overflow_crest_length_m': {'type': 'number', 'default': 1.0}}, 'description': 'Parameter form for an attenuation outlet headwall.\n\nComposes a precast headwall (size, bedding) with one always-present\norifice plate and up to three optional outlet-control ironmongery\nitems (flap valve, weir overflow, penstock), plus a scour\nprotection variant.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_headwall_precast
Compute Precast Concrete Outfall Headwall BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_headwall. Precast concrete outfall headwall, supplied as a whole unit from a UK manufacturer (Marshalls CPM, FP McCann, Stanton Bonna or equivalent). Catalogue-driven sizing from PHW_300 (300mm pipe ID) to PHW_1500 (1500mm). Includes excavation, concrete or granular bedding, and optional rock-armour scour protection. Routes precast unit through CESMM4 Class H, NRM2 33.9.1, MMHW 500.8.1 (SHW Cl. 511), and SMM7 R12.3.7 via headwall_type=precast attribute discrimination. Example params: bedding_thickness_mm=150 mm (75–300), bedding_overhang_m=0.15 m (0.075–0.3), working_space_each_side_m=0.45 m (0.3–1.5). Example call: {"params": {"bedding_thickness_mm": 150, "bedding_overhang_m": 0.15, "working_space_each_side_m": 0.45}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['PHW_300', 'PHW_375', 'PHW_450', 'PHW_600', 'PHW_750', 'PHW_900', 'PHW_1050', 'PHW_1200', 'PHW_1500'], 'type': 'string', 'default': 'PHW_600', 'description': 'Standard UK precast headwall sizes, by outfall pipe internal diameter.\n\nThese bracket the offerings from Marshalls CPM, FP McCann, and\nStanton Bonna. The unit size determines the CESMM4 Class H sub-code\n(H.7.1 â\x89¤ 1200mm, H.7.2 > 1200mm), the typical mass for handling\nplant requirements, and the bedding footprint.'}, 'quantity': {'type': 'integer', 'default': 1}, 'unit_mass_t': {'type': 'number', 'default': None}, 'bedding_type': {'enum': ['concrete_bed', 'granular_bed'], 'type': 'string', 'default': 'concrete_bed', 'description': 'Bedding type beneath a precast headwall.\n\nCONCRETE_BED uses mass concrete blinding (typically C8/10 or C16/20)\nunder the unit, providing a level rigid surface and tying the unit\nto the formation. Common for soft cohesive ground and where flow\nerosion under the unit is a risk.\n\nGRANULAR_BED uses imported Class 6N or 6P granular material per\nSHW Cl. 803, compacted and levelled. Common for non-erodible\ngranular soils where a concrete bed is unnecessary.'}, 'unit_depth_m': {'type': 'number', 'default': None}, 'unit_width_m': {'type': 'number', 'default': None}, 'apron_width_m': {'type': 'number', 'default': None}, 'unit_height_m': {'type': 'number', 'default': None}, 'apron_length_m': {'type': 'number', 'default': None}, 'bedding_overhang_m': {'type': 'number', 'default': 0.15}, 'scour_apron_width_m': {'type': 'number', 'default': None}, 'scour_stone_size_mm': {'type': 'integer', 'default': 200}, 'bedding_thickness_mm': {'type': 'integer', 'default': 150}, 'has_scour_protection': {'type': 'boolean', 'default': True}, 'scour_apron_length_m': {'type': 'number', 'default': 2.0}, 'concrete_bedding_grade': {'type': 'string', 'default': 'C8/10'}, 'granular_bedding_class': {'type': 'string', 'default': '6N'}, 'formation_below_bedding_m': {'type': 'number', 'default': 0.075}, 'pipe_internal_diameter_mm': {'type': 'integer', 'default': None}, 'scour_blanket_thickness_m': {'type': 'number', 'default': 0.3}, 'working_space_each_side_m': {'type': 'number', 'default': 0.45}}, 'description': "Parameter form for a precast headwall.\n\nCatalogue-driven: pick a `size` and the unit's nominal physical\ndimensions are read from `_CATALOGUE`. Override individual physical\nfields if a specific manufacturer differs."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_highway_drainage_channel
Compute Highway Drainage Channel BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Highway / surface-water drainage channel installation per BS EN 1433 + SHW Cl. 511-514 + HD 33/16. Discriminates between five UK channel product classifications via the channel_type enum (linear_polymer_concrete — ACO-pattern; linear_concrete — Charcon-pattern precast; slot_drain — narrow-slot recessed; combined_kerb_drainage — Beany/Safeticurb integrated unit per SHW Cl. 514; steel_grated_channel — heavy-duty stainless/galvanised). Plus parallel discriminators on two further WorkCategory entries: outfall_type on CHANNEL_OUTFALL (end / branch / side), silt_box_type on CHANNEL_SILT_BOX (standard / heavy-duty / deep-sump). The MMHW Series 500 _highway_drainage_channel handler is the platform's FOURTH 2D-banded handler — code `500.8.{t}.{d}` bands by channel_type (5 bands) AND depth_class (4 bands). 5×4 = 20-cell grid. SMM7 routes to R12 (Drainage below ground) — SECOND highway L1 family outside Section Q after S39 lighting → V41. Example params: channel_depth_mm=100 mm (50–1500), channel_length_m=50 m (1–500), outfall_count=1 nr (0–20). Example call: {"params": {"channel_depth_mm": 100, "channel_length_m": 50, "outfall_count": 1}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'depth_class': {'enum': ['shallow', 'medium', 'deep', 'extra_deep'], 'type': 'string', 'default': 'shallow', 'description': 'Channel depth classification per typical UK pricing tiers.\n\nDepth drives unit weight, bedding volume, trench-support\nrequirement, and ground-water-handling cost independently of the\nchannel type. UK practice prices channel depth in four\ncommercial bands:\n\nSHALLOW    â\x80\x94 â\x89¤150mm. Footway / pedestrian area / car park.\nMEDIUM     â\x80\x94 151-300mm. Standard carriageway edge.\nDEEP       â\x80\x94 301-500mm. High-flow carriageway / motorway edge.\nEXTRA_DEEP â\x80\x94 >500mm. Junction sump / heavy-flow location.'}, 'channel_type': {'enum': ['linear_polymer_concrete', 'linear_concrete', 'slot_drain', 'combined_kerb_drainage', 'steel_grated_channel'], 'type': 'string', 'default': 'linear_polymer_concrete', 'description': 'Channel product classification per BS EN 1433 + UK industry practice.\n\nLINEAR_POLYMER_CONCRETE â\x80\x94 Monolithic moulded fibre-reinforced polymer-\n    concrete unit (ACO-pattern, the dominant UK case). Tight-tolerance\n    manufactured joint, ductile-iron grating per BS EN 124.\nLINEAR_CONCRETE         â\x80\x94 Precast reinforced concrete unit (Charcon-\n    pattern). Rebated joint, ductile-iron grating per BS EN 124.\nSLOT_DRAIN              â\x80\x94 Recessed narrow-slot channel section\n    (stainless-steel or polymer-concrete). Used where visual\n    impact must be minimised (conservation areas, pedestrianised\n    zones, courtyard schemes).\nCOMBINED_KERB_DRAINAGE  â\x80\x94 Integrated kerb+drain monolithic unit per\n    SHW Cl. 514 (Beany / Safeticurb-pattern). The kerb face and\n    the channel are a single precast item. Used where kerb-line\n    installation and surface drainage are integrated.\nSTEEL_GRATED_CHANNEL    â\x80\x94 Heavy-duty stainless-steel or galvanised-\n    steel grated channel for industrial-loading service\n    (Class E600/F900 BS EN 124). Used at airports, port hardstandings,\n    and industrial yards.'}, 'outfall_type': {'anyOf': [{'enum': ['end_outfall', 'branch_outfall', 'side_outfall'], 'type': 'string', 'description': 'Outfall fitting classification per UK industry practice.\n\nEND_OUTFALL    â\x80\x94 Termination of channel run with downstream\n    connection to chamber or carrier pipe.\nBRANCH_OUTFALL â\x80\x94 Mid-run discharge connection (T-fitting to\n    the channel base).\nSIDE_OUTFALL   â\x80\x94 Lateral discharge to an adjacent chamber\n    (S-fitting through the channel side wall).'}, {'type': 'null'}], 'default': 'end_outfall'}, 'outfall_count': {'type': 'integer', 'default': 1}, 'silt_box_type': {'anyOf': [{'enum': ['standard', 'heavy_duty', 'deep_sump'], 'type': 'string', 'description': 'Silt box classification per BS EN 124 load class + service.\n\nSTANDARD   â\x80\x94 Class C250 BS EN 124. Footway / car park service.\nHEAVY_DUTY â\x80\x94 Class D400 BS EN 124. Standard carriageway service.\nDEEP_SUMP  â\x80\x94 Extended sediment trap depth. For high-silt-load\n    locations (forest edge, construction-site adjacent, etc.).'}, {'type': 'null'}], 'default': None}, 'silt_box_count': {'type': 'integer', 'default': 0}, 'channel_depth_mm': {'type': 'integer', 'default': 100}, 'channel_length_m': {'type': 'number', 'default': 50.0}, 'branch_outfall_count': {'type': 'integer', 'default': 0}}, 'description': 'Inputs for the highway_drainage_channel assembly.\n\nRequired:\n  channel_type           â\x80\x94 ChannelType enum (or string equivalent)\n  depth_class            â\x80\x94 DepthClass enum (or string)\n  channel_depth_mm       â\x80\x94 actual channel depth in mm\n  channel_length_m       â\x80\x94 channel run length in metres\n\nOptional:\n  outfall_type           â\x80\x94 OutfallType enum (or string); defaults to\n                           END_OUTFALL when outfall_count > 0\n  outfall_count          â\x80\x94 number of primary outfalls (default 1)\n  branch_outfall_count   â\x80\x94 number of additional branch outfalls\n                           (default 0)\n  silt_box_type          â\x80\x94 SiltBoxType enum (or string); required\n                           when silt_box_count > 0\n  silt_box_count         â\x80\x94 number of silt boxes (default 0)'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_kerb_run
Compute Precast Concrete Kerb Run BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Linear precast concrete kerb run on concrete bed and haunch over Type 1 (Class 1A) granular sub-base. Emits excavation, sub-base (v8 SHW-class-aware), concrete bed, kerb units to BS EN 1340 / SHW Cl. 1101, concrete haunch to back face, optional channel block, and disposal. Supports HB2/HB1/SP/BN/EF/ER kerb profiles and CS1/CS2/dish channels. All four standards render with type designators (CESMM4 R.7, NRM2 34.10, MMHW 1100, SMM7 Q10). Example params: kerb_length=25 m (1–1000), bed_thickness_mm=150 mm (75–300), bed_extra_each_side_mm=100 mm (0–300). Example call: {"params": {"kerb_length": 25, "bed_thickness_mm": 150, "bed_extra_each_side_mm": 100}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'kerb_type': {'enum': ['HB2', 'HB1', 'SP', 'BN', 'EF', 'ER'], 'type': 'string', 'default': 'HB2', 'description': 'Precast concrete kerb profiles per BS EN 1340 (and the SHW Cl. 1101\ntype designators used in UK highway practice).\n\nDimensions are width Ã\x97 height in mm (cross-section). Upstand is the\nportion above road level (typically half the height for HB types).'}, 'kerb_length': {'type': 'number', 'default': 25.0}, 'channel_type': {'enum': ['none', 'CS1', 'CS2', 'dish'], 'type': 'string', 'default': 'none', 'description': 'Optional channel block on the carriageway side of the kerb.'}, 'sub_base_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'bed_thickness_mm': {'type': 'integer', 'default': 150}, 'bed_concrete_grade': {'type': 'string', 'default': 'C20/25'}, 'haunch_height_ratio': {'type': 'number', 'default': 0.5}, 'haunch_concrete_grade': {'type': 'string', 'default': 'C20/25'}, 'sub_base_thickness_mm': {'type': 'integer', 'default': 150}, 'bed_extra_each_side_mm': {'type': 'integer', 'default': 100}, 'haunch_width_at_base_mm': {'type': 'integer', 'default': 150}, 'excavation_extra_each_side_mm': {'type': 'integer', 'default': 50}}, 'description': 'Input parameters for a kerb run assembly.\n\nGeometric defaults match a standard UK HB2 road kerb on 150mm\nconcrete bed over 150mm Type 1 sub-base, with triangular haunch\nrising to half the kerb height on the back face.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_lighting_column
Compute Lighting Column BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Highway / street lighting column installation per BS EN 40 + BS 5489-1:2020 + TR 22. Discriminates between four UK column material classifications via the column_type enum (steel_galvanised, aluminium, composite_grp, decorative_cast_iron). Plus parallel discriminators on three further WorkCategory entries: foundation_type on COLUMN_FOUNDATION, luminaire_type on LUMINAIRE, bracket_type on COLUMN_BRACKET. The MMHW Series 1300 _lighting_column handler is the platform's THIRD 2D-banded handler — code `1300.4.1.{h}.{c}` bands by column_height_class (6 bands per TR 22) AND column_loading_class (4 bands per BS EN 40-3). 6×4 = 24-cell grid (the LARGEST banded grid in the platform). Example params: mounting_height_m=6 m (4–16), luminaire_wattage_W=60 W (10–1000), bracket_count=0 Nr (0–4). Example call: {"params": {"mounting_height_m": 6, "luminaire_wattage_W": 60, "bracket_count": 0}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'column_type': {'enum': ['steel_galvanised', 'aluminium', 'composite_grp', 'decorative_cast_iron'], 'type': 'string', 'default': 'steel_galvanised', 'description': 'Column material classification per BS EN 40-5/6/7.\n\nSTEEL_GALVANISED â\x80\x94 Carbon-steel column shaft, hot-dip galvanised\n    after fabrication. The dominant UK case (~85% of new street\n    lighting installations). BS EN 40-5.\nALUMINIUM        â\x80\x94 Extruded aluminium column. Used for ped-cycle\n    track lighting (lighter handling) and seafront/marine zones\n    (corrosion resistance). BS EN 40-6.\nCOMPOSITE_GRP    â\x80\x94 Glass-reinforced polymer column. Used in zones\n    with high crash energy (frangible) or where electrical\n    isolation is required. BS EN 40-7.\nDECORATIVE_CAST_IRON â\x80\x94 Cast-iron decorative column for conservation\n    areas and heritage zones. Bespoke finish; BS EN 40-5 with\n    traditional Victorian/Edwardian design.'}, 'bracket_type': {'anyOf': [{'enum': ['single_side_entry', 'double_side_entry', 'post_top_adaptor', 'decorative_swan_neck'], 'type': 'string', 'description': 'Column bracket classification per BS EN 40-2.\n\nSINGLE_SIDE_ENTRY     â\x80\x94 Single side-entry outreach bracket. The\n    dominant case for carriageway lighting where the luminaire\n    is offset over the kerb.\nDOUBLE_SIDE_ENTRY     â\x80\x94 Double side-entry bracket carrying two\n    luminaires (one each side). Used at junctions / where dual\n    carriageways meet at a single column.\nPOST_TOP_ADAPTOR      â\x80\x94 Post-top adaptor (luminaire mounted on\n    column tip, no outreach). Used for residential and ped-cycle\n    lighting where the luminaire is directly above the column.\nDECORATIVE_SWAN_NECK   â\x80\x94 Decorative swan-neck bracket for heritage\n    / conservation zones.'}, {'type': 'null'}], 'default': None}, 'bracket_count': {'type': 'integer', 'default': 0}, 'luminaire_type': {'enum': ['led_M_class', 'led_decorative', 'son_legacy', 'sox_legacy', 'floodlight'], 'type': 'string', 'default': 'led_M_class', 'description': 'Luminaire classification per BS EN 13201 / ILP TR23.\n\nLED_M_CLASS    â\x80\x94 LED luminaire suitable for M-class carriageway\n    lighting per BS EN 13201. The dominant new-install case\n    post-2015.\nLED_DECORATIVE â\x80\x94 LED decorative lantern for conservation-area /\n    heritage zones (Victorian/Edwardian styling).\nSON_LEGACY     â\x80\x94 High-pressure sodium SON lamp luminaire. Legacy\n    only â\x80\x94 included for like-for-like replacement schemes.\nSOX_LEGACY     â\x80\x94 Low-pressure sodium SOX lamp luminaire. Legacy\n    only â\x80\x94 banned for new installs since the 2010s; included for\n    rare replacement.\nFLOODLIGHT     â\x80\x94 Asymmetric-beam floodlight luminaire (junction\n    floodlighting, pedestrian-area floodlighting).'}, 'foundation_type': {'enum': ['precast_socket', 'insitu_reinforced', 'root_planted'], 'type': 'string', 'default': 'precast_socket', 'description': "Column foundation classification per SHW Cl. 1304 / TR 22.\n\nPRECAST_SOCKET     â\x80\x94 Precast concrete plant base socket. Typical\n    for columns â\x89¤8m on residential/urban streets. Quick install\n    (drop-in), reusable across the contractor's stock.\nINSITU_REINFORCED  â\x80\x94 In-situ reinforced concrete foundation with\n    holding-down bolts. Typical for columns â\x89¥10m where wind/dynamic\n    loads exceed the precast socket's anchorage capacity.\nROOT_PLANTED       â\x80\x94 Direct-buried planted column (no separate\n    foundation block); the steel column extends below ground to\n    TR 22 minimum embedment depth."}, 'bracket_reach_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'mounting_height_m': {'type': 'number', 'default': 6.0}, 'column_height_class': {'enum': ['h_5m', 'h_6m', 'h_8m', 'h_10m', 'h_12m', 'h_15m'], 'type': 'string', 'default': 'h_6m', 'description': 'Column mounting height class per TR 22 standard heights.\n\nThe six values correspond to UK standard heights for street\nlighting. Each height class drives steel section thickness, base\nplate size, and foundation depth per BS EN 40-2.\n\nH_5M  â\x80\x94 5m  (residential / footway side)\nH_6M  â\x80\x94 6m  (urban residential / pedestrian areas)\nH_8M  â\x80\x94 8m  (urban distributor / town centre)\nH_10M â\x80\x94 10m (urban traffic route / arterial)\nH_12M â\x80\x94 12m (motorway slip road / interchange approaches)\nH_15M â\x80\x94 15m (motorway main line / high-mast areas)'}, 'luminaire_wattage_W': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': 60}, 'column_loading_class': {'enum': ['A', 'B', 'C', 'D'], 'type': 'string', 'default': 'B', 'description': "Column wind-loading class per BS EN 40-3.\n\nThe class defines the permitted luminaire+bracket projected wind\narea for a given column section. Class jumps drive the column's\nsteel weight independently of mounting height.\n\nA â\x80\x94 small luminaire, projected area <0.025 m²\nB â\x80\x94 medium luminaire, 0.025-0.045 m²\nC â\x80\x94 large luminaire / single bracket, 0.045-0.075 m²\nD â\x80\x94 high-mast / multi-luminaire, >0.075 m²"}}, 'description': 'Inputs for the lighting_column assembly.\n\nDefaults anchored to URBAN_6M_LED â\x80\x94 UK urban distributor: 6 m steel\ngalvanised column on precast socket, BS EN 40-3 Class B, LED M-class\nluminaire (~60 W typical). Required-field defaults added per G.6.7.24\nprecedent â\x80\x94 non-breaking API enrichment opens the slug to schema-\ndriven workspace defaults.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_manhole
Compute Precast Concrete Circular Manhole BoQ
Free tier. Renders the MMHW standard only — CESMM4, NRM2 and SMM7 require a paid tier. Anonymous callers welcome. Composite assembly: precast concrete circular manhole with base slab, chamber rings (optional reducing slab + shaft), cover slab, frame & cover (BS EN 124 loading classes), step irons or ladder, in-situ benching with pre-formed channel, granular surround, geotextile separator, and excavation. Supports both open-battered and sheet-piled excavations. Example params: internal_diameter=1.5 m (1–3), wall_thickness=0.15 m (0.1–0.25), invert_depth=3.5 m (0.5–12). Example call: {"params": {"internal_diameter": 1.5, "wall_thickness": 0.15, "invert_depth": 3.5}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'base_grade': {'type': 'string', 'default': 'C32/40'}, 'access_type': {'enum': ['step_irons', 'ladder', 'none'], 'type': 'string', 'default': 'step_irons'}, 'invert_depth': {'type': 'number', 'default': 3.5}, 'cover_loading': {'enum': ['A15', 'B125', 'C250', 'D400', 'E600', 'F900'], 'type': 'string', 'default': 'D400'}, 'base_thickness': {'type': 'number', 'default': 0.2}, 'benching_grade': {'type': 'string', 'default': 'C32/40'}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'wall_thickness': {'type': 'number', 'default': 0.15}, 'base_projection': {'type': 'number', 'default': 0.15}, 'cover_slab_grade': {'type': 'string', 'default': 'C32/40'}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'has_reducing_slab': {'type': 'boolean', 'default': True}, 'internal_diameter': {'type': 'number', 'default': 1.5}, 'step_iron_spacing': {'type': 'number', 'default': 0.3}, 'surround_material': {'type': 'string', 'default': '20mm single-size aggregate'}, 'blinding_thickness': {'type': 'number', 'default': 0.075}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'surround_thickness': {'type': 'number', 'default': 0.15}, 'cover_clear_opening': {'type': 'number', 'default': 0.6}, 'cover_slab_thickness': {'type': 'number', 'default': 0.2}, 'cover_to_top_of_slab': {'type': 'number', 'default': 0.075}, 'geotextile_full_wrap': {'type': 'boolean', 'default': True}, 'seating_rings_height': {'type': 'number', 'default': 0.15}, 'main_channel_diameter': {'type': 'number', 'default': 0.3}, 'reducing_slab_at_depth': {'type': 'number', 'default': 1.2}, 'reducing_slab_thickness': {'type': 'number', 'default': 0.225}, 'shaft_internal_diameter': {'type': 'number', 'default': 0.675}, 'working_space_each_side': {'type': 'number', 'default': 0.5}, 'benching_rebar_kg_per_m3': {'type': 'number', 'default': 60.0}, 'base_slab_rebar_kg_per_m3': {'type': 'number', 'default': 110.0}, 'cover_slab_rebar_kg_per_m3': {'type': 'number', 'default': 130.0}, 'sheet_pile_depth_below_formation': {'type': 'number', 'default': 1.0}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_manhole_precast
Compute Precast Concrete Monolithic Manhole BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Fully monolithic precast concrete circular manhole comprising factory-cast base + bottom ring + integral benching + pre-formed channel as a single delivered unit (BS 5911-3), with stacked precast chamber rings, optional reducing slab and access shaft, precast cover slab, ductile-iron frame and cover (BS EN 124 loading classes), step irons cast into rings, granular or concrete bedding, granular surround, geotextile separator, and excavation. Catalogue-driven sizing from PMC_1200 (1200mm ID) to PMC_2400 (2400mm ID). Routes via manhole_type=precast_monolithic attribute discrimination through CESMM4 Class K.1.2.x, NRM2 33.7.5, MMHW 500.5.5-.8 (SHW Cl. 507), and SMM7 R12.3.1.x. Example params: invert_depth=3.5 m (0.5–12), bedding_thickness_mm=150 mm (100–300), bedding_overhang_m=0.15 m (0.1–0.3). Example call: {"params": {"invert_depth": 3.5, "bedding_thickness_mm": 150, "bedding_overhang_m": 0.15}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['PMC_1200', 'PMC_1500', 'PMC_1800', 'PMC_2100', 'PMC_2400'], 'type': 'string', 'default': 'PMC_1500', 'description': 'Standard UK precast monolithic-base manhole chamber internal\ndiameters. Catalogued by Marshalls CPM, FP McCann, Stanton Bonna,\nand CPM Group. PMC1200 is the smallest commonly stocked monolithic\nbase; PMC2400 is the largest practical without bespoke order.'}, 'quantity': {'type': 'integer', 'default': 1}, 'access_type': {'enum': ['step_irons', 'ladder', 'none'], 'type': 'string', 'default': 'step_irons'}, 'ring_mass_t': {'type': 'number', 'default': None}, 'bedding_type': {'enum': ['granular', 'concrete'], 'type': 'string', 'default': 'granular', 'description': 'Bedding layer beneath a precast monolithic base.'}, 'invert_depth': {'type': 'number', 'default': 3.5}, 'cover_loading': {'enum': ['A15', 'B125', 'C250', 'D400', 'E600', 'F900'], 'type': 'string', 'default': 'D400', 'description': 'BS EN 124 cover-and-frame loading classes.'}, 'ring_height_m': {'type': 'number', 'default': None}, 'wall_thickness': {'type': 'number', 'default': None}, 'base_unit_mass_t': {'type': 'number', 'default': None}, 'cover_slab_grade': {'type': 'string', 'default': 'C40/50'}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'has_reducing_slab': {'type': 'boolean', 'default': True}, 'internal_diameter': {'type': 'number', 'default': None}, 'step_iron_spacing': {'type': 'number', 'default': 0.3}, 'surround_material': {'type': 'string', 'default': '20mm single-size aggregate'}, 'base_unit_height_m': {'type': 'number', 'default': None}, 'bedding_overhang_m': {'type': 'number', 'default': 0.15}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'surround_thickness': {'type': 'number', 'default': 0.15}, 'cover_clear_opening': {'type': 'number', 'default': 0.6}, 'bedding_thickness_mm': {'type': 'integer', 'default': 150}, 'cover_slab_thickness': {'type': 'number', 'default': 0.2}, 'cover_to_top_of_slab': {'type': 'number', 'default': 0.075}, 'geotextile_full_wrap': {'type': 'boolean', 'default': True}, 'seating_rings_height': {'type': 'number', 'default': 0.15}, 'bedding_concrete_grade': {'type': 'string', 'default': 'C8/10'}, 'bedding_granular_class': {'type': 'string', 'default': '6N'}, 'reducing_slab_at_depth': {'type': 'number', 'default': 1.2}, 'reducing_slab_thickness': {'type': 'number', 'default': 0.225}, 'shaft_internal_diameter': {'type': 'number', 'default': 0.675}, 'working_space_each_side': {'type': 'number', 'default': 0.5}, 'sheet_pile_depth_below_formation': {'type': 'number', 'default': 1.0}}, 'description': "Parameter form for a fully monolithic precast concrete manhole.\n\nCatalogue-driven: pick a ``size`` and the chamber's nominal\ndimensions, masses, and ring heights are read from ``_CATALOGUE``.\nOverride individual fields if a specific manufacturer differs."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_multi_section_assembly
Compute multi-section assembly BoQ
Compute one sectioned/linear assembly across multiple sections in a single call and return a combined Bill of Quantities plus per-section results. Each section sets its own run_length and geometry; shared_params apply to all sections. Use for a wall, kerb run, drain or barrier that changes along its length. assembly_slug must be a sectioned assembly (e.g. cantilever_wall, kerb_run, edge_drain); non-linear items return INVALID_INPUT. Free tier: MMHW only, each section consumes one daily slot. Example: {"assembly_slug":"cantilever_wall","standard":"MMHW","sections":[{"label":"Bay 1","run_length":20,"stem_height":1.5},{"label":"Bay 2","run_length":15,"stem_height":2.4}]}.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['assembly_slug', 'sections'], 'properties': {'sections': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}, 'aggregate_boq': {'type': 'boolean', 'default': True}, 'assembly_slug': {'type': 'string'}, 'shared_params': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'include_backup': {'type': 'boolean', 'default': False}, 'include_section_boq': {'type': 'boolean', 'default': False}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'section_count', 'section_summary', 'aggregated_boq_rows'], 'properties': {'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['section_label', 'warning'], 'properties': {'warning': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}, 'section_label': {'type': 'string', 'minLength': 1}}, 'description': 'A section-labelled geometry/advisory warning.', 'additionalProperties': False}}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'section_count': {'type': 'integer', 'minimum': 1}, 'parameters_used': {'type': 'object', 'additionalProperties': True}, 'section_results': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'section_summary': {'type': 'array', 'items': {'type': 'object', 'required': ['label', 'totals_summary'], 'properties': {'label': {'type': 'string', 'minLength': 1}, 'run_length': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}}, 'description': 'Cheap always-on per-section line: label + run length + totals.', 'additionalProperties': False}}, 'aggregated_boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}}, 'description': 'Aggregated + per-section result for a sectioned assembly run.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_pad_foundation
Compute Concrete Pad Foundation BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Single isolated reinforced concrete pad foundation with optional pedestal. Demonstrates BS 8666:2020 reinforcement scheduling integrated with the four-standard rendering invariant. Example params: length=2 m (0.5–10), width=2 m (0.5–10), thickness=0.45 m (0.15–2). Example call: {"params": {"length": 2, "width": 2, "thickness": 0.45}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'width': {'type': 'number', 'default': 2.0}, 'length': {'type': 'number', 'default': 2.0}, 'top_mat': {'type': 'boolean', 'default': True}, 'cover_mm': {'type': 'integer', 'default': 50}, 'thickness': {'type': 'number', 'default': 0.45}, 'has_pedestal': {'type': 'boolean', 'default': False}, 'working_space': {'type': 'number', 'default': 0.3}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'pedestal_width': {'type': 'number', 'default': 0.4}, 'side_bar_count': {'type': 'integer', 'default': 2}, 'pedestal_height': {'type': 'number', 'default': 0.5}, 'pedestal_length': {'type': 'number', 'default': 0.4}, 'top_bar_pitch_mm': {'type': 'integer', 'default': 200}, 'main_bar_pitch_mm': {'type': 'integer', 'default': 150}, 'blinding_thickness': {'type': 'number', 'default': 0.075}, 'top_bar_diameter_mm': {'type': 'integer', 'default': 12}, 'main_bar_diameter_mm': {'type': 'integer', 'default': 16}, 'side_bar_diameter_mm': {'type': 'integer', 'default': 10}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_parapet
Compute Parapet (Bridge / Structural Deck) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Bridge / structural-deck parapet installation per BS 6779-1 + BS EN 1317-2 + SHW Cl. 408. Discriminates between four UK parapet system classifications via the parapet_type enum (pedestrian_only per BS 7818; vehicle_p1_p2 — low-containment BS EN 1317-2; vehicle_h1_h2_h3 — higher-containment; combined_pedestrian_vehicle — composite design). Plus parallel discriminators on two further WorkCategory entries: same parapet_type on PARAPET_POST, transition_type on PARAPET_TRANSITION (to_vrs / to_abutment / expansion_joint). The MMHW Series 400 _parapet handler is the platform's SEVENTH 1D-banded handler — code `400.4.1.{c}` bands by containment_level (4 bands per BS EN 1317-2). 1D choice is disciplined — second principled rejection of forced 2D banding (after S38 road_marking). LAUNCH-COMPLETING 45TH ASSEMBLY — opens highway_bridge_edge L2 leaf, closing the highway suite at 5/5 populated leaves and the platform at 45/45 launch target. SMM7 routes BACK to Q40 (sibling slot to VRS at Q40.5) — preserves UK trade reality. Example params: parapet_height_mm=1100 mm (900–1800), parapet_length_m=25 m (1–2000), post_count=0 Nr (0–200). Example call: {"params": {"parapet_height_mm": 1100, "parapet_length_m": 25, "post_count": 0}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'post_count': {'type': 'integer', 'default': 0}, 'parapet_type': {'enum': ['pedestrian_only', 'vehicle_p1_p2', 'vehicle_h1_h2_h3', 'combined_pedestrian_vehicle'], 'type': 'string', 'default': 'vehicle_p1_p2', 'description': 'Parapet system classification per UK design practice.\n\nPEDESTRIAN_ONLY              â\x80\x94 BS 7818 handrail-and-infill for\n    footway / pedestrian-only bridges. Live load to BS EN 1991-2\n    but NO vehicle containment requirement.\nVEHICLE_P1_P2                â\x80\x94 BS EN 1317-2 containment class P1\n    or P2. Low-containment vehicle parapet for low-speed roads\n    (â\x89¤50mph). NOTE: in BS EN 1317-2 itself, P1/P2 are pedestrian\n    classes; UK vehicle-parapet practice extends the P-prefix to\n    cover low-containment vehicle situations.\nVEHICLE_H1_H2_H3             â\x80\x94 BS EN 1317-2 containment class H1,\n    H2 or H3. Higher-containment vehicle parapet for motorways\n    and high-speed roads.\nCOMBINED_PEDESTRIAN_VEHICLE  â\x80\x94 Composite design with vehicle-rated\n    lower section per BS EN 1317-2 and pedestrian-rated upper rail\n    per BS 7818. Used on shared footway/carriageway bridges.'}, 'transition_type': {'anyOf': [{'enum': ['to_vrs', 'to_abutment', 'expansion_joint'], 'type': 'string', 'description': 'Parapet transition classification.\n\nTO_VRS          â\x80\x94 Most common. Parapet-to-ground-level VRS\n    transition at the bridge approach end (deck-end to embankment).\n    Subject to BS EN 1317-4 transition compatibility requirements.\nTO_ABUTMENT     â\x80\x94 Parapet anchorage transition into masonry or\n    concrete bridge abutment wall (no VRS continuation â\x80\x94\n    terminates at the abutment).\nEXPANSION_JOINT â\x80\x94 Continuity break in the parapet at a deck\n    expansion joint on long bridges, accommodating structural\n    movement.'}, {'type': 'null'}], 'default': None}, 'parapet_length_m': {'type': 'number', 'default': 25.0}, 'transition_count': {'type': 'integer', 'default': 0}, 'containment_level': {'enum': ['P1', 'P2', 'N1', 'N2', 'H1', 'H2', 'H3', 'H4a', 'H4b'], 'type': 'string', 'default': 'N2', 'description': 'BS EN 1317-2 / BS EN 1317-6 containment classification.\n\nPedestrian classes:\n  P1 â\x80\x94 Light pedestrian containment.\n  P2 â\x80\x94 Heavier pedestrian containment (e.g. cyclist permitted).\n\nVehicle classes (ascending containment energy):\n  N1 â\x80\x94 Low containment, normal traffic.\n  N2 â\x80\x94 Higher of the normal range.\n  H1 â\x80\x94 Higher containment, high-speed road.\n  H2 â\x80\x94 Higher containment, dual carriageway.\n  H3 â\x80\x94 Very high containment, motorway.\n  H4a â\x80\x94 Highest containment, motorway HGV restraint.\n  H4b â\x80\x94 Highest containment, motorway HGV+bus restraint.'}, 'parapet_height_mm': {'type': 'integer', 'default': 1100}}, 'description': 'Inputs for the parapet assembly.\n\nRequired:\n  parapet_type        â\x80\x94 ParapetType enum (or string equivalent)\n  containment_level   â\x80\x94 ContainmentLevel enum (or string)\n  parapet_height_mm   â\x80\x94 nominal parapet height above deck in mm\n  parapet_length_m    â\x80\x94 parapet run length in metres\n\nOptional:\n  post_count          â\x80\x94 number of enumerated posts (default 0 â\x80\x94\n                        posts deemed-included in parapet m-rate).\n                        Set > 0 only for contracts requiring\n                        specialist per-post pricing.\n  transition_type     â\x80\x94 TransitionType enum (or string). Required\n                        if transition_count > 0.\n  transition_count    â\x80\x94 number of transition pieces (default 0).'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_permeable_pavement
Compute Permeable Pavement (CIRIA C753 SuDS) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Permeable pavement build-up per CIRIA C753 — The SuDS Manual Chapter 20. Covers the three principal UK permeable surface types (Permeable Block Paving per BS 7533-13; Porous Asphalt per SHW Cl. 938; Porous no-fines Concrete per CIRIA C753) and the three CIRIA infiltration regimes (System A full infiltration; System B partial / sides-tanked; System C no infiltration / fully tanked). Emits excavation + formation prep + tanking liner (Systems B/C) + geotextile separator + Class 3 open-graded reservoir sub-base + laying course (PBP) + permeable surface + perforated outlet pipe (Systems B/C) + disposal. Routes the reservoir sub-base, the tanking liner, and the permeable surface through three parallel classed-then-legacy discriminators (is_reservoir_sub_base, is_pavement_tanking, pavement_family) across all four standards. SMM7 PBP routes to Q25 (block pavings — different trade) while PA/PC stay at Q22 (asphalt trade) — UK trade-boundary platform principle. First launch-class assembly built entirely on existing WorkCategory vocabulary. Example params: length=12 m (0.5–500), width=5 m (0.5–100), reservoir_thickness_mm=350 mm (150–1000). Example call: {"params": {"length": 12, "width": 5, "reservoir_thickness_mm": 350}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'width': {'type': 'number', 'default': 5.0}, 'length': {'type': 'number', 'default': 12.0}, 'surface_type': {'enum': ['PBP', 'PA', 'PC'], 'type': 'string', 'default': 'PBP', 'description': 'Three principal UK permeable surface types per CIRIA C753.\nMapped 1:1 onto the new PavementFamily enum extensions (PBP/PA/PC).\nCarried as a dedicated enum on Parameters so the assembly\nparametrisation expresses intent in CIRIA-Manual vocabulary.'}, 'geotextile_grade': {'type': 'string', 'default': '200 g/m² non-woven'}, 'tanking_material': {'type': 'string', 'default': 'HDPE'}, 'include_outlet_pipe': {'type': 'boolean', 'default': False}, 'infiltration_system': {'enum': ['A', 'B', 'C'], 'type': 'string', 'default': 'A', 'description': 'Three CIRIA C753 (SuDS Manual Ch.20) permeable-pavement infiltration\nregimes. Drives the membrane / outlet pipe inclusion.'}, 'reservoir_shw_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '3', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'reservoir_voids_pct': {'type': 'integer', 'default': 30}, 'outlet_pipe_length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'surface_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'include_formation_prep': {'type': 'boolean', 'default': True}, 'reservoir_thickness_mm': {'type': 'integer', 'default': 350}, 'laying_course_shw_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '6N', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'outlet_pipe_diameter_mm': {'type': 'integer', 'default': 150}, 'tanking_thickness_micron': {'type': 'integer', 'default': 2000}, 'include_laying_course_line': {'type': 'boolean', 'default': False}, 'laying_course_thickness_mm': {'type': 'integer', 'default': 30}, 'include_geotextile_separator': {'type': 'boolean', 'default': True}, 'excavation_extra_each_side_mm': {'type': 'integer', 'default': 0}}, 'description': 'Input parameters for a permeable pavement assembly.\n\nGeometric defaults match a 12m Ã\x97 5m residential drive with PBP\nsurface and System A (full infiltration) â\x80\x94 the dominant UK\nsmall-civils SuDS use case.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_petrol_oil_interceptor
Compute Prefabricated Petrol/Oil Interceptor (Separator) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Prefabricated petrol/oil interceptor (separator) per BS EN 858-1:2002 / BS EN 858-2:2003 and SHW Cl. 519. Catalogue-driven on three axes: Class (1 with coalescer + auto-closure for ≤5 mg/l surface-water discharge, or 2 for ≤100 mg/l foul-sewer discharge), Type (full retention NSF for high-spill-risk forecourts, or bypass NSB for low-spill-risk car parks), and Nominal Size (NS3 to NS100 l/s flow rating — 7 catalogue entries). Composite of the procured interceptor unit (Nr, default supply route CONTRACTOR_INSTALL_PC_SUPPLY for engineer-specified prefab), concrete blinding bedding, granular surround per SHW Cl. 803, geotextile separator, and foundation excavation with optional sheet pile support. Oil storage capacity derived per BS EN 858-2 cl. 4.3.6 (V = NS×10 for full retention, NSB×15 for bypass). Opens drainage_treatment leaf; the canonical pre-treatment for hot-spot catchments draining to soakaway, watercourse, or foul sewer. Routes via CESMM4 K.5.x.n (size-banded), NRM2 33.9.x, MMHW 500.13.x (SHW Cl. 519), SMM7 R12.5.x. Example params: bedding_blinding_thickness_mm=150 mm (100–300), bedding_overhang_m=0.3 m (0.15–0.5), surround_thickness_each_side_m=0.3 m (0.15–0.5). Example call: {"params": {"bedding_blinding_thickness_mm": 150, "bedding_overhang_m": 0.3, "surround_thickness_each_side_m": 0.3}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'size': {'enum': ['NS3', 'NS6', 'NS10', 'NS15', 'NS30', 'NS65', 'NS100'], 'type': 'string', 'default': 'NS10', 'description': 'Nominal size NS designation per BS EN 858-2. The number is the\nnominal flow rating in l/s; the catalogue dimensions are sized to\nsuit the full-retention storage volume V_oil = NS Ã\x97 10 litres\n(cl. 4.3.6). Bypass units of the same NS rating share dimensions\nin most UK manufacturer ranges (the bypass weir is internal).\n\nSeven catalogue entries spanning the practical UK range:\n  NS3   â\x80\x94 small private yard, ~600m² impermeable catchment\n  NS6   â\x80\x94 modest commercial / garage forecourt, ~1,200m²\n  NS10  â\x80\x94 typical commercial yard / small forecourt, ~2,000m²\n  NS15  â\x80\x94 larger commercial site, ~3,000m²\n  NS30  â\x80\x94 large car park / petrol forecourt, ~6,000m²\n  NS65  â\x80\x94 major forecourt / small depot, ~13,000m²\n  NS100 â\x80\x94 industrial / lorry park / motorway service area, ~20,000m²\n\n(NS rating â\x86\x94 catchment area mapping is approximate; BS EN 858-2\ncl. 4.3.4 gives the formula NS = A Ã\x97 i Ã\x97 f, where i is the design\nrainfall intensity and f is the fluid-density factor.)'}, 'width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'height_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'integer', 'default': 1}, 'project_ref': {'type': 'string', 'default': ''}, 'unit_mass_t': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'ns_rating_ls': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'supply_route': {'enum': ['contractor_full', 'contractor_install_pc_supply', 'provisional_sum', 'utility_provider_supply', 'employer_direct'], 'type': 'string', 'default': 'contractor_install_pc_supply'}, 'oil_storage_l': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'chainage_label': {'type': 'string', 'default': ''}, 'surround_class': {'type': 'string', 'default': '6N'}, 'invert_to_top_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'silt_capacity_l': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'interceptor_type': {'enum': ['full_retention', 'bypass'], 'type': 'string', 'default': 'full_retention', 'description': 'Separator type per BS EN 858-2 cl. 4.3:\n\n  FULL_RETENTION (NS / NSF designation): treats the full design flow\n    from the contributing impermeable catchment. Sized to retain the\n    full contents of one compartment of a road tanker (â\x89¥ 7,600 litres\n    per cl. 4.3.6 for forecourt applications). Used at petrol filling\n    stations, fuel depots, and any high-spill-risk site.\n\n  BYPASS (NSB designation): treats only the first-flush of run-off\n    (typically up to 6.5 mm/h equivalent rainfall, ~10% of design\n    peak). Above that rate, excess flow bypasses the separator via\n    an internal weir. Used at large car parks where the spill risk\n    is low and bypass of large storm flows is acceptable. Oil\n    storage volume V = NSB Ã\x97 15 (cl. 4.3.6) â\x80\x94 50% more storage per\n    nominal-size unit than full-retention.'}, 'cover_to_invert_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'performance_class': {'enum': ['class_1', 'class_2'], 'type': 'string', 'default': 'class_1', 'description': 'Performance class per BS EN 858-1 cl. 5.4 / 5.5. Tested oil-in-water\nconcentration at outflow under standard test conditions:\n\n  CLASS_1: â\x89¤ 5 mg/l. Includes a coalescing filter and an automatic\n           closure device (auto-shut valve triggered when oil layer\n           reaches design depth). Required for discharge to:\n             - surface water sewer\n             - watercourse (river / stream)\n             - soakaway (with engineer agreement)\n             - any controlled water body\n  CLASS_2: â\x89¤ 100 mg/l. Gravity separation only (no coalescer). Used\n           for discharge to a foul sewer or to upstream of a Class 1\n           unit (rare two-stage configuration).'}, 'bedding_overhang_m': {'type': 'number', 'default': 0.3}, 'excavation_support': {'enum': ['open_batter', 'vertical_supported'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support method. OPEN_BATTER assumes stable ground and\nenough working area for battered sides (typically 1V:1H or steeper);\nVERTICAL_SUPPORTED requires sheet piling, trench boxes, or shoring\nand emits an EXCAVATION_SUPPORT (m²) line.'}, 'catalogue_size_label': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'bedding_blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'cover_to_top_of_unit_m': {'type': 'number', 'default': 0.3}, 'has_separate_silt_chamber': {'type': 'boolean', 'default': False}, 'working_space_each_side_m': {'type': 'number', 'default': 0.5}, 'geotextile_separator_grade': {'type': 'string', 'default': '200 g/m²'}, 'bedding_blinding_thickness_mm': {'type': 'integer', 'default': 150}, 'surround_thickness_each_side_m': {'type': 'number', 'default': 0.3}, 'sheet_pile_depth_below_invert_m': {'type': 'number', 'default': 1.0}}, 'description': 'Parameter form for a petrol/oil interceptor installation.\n\nCatalogue-driven on three axes: size (NS rating, catalogue lookup\nfor dimensions/mass/silt), class (performance â\x80\x94 CLASS_1/CLASS_2),\nand type (full retention vs bypass).'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_pipe_bedding
Compute Pipe Bedding and Surround BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Linear pipe trench with class-driven bedding and surround. Strategy pattern on (BeddingContext × BeddingClass): Highway (HA 40/01 / MMHW Series 500) vs Building (BS EN 1610 / NRM2 §33), Class N/F/B/S/A/Z. Emits trench excavation, granular bed, surround or concrete cradle/encasement, selected backfill, disposal and pipework. All four standards render with class and clause references. Example params: pipe_internal_diameter_mm=300 mm (100–1800), pipe_wall_thickness_mm=50 mm (10–200), pipe_length=25 m (1–500). Example call: {"params": {"pipe_internal_diameter_mm": 300, "pipe_wall_thickness_mm": 50, "pipe_length": 25}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'pipe_length': {'type': 'number', 'default': 25.0}, 'invert_depth': {'type': 'number', 'default': 1.5}, 'bedding_class': {'enum': ['N', 'F', 'B', 'S', 'A', 'Z'], 'type': 'string', 'default': 'B', 'description': 'Geometric bedding class per HA 40/01 / BS EN 1610.\n\nListed in ascending order of structural support.'}, 'pipe_material': {'enum': ['vitrified_clay', 'hdpe', 'upvc', 'concrete', 'ductile_iron'], 'type': 'string', 'default': 'vitrified_clay', 'description': 'Carrier pipe material.'}, 'backfill_class': {'type': 'string', 'default': 'Class 2A general fill'}, 'bedding_context': {'enum': ['highway', 'building'], 'type': 'string', 'default': 'highway', 'description': 'Specification context for pipe bedding measurement.\n\nHIGHWAY  â\x80\x94 MMHW Series 500 / HA 40/01. Bedding clause references\n           SHW Cl. 503. Class N/F/B/A common; Class S less so.\nBUILDING â\x80\x94 NRM2 §33 / BS EN 1610. Class S is the typical default;\n           Class A and Z used for deep or structural locations.'}, 'cover_above_crown': {'type': 'number', 'default': 0.15}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'trench_width_extra': {'type': 'number', 'default': 0.3}, 'pipe_wall_thickness_mm': {'type': 'integer', 'default': 50}, 'working_space_each_side': {'type': 'number', 'default': 0.15}, 'pipe_internal_diameter_mm': {'type': 'integer', 'default': 300}, 'excavation_support_required': {'type': 'boolean', 'default': False}, 'bedding_thickness_below_pipe': {'type': 'number', 'default': 0.15}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_pipework_testing
Compute Pipework Testing (drainage) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Linear measurement of testing on new drainage pipework — CCTV survey, air pressure test, water pressure test, or mandrel pull-through. Routes via CESMM4 Class I §I.8 (Tests on new pipework), NRM2 Group 33.18 (Testing of drainage) as priceable lines; via MMHW Series 500.7 (per SHW Cl. 507 deemed included in pipe-run rate) and SMM7 R12.7 (R12 coverage rules deemed included) as zero-priceable annotated lines for tender transparency. Introduces the platform's third named maturity pattern: deemed-included extra-over annotation (joining classed-then-legacy and declared-then-banded). Eight variant presets cover all four test methods x two bore scenarios each. Unit: M. Third member of the drainage_ancillaries L2 leaf. 21st use of the discriminator pattern via test_method. Example params: length_tested_m=100 m (1–2000), diameter_mm=225 mm (100–2400). Example call: {"params": {"length_tested_m": 100, "diameter_mm": 225}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'diameter_mm': {'type': 'integer', 'default': 225}, 'test_method': {'enum': ['cctv', 'air_pressure', 'water_pressure', 'mandrel_pull'], 'type': 'string', 'default': 'cctv', 'description': "Method of testing applied to the installed pipework.\n\nThe discriminator that routes through to the four standards'\nsub-codes:\n    cctv            -> CESMM4 I.8.1 / NRM2 33.18.1\n                        / MMHW 500.7.1 / SMM7 R12.7.1\n    air_pressure    -> CESMM4 I.8.2 / NRM2 33.18.2\n                        / MMHW 500.7.2 / SMM7 R12.7.2\n    water_pressure  -> CESMM4 I.8.3 / NRM2 33.18.3\n                        / MMHW 500.7.3 / SMM7 R12.7.3\n    mandrel_pull    -> CESMM4 I.8.4 / NRM2 33.18.4\n                        / MMHW 500.7.4 / SMM7 R12.7.4"}, 'pipe_material': {'type': 'string', 'default': 'vitrified clay'}, 'length_tested_m': {'type': 'number', 'default': 100.0}}, 'description': 'Parameters for a single pipework testing measurement.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_reinforced_soil_wall
Compute Reinforced Soil Wall (RSW) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Reinforced soil retaining wall (RSW) using granular fill reinforced with horizontal layers of geogrid or steel tie strips, with one of four facing systems: precast concrete panels (Reinforced Earth™ / VSL Retained Earth style), segmental modular blocks (Allan Block / Keystone), wraparound soft face (vegetated or biodegradable mat), or Terramesh-style steel mesh face (re-using the S29 gabion vocabulary). The SECOND member of the earth_structures L1 leaf (after gabion_wall at S29), the SIXTH member of the wall family, the FIFTH structural system, and the FIRST wall family member with a face-area-primary measurement basis (m² of face + m² × layers of geogrid, both m²; every prior wall body was m³). 17th use of the classed-then-legacy attribute discrimination pattern. Routes via four new WorkCategory entries (RSW_FACING_PANEL, RSW_MODULAR_BLOCK, RSW_WRAPAROUND_FACE, RSW_TIE_STRIP) plus the GEOGRID category (whose handler is gap-filled in CESMM4/NRM2/MMHW this session) plus re-use of GABION_BASKET on the STEEL_MESH_FACE variant. Codes: CESMM4 E.8.4-8 (Class E Earthworks §E.8 stabilisation), NRM2 5.23-27 (Group 5 Excavating and filling), MMHW 600.15-19 (Series 600 Earthworks; SHW Cl. 624 reinforced earth retaining structures), and SMM7 D41.3/D41.4/D41.5/D20.21/D20.14.2 (D41 — Crib walls / gabions / REINFORCED EARTH — the NAMED home, now serving TWO wall families). Eight variant presets exercise all four RSWFacing values (2/2/2/2 split). Example params: wall_height=6 m (0.5–12), wall_length=40 m (5–200), depth_into_fill_m=4.5 m (0.35–15). Example call: {"params": {"wall_height": 6, "wall_length": 40, "depth_into_fill_m": 4.5}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'fill_class': {'type': 'string', 'default': 'Class 6I'}, 'rsw_facing': {'enum': ['precast_panel', 'modular_block', 'wraparound', 'steel_mesh_face'], 'type': 'string', 'default': 'precast_panel', 'description': 'Facing system of the reinforced soil wall.\n\nPRECAST_PANEL   â\x80\x94 Reinforced Earthâ\x84¢ / Freyssinet / VSL Retained Earth\n                  style precast concrete facing panels (T-shape or\n                  cruciform). Primary measurement: face area m²\n                  routes to RSW_FACING_PANEL. Steel tie strips\n                  route separately to RSW_TIE_STRIP. Geogrid\n                  reinforcement (where used in addition to or in\n                  place of tie strips) routes to GEOGRID. Typical\n                  highway use: motorway widening, bridge approach\n                  embankments, mainline-network junction\n                  improvements.\n\nMODULAR_BLOCK   â\x80\x94 Segmental concrete block facing (Allan Block /\n                  Keystone / Anchor / Versa-Lok). Primary\n                  measurement: face area m² routes to\n                  RSW_MODULAR_BLOCK. Geogrid layers clamped between\n                  courses route to GEOGRID. Typical use: retail\n                  park boundary walls, golf-course retaining walls,\n                  cycle bridge approaches, residential development\n                  grading.\n\nWRAPAROUND      â\x80\x94 Soft-faced wraparound system: geogrid wraps the\n                  face of each lift and folds back into the\n                  reinforced fill. Primary measurement: face area\n                  m² routes to RSW_WRAPAROUND_FACE (the extra\n                  wraparound geogrid is built into the rate);\n                  horizontal reinforcement layers route to\n                  GEOGRID. Typical use: embankment toe\n                  stabilisation, slope-repair works, vegetated\n                  landscape retaining structures, temporary\n                  haul-road retaining walls.\n\nSTEEL_MESH_FACE â\x80\x94 Welded steel mesh "gabion-style" face with\n                  geogrid extending into the reinforced fill\n                  behind (Maccaferri Terramesh / Tensar Terramesh\n                  system). The face is structurally a gabion at\n                  the face line but the bulk of the structure is\n                  reinforced soil. Primary measurement: face is\n                  a thin gabion-style basket and routes to\n                  GABION_BASKET (re-using the S29 vocabulary â\x80\x94\n                  every RSW STEEL_MESH_FACE variant has zero new\n                  face WorkCategory introduction). Geogrid\n                  reinforcement layers extending into the fill\n                  route to GEOGRID. Typical use: highway boundary\n                  walls where the gabion aesthetic is wanted but\n                  the wall is too tall for a gravity gabion\n                  structure.'}, 'layer_count': {'type': 'integer', 'default': 8}, 'wall_height': {'type': 'number', 'default': 6.0}, 'wall_length': {'type': 'number', 'default': 40.0}, 'block_pattern': {'enum': ['allan_block', 'keystone', 'anchor_vertica', 'versa_lok'], 'type': 'string', 'default': 'allan_block', 'description': 'Block pattern for MODULAR_BLOCK variant.'}, 'geogrid_grade': {'enum': ['biaxial_pp', 'uniaxial_hdpe', 'uniaxial_polyester', 'galfan_steel_strip'], 'type': 'string', 'default': 'uniaxial_polyester', 'description': 'Geogrid product grade per BS EN 13251 / BS 8006-1:2010.\n\nThe grade governs the long-term design strength T_d (kN/m), which\ndrives the layer length and the layer count required for stability.'}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'face_treatment': {'enum': ['vegetated', 'biodegradable_erosion_mat', 'sprayed_hydroseed'], 'type': 'string', 'default': 'vegetated', 'description': 'Surface treatment for WRAPAROUND variant.'}, 'lift_height_mm': {'type': 'integer', 'default': 600}, 'block_height_mm': {'type': 'integer', 'default': 200}, 'face_panel_type': {'enum': ['t_shape_cruciform', 'hexagonal', 'rectangular_flat'], 'type': 'string', 'default': 't_shape_cruciform', 'description': 'Facing panel pattern for PRECAST_PANEL variant.'}, 'layer_spacing_m': {'type': 'number', 'default': 0.75}, 'geotextile_grade': {'type': 'string', 'default': '200 g/m²'}, 'include_blinding': {'type': 'boolean', 'default': True}, 'depth_into_fill_m': {'type': 'number', 'default': 4.5}, 'excavation_batter': {'type': 'number', 'default': 1.0}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter', 'description': 'Excavation support strategy for below-ground assemblies.\n\nConsumed by retaining walls (cantilever, gravity, counterfort,\nanchored, bored pile), foundation assemblies, and drainage chambers\nthat involve a battered or vertical-supported pit. The enum value is\nsurfaced in the description text of the relevant excavation BoQ line\nand in some standards (CESMM4 E.4.4 et seq.) drives a separate code.'}, 'foundation_profile': {'enum': ['level', 'stepped'], 'type': 'string', 'default': 'level', 'description': 'Foundation formation profile â\x80\x94 level or stepped.\n\nConsumed by retaining walls and foundation assemblies built on\nsloping ground. STEPPED foundation reuses the v10 cross-cutting\nEXCAVATION_FOUNDATION stepping discrimination upgrade (originally\nadded for strip_foundation S8). The stepping branch in the standards\nhandlers detects ``is_stepped=True`` on EXCAVATION_FOUNDATION items\nand routes to the stepped-foundation codes.'}, 'include_geotextile': {'type': 'boolean', 'default': True}, 'include_tie_strips': {'type': 'boolean', 'default': True}, 'panel_thickness_mm': {'type': 'integer', 'default': 180}, 'tie_strip_length_m': {'type': 'number', 'default': 4.5}, 'tie_strip_width_mm': {'type': 'integer', 'default': 50}, 'blinding_thickness_m': {'type': 'number', 'default': 0.1}, 'panel_concrete_grade': {'type': 'string', 'default': 'C40/50'}, 'terramesh_mesh_grade': {'type': 'string', 'default': 'galvanised hexagonal (BS EN 10223-3)'}, 'terramesh_stone_size': {'type': 'string', 'default': '100-200'}, 'tie_strip_thickness_mm': {'type': 'integer', 'default': 4}, 'excavation_working_space': {'type': 'number', 'default': 0.3}, 'terramesh_basket_width_m': {'type': 'number', 'default': 0.7}, 'tie_strip_density_per_m2': {'type': 'number', 'default': 2.0}, 'terramesh_basket_height_m': {'type': 'number', 'default': 1.0}, 'terramesh_basket_length_m': {'type': 'number', 'default': 2.0}, 'block_setback_per_course_mm': {'type': 'integer', 'default': 15}, 'geogrid_long_term_strength_kN': {'type': 'number', 'default': 80.0}}, 'description': 'Parameter form for a reinforced soil wall.\n\nA single dataclass that â\x80\x94 through combinations of its fields and\nthe ``rsw_facing`` discriminator â\x80\x94 produces all eight\nVARIANT_PRESETS plus arbitrary user-specified geometries across\nall four RSWFacing options. Sensible defaults yield a 6m\nhighway-approach PRECAST_PANEL wall.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_rigid_pavement
Compute Rigid (Concrete) Pavement Build-Up BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Rigid pavement build-up: optional capping (Class 6F) + Type 1 (Class 1A) granular sub-base + optional separation membrane + PQC slab (URC, JRC, or CRCP variant) with joint formwork (transverse contraction, longitudinal construction, expansion) and reinforcement (dowel bars + tie bars + optional fabric mesh for JRC, continuous longitudinal for CRCP). Routes the slab and its joints/reinforcement through the v12 is_pavement_slab discrimination to pavement-specific codes across all four standards (CESMM4 Class R, NRM2 Group 34.7, MMHW Series 1000, SMM7 Q21). Sub-base and capping route through the v8 FILL_SUB_BASE/FILL_CAPPING SHW-class-aware handlers. Three pavement-type defaults (URC/JRC/CRCP) per DMRB CD 226. Reinforcement scheduled per BS 8666:2020 (shape 00 dowels and tie bars; mass-only mesh and CRCP continuous). Example params: length=50 m (0.5–2000), width=7 m (0.5–30), sub_base_thickness_mm=150 mm (100–500). Example call: {"params": {"length": 50, "width": 7, "sub_base_thickness_mm": 150}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'width': {'type': 'number', 'default': 7.0}, 'length': {'type': 'number', 'default': 50.0}, 'mesh_type': {'enum': ['A142', 'A193', 'A252', 'A393', 'A483'], 'type': 'string', 'default': 'A393', 'description': 'BS 4483 fabric mesh designations relevant to JRC pavement.'}, 'lane_width_m': {'type': 'number', 'default': 3.5}, 'capping_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '6F2', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'pavement_type': {'enum': ['URC', 'JRC', 'CRCP'], 'type': 'string', 'default': 'JRC', 'description': 'Named UK rigid pavement variants per DMRB CD 226 / HD 26.\n\nURC  : Unreinforced Concrete (jointed, no mesh, dowels + tie bars only)\nJRC  : Jointed Reinforced Concrete (mesh mid-depth, dowels + tie bars)\nCRCP : Continuously Reinforced Concrete Pavement (continuous longitudinal\n       steel, no transverse joints)'}, 'concrete_grade': {'anyOf': [{'enum': ['C32/40', 'C40/50', 'C50/60'], 'type': 'string', 'description': 'Concrete grades typical for UK PQC per SHW Cl. 1001.\nPQ grades are project-specified but these three cover the bulk of\nUK practice for the small-civils market this product targets.'}, {'type': 'null'}], 'default': None}, 'sub_base_class': {'enum': ['1A', '1B', '1C', '2A', '2B', '2C', '2D', '2E', '3', '4', '5A', '5B', '6A', '6B', '6C', '6D', '6E', '6F1', '6F2', '6F3', '6F4', '6F5', '6I', '6J', '6N', '6P', '6Q', '7A', '7B', '7C', '7D', '7E', '7F', '8', '9A', '9B', 'U1A', 'U1B', 'U2'], 'type': 'string', 'default': '1A', 'description': 'Full SHW Series 600 Table 6/1 acceptable material class set, plus the\nTable 6/2 unacceptable classes.\n\nThe enum value is the SHW designator. Use `family` and `default_use`\nproperties for routing in the assembly and renderer code.'}, 'include_capping': {'type': 'boolean', 'default': False}, 'slab_thickness_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'capping_thickness_mm': {'type': 'integer', 'default': 350}, 'expansion_joint_count': {'type': 'integer', 'default': 0}, 'sub_base_thickness_mm': {'type': 'integer', 'default': 150}, 'crcp_long_bar_pitch_mm': {'type': 'integer', 'default': 150}, 'include_formation_prep': {'type': 'boolean', 'default': True}, 'crcp_long_bar_diameter_mm': {'type': 'integer', 'default': 16}, 'membrane_thickness_micron': {'type': 'integer', 'default': 125}, 'transverse_joint_spacing_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'include_separation_membrane': {'type': 'boolean', 'default': True}, 'excavation_extra_each_side_mm': {'type': 'integer', 'default': 0}}, 'description': 'Input parameters for a rigid pavement assembly.\n\nDefaults: 50m Ã\x97 7m urban distributor â\x80\x94 JRC with 25m bay length, 230mm\nslab on 150mm Type 1 sub-base, A393 mesh mid-depth. Tie bars at\n3.5m lane boundary. No capping by default.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_road_marking
Compute Road Marking BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Road marking installation per SHW Cl. 1207-1215 and TSRGD 2016. Discriminates between five UK marking-line classifications via the marking_line_type enum: continuous, broken_short, broken_long, double_continuous, lane_line. Plus parallel discriminators on three further WorkCategory entries: area_marking_type on ROAD_MARKING_AREA, symbol_type on ROAD_MARKING_SYMBOL, and stud_type on ROAD_STUD. THIRD member of the highway L1 leaf (after S36 VRS, S37 traffic_sign) and SECOND member of the highway_signs_markings L2 leaf — 42nd assembly. The highway_signs_markings L2 leaf becomes the first L2 leaf in the highway L1 to reach 2 members. Five variant presets cover the principal UK commercial scenarios: urban continuous white line, rural broken centreline with hazard, motorway hatched chevron, junction give-way with triangle, and motorway lane line with studs. Routes via four new WorkCategory entries (ROAD_MARKING_LINE, ROAD_MARKING_AREA, ROAD_MARKING_SYMBOL, ROAD_STUD). Codes: CESMM4 X.5 (Class X §5 — road markings), NRM2 34.9 (Site works — markings), MMHW 1200.1.{w} (Series 1200 — Traffic Signs and Road Markings, with 1D banding by line_width_class), SMM7 Q40.7 (Section Q40 — Fencing/site furniture). 26th use of classed-then-legacy attribute discrimination pattern; 7th use of declared-then-banded (remains 1D — material rejected as a banding axis). Broadest unit-mix in any single CivilQuants assembly: m of line + m² of area + nr of symbol + nr of stud. Example params: actual_line_width_mm=100 mm (50–450), line_length_m=200 m (0–10000), secondary_line_length_m=0 m (0–10000). Example call: {"params": {"actual_line_width_mm": 100, "line_length_m": 200, "secondary_line_length_m": 0}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'area_m2': {'type': 'number', 'default': 0.0}, 'quantity': {'type': 'integer', 'default': 1}, 'stud_type': {'anyOf': [{'enum': ['non_depressible', 'depressible', 'bidirectional'], 'type': 'string', 'description': 'Reflective road stud type per BS EN 1463-1.\n\nNON_DEPRESSIBLE â\x80\x94 Older specification adhered or mechanically fixed,\n    still common on minor roads and lower-volume routes. Not\n    snowplough-resistant.\nDEPRESSIBLE     â\x80\x94 Motorway / dual-carriageway specification per\n    BS EN 1463-1 Class TRP-D. Stud body retracts into the running\n    surface under snowplough blade pressure.\nBIDIRECTIONAL   â\x80\x94 Two-way visibility stud for junction approaches\n    and central reserves.'}, {'type': 'null'}], 'default': None}, 'stud_count': {'type': 'integer', 'default': 0}, 'symbol_type': {'anyOf': [{'enum': ['arrow', 'word', 'give_way_triangle', 'transverse_bar', 'mini_roundabout', 'cycle_symbol'], 'type': 'string', 'description': 'Painted symbol/legend type. UK practice enumerates per occurrence\nregardless of physical size (a STOP word is 1nr whether the\ncharacters are 1.6m or 2.8m).\n\nARROW              â\x80\x94 Directional arrow per TSRGD 2016 Schedule 7.\nWORD               â\x80\x94 Word/legend (BUS, KEEP CLEAR, SLOW, SCHOOL,\n                     STOP, GIVE WAY) per TSRGD Schedule 8.\nGIVE_WAY_TRIANGLE  â\x80\x94 Give-way triangle marking per TSRGD diagram 1023.\nTRANSVERSE_BAR     â\x80\x94 Transverse bar pair per TSRGD Schedule 6 (the\n                     transverse element of give-way / stop lines).\nMINI_ROUNDABOUT    â\x80\x94 Mini-roundabout central symbol per TSRGD\n                     diagram 1003.4.\nCYCLE_SYMBOL       â\x80\x94 Cycle symbol per TSRGD diagram 1057 (painted\n                     cycle icon on cycle lane or shared surface).'}, {'type': 'null'}], 'default': None}, 'symbol_count': {'type': 'integer', 'default': 0}, 'line_length_m': {'type': 'number', 'default': 200.0}, 'line_width_class': {'enum': ['standard_100mm', 'wide_200mm', 'extra_wide_300mm', 'hatched_400mm_plus'], 'type': 'string', 'default': 'standard_100mm', 'description': 'Line width band per UK QS pricing practice. Line width is the\ndominant cost driver per linear metre of marking â\x80\x94 paint coverage\nscales linearly with width, and the marking-application contractor\nprices per width band.\n\nSTANDARD_100MM     â\x80\x94 â\x89¤150mm (standard centre/edge line; 100mm is\n                     the dominant case)\nWIDE_200MM         â\x80\x94 >150-200mm (motorway edge line, distributor-\n                     road edge line)\nEXTRA_WIDE_300MM   â\x80\x94 >200-300mm (stop line at signalised junction,\n                     heavy-use edge line)\nHATCHED_400MM_PLUS â\x80\x94 >300mm (hatched edge stripe, ghost-island\n                     boundary marking)'}, 'marking_material': {'enum': ['thermoplastic', 'cold_paint', 'preformed_tape', 'mma'], 'type': 'string', 'default': 'thermoplastic', 'description': 'Road marking material per SHW Cl. 1208.\n\nTHERMOPLASTIC   â\x80\x94 Hot-applied thermoplastic (dominant UK material;\n                  4-7 year life on highway routes).\nCOLD_PAINT      â\x80\x94 Cold-applied paint per BS EN 1871 (lower-cost,\n                  1-2 year life, common for car parks and minor\n                  installations).\nPREFORMED_TAPE  â\x80\x94 Preformed retroreflective tape; specialist\n                  applications (temporary diversions, premium-\n                  retroreflective requirements).\nMMA             â\x80\x94 Methyl methacrylate cold-applied two-pack resin;\n                  high-friction, high-durability, premium cost.\n\nMaterial is carried on the description text only per UK QS practice\n(NOT a structural discriminator and NOT a banding axis). Material\ndifferences are priced as part of the per-line-width rate rather\nthan as separate bill lines.'}, 'area_marking_type': {'anyOf': [{'enum': ['hatched_chevron', 'ghost_island', 'box_junction', 'cycle_box', 'bus_stop_box', 'keep_clear'], 'type': 'string', 'description': 'Painted-area marking type per TSRGD 2016 Schedule 9 and various\ndiagram-numbered references. The area cost driver is paint/\nthermoplastic coverage (m² of painted surface).\n\nHATCHED_CHEVRON â\x80\x94 Hatched chevron area between carriageways,\n    typically at 45° hatching with bordered edges. TSRGD Schedule 9.\nGHOST_ISLAND    â\x80\x94 Painted refuge area within carriageway, hatched\n    border. Common at minor-road junctions and right-turn lanes.\nBOX_JUNCTION    â\x80\x94 Yellow box junction (cross-hatched, anti-grid-\n    locking). TSRGD diagram 1043.\nCYCLE_BOX       â\x80\x94 Cycle-box / advanced stop line area, typically\n    green-coloured surface plus cycle symbol. TSRGD diagram 1001.2.\nBUS_STOP_BOX    â\x80\x94 Bus stop cage marking (painted bus-stop bay\n    outline + BUS legend). TSRGD diagram 1025.\nKEEP_CLEAR      â\x80\x94 KEEP CLEAR rectangular zone prohibiting waiting\n    and parking. TSRGD diagram 1026.'}, {'type': 'null'}], 'default': None}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'marking_line_type': {'anyOf': [{'enum': ['continuous', 'broken_short', 'broken_long', 'double_continuous', 'lane_line'], 'type': 'string', 'description': 'Longitudinal road marking line type per TSRGD 2016 Schedule 6.\n\nCONTINUOUS â\x80\x94 Continuous longitudinal line. Used for edge lines, lane\n    edge lines on motorways, and prohibitive centre lines where\n    overtaking is forbidden. The dominant single-line case.\n\nBROKEN_SHORT â\x80\x94 Broken short-pattern line (short mark, long gap).\n    Used for permissive centre lines on rural roads and lane lines\n    on dual carriageways. Standard pattern per TSRGD diagram 1004.\n\nBROKEN_LONG â\x80\x94 Broken long-pattern hazard warning line (long mark,\n    short gap). Used for cautionary centre lines warning of hazard\n    ahead â\x80\x94 junction approach, bend ahead, restricted visibility.\n    TSRGD diagram 1005.\n\nDOUBLE_CONTINUOUS â\x80\x94 Double continuous longitudinal line, used where\n    overtaking is prohibited in both directions. TSRGD diagram\n    1013.1.\n\nLANE_LINE â\x80\x94 Lane-dividing line on motorway or dual-carriageway\n    (broken pattern, typically 100mm with reflective studs).\n    TSRGD diagram 1004.\n\nThe five line types span the genuinely-different UK commercial\ndecisions a QS would face when pricing a road-marking tender.'}, {'type': 'null'}], 'default': 'continuous'}, 'reflective_colour': {'anyOf': [{'enum': ['white', 'red', 'amber', 'green', 'blue'], 'type': 'string', 'description': 'Reflective road stud colour per TSRGD 2016.\n\nWHITE â\x80\x94 Lane lines (lane-dividing studs on motorway lane separators).\nRED   â\x80\x94 Left edge of carriageway (UK left-hand drive convention).\nAMBER â\x80\x94 Right edge / central reserve / motorway hard shoulder line.\nGREEN â\x80\x94 Lay-by / slip-road indication.\nBLUE  â\x80\x94 Emergency / fire-hydrant marking.'}, {'type': 'null'}], 'default': None}, 'secondary_line_type': {'anyOf': [{'enum': ['continuous', 'broken_short', 'broken_long', 'double_continuous', 'lane_line'], 'type': 'string', 'description': 'Longitudinal road marking line type per TSRGD 2016 Schedule 6.\n\nCONTINUOUS â\x80\x94 Continuous longitudinal line. Used for edge lines, lane\n    edge lines on motorways, and prohibitive centre lines where\n    overtaking is forbidden. The dominant single-line case.\n\nBROKEN_SHORT â\x80\x94 Broken short-pattern line (short mark, long gap).\n    Used for permissive centre lines on rural roads and lane lines\n    on dual carriageways. Standard pattern per TSRGD diagram 1004.\n\nBROKEN_LONG â\x80\x94 Broken long-pattern hazard warning line (long mark,\n    short gap). Used for cautionary centre lines warning of hazard\n    ahead â\x80\x94 junction approach, bend ahead, restricted visibility.\n    TSRGD diagram 1005.\n\nDOUBLE_CONTINUOUS â\x80\x94 Double continuous longitudinal line, used where\n    overtaking is prohibited in both directions. TSRGD diagram\n    1013.1.\n\nLANE_LINE â\x80\x94 Lane-dividing line on motorway or dual-carriageway\n    (broken pattern, typically 100mm with reflective studs).\n    TSRGD diagram 1004.\n\nThe five line types span the genuinely-different UK commercial\ndecisions a QS would face when pricing a road-marking tender.'}, {'type': 'null'}], 'default': None}, 'actual_line_width_mm': {'type': 'integer', 'default': 100}, 'secondary_line_length_m': {'type': 'number', 'default': 0.0}}, 'description': 'Parameters for a single road marking installation.\n\nDefaults anchored to URBAN_CONTINUOUS_WHITE_LINE â\x80\x94 200 m of\ncontinuous 100 mm thermoplastic edge/centre line. Required-field\ndefaults added per G.6.7.24 precedent â\x80\x94 non-breaking API enrichment\nopens the slug to schema-driven workspace defaults and defaults-\nbased parity-fixture regen.\n\nGeometry interpretation:\n  - ``line_length_m`` is the linear length of the primary marking\n    line (continuous edge/centre line, broken pattern, etc.). UK\n    practice measures along the line centreline. Set to 0 if no\n    primary line is part of the installation.\n  - ``secondary_line_length_m`` is for installations with two distinct\n    line types (e.g. broken_short main centreline + broken_long\n    hazard section). Set to 0 to omit. The secondary line shares\n    the same width_class and material as the primary line.\n  - ``area_m2`` is the m² of painted area marking (hatched chevron,\n    ghost island, box junction, etc.). Set to 0 if no area is\n    present.\n  - ``symbol_count`` is the number of distinct painted symbol\n    occurrences (arrows, words, give-way triangles). Set to 0 if\n    no symbols are present.\n  - ``stud_count`` is the number of reflective road studs. Set to\n    0 if no studs are present.\n\nDiscrimination & banding:\n  - ``marking_line_type`` discriminates the description text for the\n    ROAD_MARKING_LINE WorkItem(s). Required if line_length_m > 0.\n  - ``line_width_class`` discriminates the BANDED CODE in MMHW\n    (1D-banding axis) and the description text in other standards.\n  - ``area_marking_type`` discriminates description for the\n    ROAD_MARKING_AREA WorkItem. Required if area_m2 > 0.\n  - ``symbol_type`` discriminates description for the\n    ROAD_MARKING_SYMBOL WorkItem. Required if symbol_count > 0.\n  - ``stud_type`` and ``reflective_colour`` discriminate description\n    for the ROAD_STUD WorkItem. Required if stud_count > 0.\n  - ``marking_material`` is carried on every description but is\n    NOT a discriminator or banding axis (UK QS convention).'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_single_service_run
Compute Single Service Run BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Single-service utility run per NJUG Volume 1 — one water main OR one gas main OR one electricity cable duct OR one telecoms duct (or fibre / street-lighting / HV cable duct) in a dedicated trench. Wraps the combined-services-trench engine with a single-band envelope and re-tags emissions back to this assembly. Renders through CESMM4 Class I / NRM2 Group 41 / MMHW Series 1300 / SMM7 Group T (services) on top of the shared earthworks / drainage handlers (excavation, disposal, bedding, surround, fill, tape). Example params: bedding_thickness_m=0.1 m (0.05–0.3), surround_above_crown_m=0.15 m (0–0.5), trench_length_m=50 m (1–1000). Example call: {"params": {"bedding_thickness_m": 0.1, "surround_above_crown_m": 0.15, "trench_length_m": 50}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'cover_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'material': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pipe_od_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'njug_colour': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'project_ref': {'type': 'string', 'default': 'Single Service Run'}, 'service_type': {'enum': ['water', 'gas_lp', 'gas_mp', 'electricity_lv', 'electricity_hv', 'telecoms', 'fibre', 'street_lighting'], 'type': 'string', 'default': 'water', 'description': 'Utility service categories per NJUG Volume 1.'}, 'support_type': {'enum': ['none', 'trench_box', 'sheet_pile', 'timber_board'], 'type': 'string', 'default': 'none', 'description': 'How the trench sides are supported during installation.'}, 'warning_tape': {'type': 'boolean', 'default': True}, 'bedding_class': {'enum': ['N', 'F', 'B', 'S', 'A', 'Z'], 'type': 'string', 'default': 'S', 'description': 'Geometric bedding class per HA 40/01 / BS EN 1610.\n\nListed in ascending order of structural support.'}, 'chainage_label': {'type': 'string', 'default': ''}, 'trench_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'bedding_context': {'enum': ['highway', 'building'], 'type': 'string', 'default': 'highway', 'description': 'Specification context for pipe bedding measurement.\n\nHIGHWAY  â\x80\x94 MMHW Series 500 / HA 40/01. Bedding clause references\n           SHW Cl. 503. Class N/F/B/A common; Class S less so.\nBUILDING â\x80\x94 NRM2 §33 / BS EN 1610. Class S is the typical default;\n           Class A and Z used for deep or structural locations.'}, 'trench_length_m': {'type': 'number', 'default': 50.0}, 'bedding_thickness_m': {'type': 'number', 'default': 0.1}, 'surround_above_crown_m': {'type': 'number', 'default': 0.15}, 'tape_height_above_crown_m': {'type': 'number', 'default': 0.3}, 'working_space_below_bed_mm': {'type': 'integer', 'default': 100}, 'surface_reinstatement_thickness_m': {'type': 'number', 'default': 0.0}}, 'description': "Parameters for a single-service utility run.\n\nMaps neatly to a one-column UI form: the user picks a service type\nfrom a dropdown, optionally tweaks cover/OD/material, sets length\nand trench width, and that's it. The wrapper builds the equivalent\n``ServiceBand`` + single-band ``CombinedServicesTrenchParameters``\ninternally.\n\nAll defaults align with NJUG 7 minimum-cover guidance for the\nselected service type (resolved at compute-time via the same\n``_NJUG_DEFAULTS`` table that CST consumes)."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_soakaway
Compute Infiltration Soakaway (CIRIA C753) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_attenuation_tank. Infiltration soakaway per CIRIA C753 Chapter 25. Granular-fill or modular-crate storage envelope with infiltration discharge through the base and side walls. Wraps attenuation_tank for the storage envelope and emits an INFILTRATION_SURFACE item plus optional PERFORATED_DISTRIBUTION_PIPE on top. Includes the C753 rational-method sizing engine with hot-spot and cold-spot factors of safety per C753 Tables 25.4 / 25.5; the engine refuses to size for VERY_HIGH hot-spot catchments (fuel forecourts, lorry parks) which C753 prohibits from direct infiltration without pre-treatment. Half-emptying time checked against the 24h C753 §25.4 limit. Renders cleanly across CESMM4 / NRM2 / MMHW / SMM7 using existing earthworks / drainage handlers plus the two new categories (INFILTRATION_SURFACE, PERFORATED_DISTRIBUTION_PIPE) added in S22. Example params: catchment_area_m2=500 m² (10–10000), rainfall_depth_mm=60 mm (10–300), measured_infiltration_rate_m_per_s=0.0001 m/s (1e-07–0.01). Example call: {"params": {"catchment_area_m2": 500, "rainfall_depth_mm": 60, "measured_infiltration_rate_m_per_s": 0.0001}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'hot_spot': {'enum': ['low', 'medium', 'high', 'very_high'], 'type': 'string', 'default': 'low', 'description': 'CIRIA C753 §25.5 / Table 25.5 hot-spot land-use categories.\n\nA "hot spot" is a catchment area whose runoff carries elevated\npollution risk â\x80\x94 primarily hydrocarbons (fuel, oil), heavy metals\n(from brake wear, tyre wear), or de-icing chemicals. C753 requires\nenhanced treatment OR a discount on the infiltration rate (more\ntreatment time in the soil) for hot-spot catchments.\n\nThe values below match C753 Table 25.5 categorisation:\n\n  LOW           â\x80\x94 residential, footways, amenity (no discount)\n  MEDIUM        â\x80\x94 car parks, minor roads, supermarket forecourts\n  HIGH          â\x80\x94 A-roads, large car parks, HGV access, industrial yards\n  VERY_HIGH     â\x80\x94 fuel forecourts, lorry parks, vehicle workshops, depots\n                   (NB: C753 may direct that infiltration is NOT\n                    permitted at all without pre-treatment)'}, 'quantity': {'type': 'integer', 'default': 1}, 'soil_type': {'type': 'string', 'default': 'silty sand'}, 'tank_type': {'enum': ['crate', 'pipes'], 'type': 'string', 'default': 'crate'}, 'confidence': {'enum': ['low', 'medium', 'high'], 'type': 'string', 'default': 'medium', 'description': 'CIRIA C753 Table 25.4 confidence categories for the\nfactor-of-safety on the as-measured infiltration rate.\n\nThe factor compensates for spatial heterogeneity in soil\npermeability, seasonal water-table variation, and long-term\nclogging by fines.\n\n  LOW         â\x80\x94 single soakage test, FoS = 10\n  MEDIUM      â\x80\x94 2-3 tests, FoS = 4\n  HIGH        â\x80\x94 â\x89¥3 tests with consistent results + groundwater\n                 monitoring, FoS = 2'}, 'void_ratio': {'type': 'number', 'default': 0.3}, 'project_ref': {'type': 'string', 'default': 'Soakaway'}, 'plan_width_m': {'type': 'number', 'default': 5.0}, 'plan_length_m': {'type': 'number', 'default': 10.0}, 'chainage_label': {'type': 'string', 'default': ''}, 'storage_depth_m': {'type': 'number', 'default': 2.0}, 'crate_void_ratio': {'type': 'number', 'default': 0.95}, 'catchment_area_m2': {'type': 'number', 'default': 500.0}, 'cover_to_tank_top': {'type': 'number', 'default': 0.5}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'rainfall_depth_mm': {'type': 'number', 'default': 60.0}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'runoff_surface_type': {'enum': ['hard_impermeable', 'hard_permeable', 'gravel', 'grass', 'pervious_paving'], 'type': 'string', 'default': 'hard_impermeable', 'description': 'Runoff coefficient categories per BRE 365 / C753 Table 24.1.\nUsed when ``design_storm_volume_m3`` is computed from catchment\narea rather than supplied directly.\n\nValues map to typical Cv (volumetric runoff coefficient) for the\nUK climate and design storm range; the engine uses these as\ndefaults but a user can override.'}, 'has_distribution_pipe': {'type': 'boolean', 'default': True}, 'design_storm_volume_m3': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'working_space_each_side': {'type': 'number', 'default': 0.6}, 'distribution_pipe_length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'distribution_pipe_material': {'type': 'string', 'default': 'perforated HDPE'}, 'runoff_coefficient_override': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'distribution_pipe_diameter_mm': {'type': 'integer', 'default': 150}, 'measured_infiltration_rate_m_per_s': {'type': 'number', 'default': 0.0001}}, 'description': "Parameters for a CIRIA C753 infiltration soakaway.\n\nTwo ways to specify the design storm:\n\n  (a) ``design_storm_volume_m3`` directly (from an upstream\n      MicroDrainage / InfoWorks ICM model) â\x80\x94 preferred for any\n      catchment > 1 ha or where the upstream model is the\n      design-of-record.\n\n  (b) ``catchment_area_m2`` + ``rainfall_depth_mm`` +\n      ``runoff_surface_type`` (or ``runoff_coefficient_override``)\n      â\x80\x94 the rational-method shortcut, appropriate for small-catchment\n      soakaways (housing estate, supermarket forecourt, small\n      commercial yard) where a senior QS / drainage engineer\n      would sketch the design from these three numbers.\n\nIf both are specified, ``design_storm_volume_m3`` wins.\n\nSoil characterisation:\n  - ``measured_infiltration_rate_m_per_s``: from a BRE 365\n    falling-head soakage test on site\n  - ``confidence``: per C753 Table 25.4 â\x80\x94 LOW (single test, FoS=10),\n    MEDIUM (2-3 tests, FoS=4), HIGH (â\x89¥3 tests + groundwater\n    monitoring, FoS=2)\n  - ``hot_spot``: per C753 §25.5 â\x80\x94 LOW (residential / amenity),\n    MEDIUM (car parks, minor roads), HIGH (A-roads, large car\n    parks), VERY_HIGH (forecourts, lorry parks â\x80\x94 not permitted\n    without pre-treatment)\n\nGeometry:\n  Rectangular plan, prismatic depth. The depth here is the\n  effective storage depth (water level at design fill); the\n  attenuation_tank's ``cover_to_tank_top`` covers the soil cover\n  above the granular surround.\n\nThe granular fill type is governed by the underlying\nattenuation_tank delegate â\x80\x94 pick ``tank_type=CRATE`` for modular\ngeocellular soakaways (typical for high storage / low footprint)\nor ``tank_type=PIPES`` for large-bore concrete pipe soakaways\n(typical for highway and industrial). The ``void_ratio`` here\napplies to the granular-fill case (TankType.CRATE with\n``crate_void_ratio`` becomes a free user choice; for the pipe\ncase the pipes themselves provide the storage volume)."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_soil_nailed_slope
Compute Soil-Nailed Slope BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Cut slope stabilised by passively-stressed soil nails with an applied face system. Discriminates between four face systems via the face_system enum: SHOTCRETE_MESH (dominant UK highway-cutting choice per SHW Cl. 644), HARD_FACING_PANEL (premium permanent works), FLEXIBLE_MESH (weathered rock drape), and VEGETATED_GEOGRID (landscape-sensitive schemes). Third member of the earth_structures L1 leaf (after gabion_wall S29 and reinforced_soil_wall S30). Eight variant presets cover all four face systems × representative slope geometries. Routes via three new WorkCategory entries (SOIL_NAIL, SHOTCRETE_FACE, FACE_MESH_REINFORCEMENT) plus reuse of EXCAVATION_GENERAL, DISPOSAL, CONCRETE_REINFORCED, GEOTEXTILE_FILTER, GEOGRID, and TOPSOIL_PLACE. Codes: CESMM4 C.5.X (soil nail) + E.8.10 (shotcrete) + G.5.8 (mesh), NRM2 7.7.X + 5.28.1 + 11.6.1, MMHW 600.20.X + 600.21.1 + 600.22.1 (SHW Cl. 638-639 / Cl. 644), SMM7 D32.3.X (steel piling — soil nails) + D41.6/D41.7 (the NAMED home for the three earth-structures families now). 23rd use of the classed-then-legacy attribute discrimination pattern; 4th use of the declared-then-banded pattern (nail_length_m bands the C.5.X / 7.7.X / 600.20.X / D32.3.X third digit). Example params: slope_height_m=8 m (0.5–25), slope_angle_deg=65 ° (10–89), slope_length_m=30 m (2–500). Example call: {"params": {"slope_height_m": 8, "slope_angle_deg": 65, "slope_length_m": 30}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'nail_rows': {'type': 'integer', 'default': 4}, 'face_system': {'enum': ['shotcrete_mesh', 'hard_facing_panel', 'flexible_mesh', 'vegetated_geogrid'], 'type': 'string', 'default': 'shotcrete_mesh', 'description': "Face system for the soil-nailed slope.\n\nSHOTCRETE_MESH    â\x80\x94 Wet-mix sprayed concrete (typically C25/30 to\n                    C32/40) over a single layer of welded steel\n                    fabric mesh (BS 4483 A193 to A393), with\n                    horizontal reinforcing waling bars at each\n                    nail row. The dominant UK choice for permanent\n                    highway-cutting stabilisation per SHW Cl. 644.\n                    Routes: SHOTCRETE_FACE (m²) + FACE_MESH_\n                    REINFORCEMENT (m²) + SOIL_NAIL (Nr) +\n                    GEOTEXTILE_FILTER (m², drainage strips).\n\nHARD_FACING_PANEL â\x80\x94 Precast concrete face panels (typically 1.5m\n                    Ã\x97 1.5m Ã\x97 0.15m thick, RC) bolted to the slope\n                    via the nail head plates. The premium face\n                    system for permanent works adjacent to\n                    sensitive receptors (carriageways, railways,\n                    bridges) where the maintained appearance of a\n                    hard concrete face is required and the\n                    durability requirement exceeds shotcrete's\n                    design life. Routes: CONCRETE_REINFORCED\n                    (m³, panels) + SOIL_NAIL (Nr) +\n                    GEOTEXTILE_FILTER (m²). NB: shotcrete and\n                    face mesh are NOT emitted â\x80\x94 the precast\n                    panel IS the face.\n\nFLEXIBLE_MESH     â\x80\x94 Heavy-duty galvanised steel mesh drape (BS 4483\n                    A252 or similar, but typically a proprietary\n                    rockfall/erosion-protection drape mesh such as\n                    Geobrugg TECCO, Maccaferri Steelgrid HR) over\n                    the slope face, pinned by the nail head plates\n                    but NOT covered by shotcrete. The light-touch\n                    face system for weathered-rock cut faces where\n                    the dominant failure mode is surface ravelling\n                    rather than mass instability. Routes:\n                    FACE_MESH_REINFORCEMENT (m²) + SOIL_NAIL (Nr).\n                    No shotcrete, no drainage strips required.\n\nVEGETATED_GEOGRID â\x80\x94 Geogrid (PP or HDPE biaxial, e.g. Tensar SS35\n                    or Maccaferri PSG type) wrapped over the\n                    slope face with topsoil and seed/turf\n                    established on the surface. The soft-face,\n                    environmentally-sensitive option â\x80\x94 used for\n                    landslide stabilisation in rural / parkland\n                    settings, river-bank stabilisation, and\n                    landscape-led highway schemes. Routes:\n                    GEOGRID (m²) + SOIL_NAIL (Nr) + GEOTEXTILE_\n                    FILTER (m², drainage strips) + TOPSOIL_PLACE\n                    (m², face soil layer).\n\nThe four face systems span UK practice from light protection\n(FLEXIBLE_MESH) through standard (SHOTCRETE_MESH) and premium\n(HARD_FACING_PANEL) to environmentally-sensitive (VEGETATED_\nGEOGRID). These are the genuinely different commercial\ndecision points a QS would face when pricing a soil-nailed\nslope tender."}, 'steel_grade': {'type': 'string', 'default': 'B500B'}, 'geogrid_grade': {'type': 'string', 'default': 'PP_biaxial_35kN'}, 'nail_length_m': {'type': 'number', 'default': 6.0}, 'slope_height_m': {'type': 'number', 'default': 8.0}, 'slope_length_m': {'type': 'number', 'default': 30.0}, 'bar_diameter_mm': {'type': 'integer', 'default': 25}, 'nail_permanence': {'enum': ['permanent', 'temporary'], 'type': 'string', 'default': 'permanent', 'description': 'Permanent or temporary soil nail per BS EN 14490 Table 1.\n\nPERMANENT â\x80\x94 Design life â\x89¥ 2 years. Bar requires double corrosion\n            protection (DCP): epoxy-coated bar OR galvanised bar\n            + grouted cementitious annulus + corrugated plastic\n            sheath. Conventional UK choice for highway-cutting\n            stabilisation under SHW Cl. 644.\nTEMPORARY â\x80\x94 Design life < 2 years. Single corrosion protection\n            (SCP) acceptable â\x80\x94 bare bar in cementitious grout\n            annulus is sufficient. Used for temporary basement\n            support and short-term construction-phase\n            stabilisation.'}, 'shotcrete_grade': {'type': 'string', 'default': 'C25/30'}, 'slope_angle_deg': {'type': 'number', 'default': 65.0}, 'drill_diameter_mm': {'type': 'integer', 'default': 100}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'grout_strength_mpa': {'type': 'integer', 'default': 25}, 'panel_thickness_mm': {'type': 'integer', 'default': 150}, 'nail_inclination_deg': {'type': 'number', 'default': 15.0}, 'panel_concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'topsoil_thickness_mm': {'type': 'integer', 'default': 150}, 'face_mesh_designation': {'type': 'string', 'default': 'A193'}, 'shotcrete_thickness_mm': {'type': 'integer', 'default': 100}, 'drainage_strip_width_mm': {'type': 'integer', 'default': 300}, 'nail_vertical_spacing_m': {'type': 'number', 'default': 1.5}, 'drainage_strip_spacing_m': {'type': 'number', 'default': 3.0}, 'nail_horizontal_spacing_m': {'type': 'number', 'default': 1.5}}, 'description': 'Parameters for a single soil-nailed slope.\n\nGeometry interpretation:\n  - ``slope_height_m`` is the vertical extent of the cut slope\n    (top of crest to toe of slope).\n  - ``slope_angle_deg`` is the slope angle from horizontal\n    (typically 50-80° for soil-nailed cuts).\n  - ``slope_length_m`` is the horizontal length along the slope\n    crest â\x80\x94 the spatial extent of the assembly along the highway\n    alignment.\n  - ``nail_rows`` is the number of horizontal rows of nails;\n    ``nail_horizontal_spacing_m`` and ``nail_vertical_spacing_m``\n    give the in-row and between-row centres (m).\n  - ``nail_length_m`` is the design nail length (excavation +\n    bond length; same for all nails in this assembly â\x80\x94 for\n    variable-length schemes, instantiate multiple assemblies).\n  - ``nail_inclination_deg`` is the angle below horizontal of\n    the nail axis (typically 10-20°).\n\nFace-system attributes (used only if relevant to ``face_system``):\n  - ``shotcrete_thickness_mm`` / ``shotcrete_grade`` / \n    ``face_mesh_designation`` â\x80\x94 SHOTCRETE_MESH only.\n  - ``panel_thickness_mm`` / ``panel_concrete_grade`` â\x80\x94\n    HARD_FACING_PANEL only.\n  - ``geogrid_grade`` / ``topsoil_thickness_mm`` â\x80\x94\n    VEGETATED_GEOGRID only.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_strip_foundation
Compute Concrete Strip Foundation BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_cantilever_wall. Linear reinforced concrete strip foundation, level or stepped. Closes the P1 launch set alongside pad_foundation. Integrates BS 8666:2020 reinforcement scheduling. Stepping is the v10 demonstration of cross-cutting standards-handler discrimination. Example params: length=10 m (1–100), width=0.75 m (0.3–2.5), thickness=0.35 m (0.15–1.5). Example call: {"params": {"length": 10, "width": 0.75, "thickness": 0.35}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'width': {'type': 'number', 'default': 0.75}, 'length': {'type': 'number', 'default': 10.0}, 'cover_mm': {'type': 'integer', 'default': 50}, 'thickness': {'type': 'number', 'default': 0.35}, 'is_stepped': {'type': 'boolean', 'default': False}, 'step_count': {'type': 'integer', 'default': 0}, 'step_height': {'type': 'number', 'default': 0.3}, 'working_space': {'type': 'number', 'default': 0.3}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'founding_depth': {'type': 'number', 'default': 1.0}, 'blinding_thickness': {'type': 'number', 'default': 0.075}, 'top_long_bar_count': {'type': 'integer', 'default': 2}, 'bottom_long_bar_count': {'type': 'integer', 'default': 2}, 'transverse_bar_pitch_mm': {'type': 'integer', 'default': 250}, 'top_long_bar_diameter_mm': {'type': 'integer', 'default': 12}, 'transverse_bar_diameter_mm': {'type': 'integer', 'default': 8}, 'bottom_long_bar_diameter_mm': {'type': 'integer', 'default': 16}}, 'description': 'Parameters for the strip foundation assembly.\n\nDefaults are tuned to a typical UK domestic / light commercial strip:\n750mm wide, 350mm deep, 10m long, founded ~700mm below GL on 75mm\nblinding. Reinforcement is 2T16 bottom + 2T12 top with T8 transverse\ndistribution at 250 centres â\x80\x94 a conservative starting point\nrefineable per loading.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_swale
Compute SuDS Swale (CIRIA C753) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_attenuation_tank. Vegetated, geotextile-reinforced or rip-rap-lined linear drainage swale per CIRIA C753. Trapezoidal prismatic channel with three lining strategies covering the UK design palette from low-velocity amenity grass channels (1V:3H, 1-3% gradient) to high-velocity rip-rap-lined stretches. Optional check-dams (stone or concrete) for steeper sections. Renders cleanly across all four standards using existing earthworks / geosynthetics / concrete handlers — no PC items, all contractor-full supply route. Example params: bed_width=0.5 m (0.2–3), left_side_slope_h_per_v=3 (1.5–6), right_side_slope_h_per_v=3 (1.5–6). Example call: {"params": {"bed_width": 0.5, "left_side_slope_h_per_v": 3, "right_side_slope_h_per_v": 3}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'lining': {'enum': ['vegetated', 'geotextile_reinforced', 'rip_rap'], 'type': 'string', 'default': 'vegetated', 'description': 'Swale lining type â\x80\x94 drives which WorkItems are emitted.'}, 'bed_width': {'type': 'number', 'default': 0.5}, 'trm_grade': {'type': 'string', 'default': '300 g/m² turf reinforcement mat (SHW Cl. 624)'}, 'swale_depth': {'type': 'number', 'default': 0.4}, 'rip_rap_spec': {'type': 'string', 'default': '200-300mm rip-rap rock fill (SHW Cl. 622, Class 6F2)'}, 'swale_length': {'type': 'number', 'default': 50.0}, 'check_dam_count': {'type': 'integer', 'default': 0}, 'grass_seed_spec': {'type': 'string', 'default': 'amenity grass seed mix, BS 7370-3'}, 'rip_rap_thickness': {'type': 'number', 'default': 0.25}, 'check_dam_material': {'enum': ['stone', 'concrete'], 'type': 'string', 'default': 'stone', 'description': 'Material for optional check-dams.'}, 'check_dam_thickness': {'type': 'number', 'default': 0.3}, 'topsoil_place_depth': {'type': 'number', 'default': 0.15}, 'topsoil_strip_depth': {'type': 'number', 'default': 0.25}, 'longitudinal_gradient': {'type': 'number', 'default': 0.02}, 'formation_prep_required': {'type': 'boolean', 'default': True}, 'left_side_slope_h_per_v': {'type': 'number', 'default': 3.0}, 'right_side_slope_h_per_v': {'type': 'number', 'default': 3.0}, 'rip_rap_geotextile_grade': {'type': 'string', 'default': '200 g/m² non-woven filter (SHW Cl. 624)'}, 'topsoil_strip_envelope_offset': {'type': 'number', 'default': 0.5}}}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_traffic_sign
Compute Traffic Sign BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Traffic sign installation per SHW Cl. 1201-1206 and TSRGD 2016. Discriminates between five TSRGD sign classifications via the sign_type enum: warning triangular, regulatory circular, regulatory rectangular, directional rectangular, and information rectangular. SECOND member of the highway L1 leaf (after S36 VRS) and FIRST member of the highway_signs_markings L2 leaf — 41st assembly. Five variant presets cover the principal UK commercial scenarios: rural warning triangle on single post, urban regulatory circular, rural advance directional on twin posts, motorway gantry ADS, and urban information rectangle. Routes via three new WorkCategory entries (TRAFFIC_SIGN_POST, TRAFFIC_SIGN_FACE, SIGN_FOUNDATION). Codes: CESMM4 X.4 (Class X §4 — traffic signs), NRM2 34.8 (Site works — signs), MMHW 1300.1.{a}.{h} (Series 1300 — Road Lighting/Traffic Signs/Bollards, with 2D banding by face_area × mounting_height), SMM7 Q40.6 (Section Q40 — Fencing/site furniture). 25th use of classed-then-legacy attribute discrimination pattern; 6th use of declared-then-banded AND the SECOND 2D-banded handler (MMHW 1300.1.{a}.{h} bands by both axes simultaneously). Example params: post_length_m=3 m (1.5–12), post_count=1 Nr (1–4), faces=1 Nr (1–6). Example call: {"params": {"post_length_m": 3, "post_count": 1, "faces": 1}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'faces': {'type': 'integer', 'default': 1}, 'quantity': {'type': 'integer', 'default': 1}, 'sign_type': {'enum': ['warning_triangular', 'regulatory_circular', 'regulatory_rectangular', 'directional_rectangular', 'information_rectangular'], 'type': 'string', 'default': 'warning_triangular', 'description': 'Traffic sign type per TSRGD 2016 classification.\n\nWARNING_TRIANGULAR â\x80\x94 Warning sign per TSRGD 2016 Schedule 2.\n    Equilateral triangular face (typically 750mm/900mm/1200mm\n    per side per TSM Ch. 4). Red border on white background;\n    warning of hazards ahead. The dominant low-cost UK case.\n\nREGULATORY_CIRCULAR â\x80\x94 Regulatory sign per TSRGD 2016 Schedule 3.\n    Circular face (typically 600mm/750mm/900mm diameter).\n    Red border (prohibition) or blue (mandatory). The\n    dominant UK enumerated-regulatory case.\n\nREGULATORY_RECTANGULAR â\x80\x94 Regulatory sign per TSRGD 2016\n    Schedules 3 and 4. Rectangular face â\x80\x94 used for parking\n    restrictions, speed limits with supplementary plates,\n    loading bays. White background with text/symbols.\n\nDIRECTIONAL_RECTANGULAR â\x80\x94 Directional sign per TSRGD 2016\n    Schedule 11. Rectangular face â\x80\x94 large area for route\n    legends. Green (primary routes), blue (motorways), white\n    (local). Internally illuminated where specified per\n    TSM Ch. 7.\n\nINFORMATION_RECTANGULAR â\x80\x94 Information sign per TSRGD 2016\n    Schedule 12. Rectangular face â\x80\x94 tourist destinations,\n    facilities, services, place names.\n\nThe five sign types span the genuinely-different UK commercial\ndecisions a QS would face when pricing a traffic-sign tender.'}, 'post_count': {'type': 'integer', 'default': 1}, 'post_length_m': {'type': 'number', 'default': 3.0}, 'post_material': {'enum': ['steel', 'aluminium', 'timber'], 'type': 'string', 'default': 'steel', 'description': 'Sign post material per SHW Cl. 1201. UK convention specifies\nhot-dip galvanised steel as the default; aluminium is used for\nlightweight applications; timber is exceptional (heritage\nlocations only).'}, 'concrete_grade': {'type': 'string', 'default': 'C25/30'}, 'face_area_class': {'enum': ['small', 'medium', 'large', 'very_large'], 'type': 'string', 'default': 'small', 'description': 'Sign face area band per UK QS pricing practice. The face area\ndrives material cost (retroreflective sheeting per m²),\nfabrication cost, and (above the small threshold) typically\ndrives the number of posts required. Bands chosen to match\ntypical UK signage practice per TSM Ch. 4:\n\nSMALL       â\x80\x94 â\x89¤0.5m² (typical warning triangle 900mm side)\nMEDIUM      â\x80\x94 0.5-2.0m² (typical regulatory 750-900mm dia,\n              small directional plate)\nLARGE       â\x80\x94 2.0-10.0m² (typical single-route directional\n              on twin posts)\nVERY_LARGE  â\x80\x94 >10m² (gantry-mounted ADS panel covering\n              multiple lanes; sometimes called "gantry"\n              face area class)'}, 'foundation_type': {'enum': ['post_mounted_small', 'post_mounted_large', 'twin_post_pad', 'gantry_pad'], 'type': 'string', 'default': 'post_mounted_small', 'description': 'Sign foundation type per SHW Cl. 1204. Drives the SIGN_FOUNDATION\ndescription and the implicit unit rate the QS will apply.\n\nPOST_MOUNTED_SMALL  â\x80\x94 Small mass-concrete block (~0.3m³) for a\n    single warning or regulatory sign on a single post. The\n    dominant UK case by count.\nPOST_MOUNTED_LARGE  â\x80\x94 Larger mass-concrete block (~0.6m³) for\n    a heavier sign or longer post (>3m post height).\nTWIN_POST_PAD       â\x80\x94 Pair of small mass-concrete blocks linked\n    by a ground beam for a twin-post directional sign.\nGANTRY_PAD          â\x80\x94 Full reinforced pad (~2m³+) for gantry\n    legs. Concrete is still deemed-included in the unit rate\n    per SHW Cl. 1205 â\x80\x94 the gantry pad is bundled with gantry\n    leg supply.'}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'actual_face_area_m2': {'type': 'number', 'default': 0.35}, 'mounting_height_class': {'enum': ['post_mounted', 'elevated', 'gantry'], 'type': 'string', 'default': 'post_mounted', 'description': 'Sign mounting height band per UK QS pricing practice. The\nmounting height drives access cost (small post = step-ladder;\nelevated = MEWP / cherry picker; gantry = full lane closure +\nspecialist lifting). Bands chosen to match typical UK access\npractice:\n\nPOST_MOUNTED â\x80\x94 <3m AGL (above ground level) â\x80\x94 typical for\n               warning and regulatory signs on single posts.\n               Hand-tool access from the verge.\nELEVATED     â\x80\x94 3-5m AGL â\x80\x94 typical for large directional signs\n               on twin posts. MEWP / cherry-picker access.\nGANTRY       â\x80\x94 >5m AGL â\x80\x94 overhead gantry signs spanning\n               carriageway. Lane-closure + specialist lifting\n               required.'}, 'approximate_foundation_volume_m3': {'type': 'number', 'default': 0.3}}, 'description': 'Parameters for a single traffic sign installation.\n\nGeometry interpretation:\n  - ``post_length_m`` is the length of the supporting post above\n    ground (UK convention measures the *above-ground* length, not\n    the often-greater driven/embedded length). For gantry signs,\n    this is the height of each gantry leg.\n  - ``post_count`` is the number of supporting posts. Typical\n    values: 1 (small warning/regulatory), 2 (twin-post directional,\n    gantry legs).\n  - ``faces`` is the number of distinct sign faces on the\n    assembly. A single gantry can carry 1-3 distinct sign faces\n    (one per lane); a twin-post directional can carry advance\n    and confirmation faces.\n\nFace geometry:\n  - ``actual_face_area_m2`` is the m² of a single face (used for\n    face-area descriptions; the WorkItem quantity is enumerated\n    per face).\n\nFoundation:\n  - ``foundation_type`` carries the SHW Cl. 1204 classification.\n  - ``concrete_grade`` is for description text â\x80\x94 concrete is\n    deemed-included in the foundation unit rate (no separate\n    CONCRETE line emitted).\n  - ``approximate_foundation_volume_m3`` is for description text\n    only â\x80\x94 UK QS convention does not measure sign-foundation\n    concrete separately (see SHW Cl. 1204).'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_utility_chamber
Compute Utility Access Chamber BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Catalogue-driven utility access chamber covering ten standard UK types: BT/Openreach jointing chambers JC1-JC4 (defaulting to UTILITY_PROVIDER_SUPPLY routing), water meter chamber (FW6), wastewater inspection chamber (RW9), valve chamber, gas Emergency Control Valve pit (ECV), LV electrical link box, and cable draw pit. Composite emission: precast chamber unit + BS EN 124 cover & frame (PC supply) + excavation + bedding (SHW Cl. 803) + granular surround + optional geotextile + selected fill + disposal. Routes via manhole_type=utility_chamber attribute discrimination through CESMM4 Class K.1.5.x, NRM2 33.7.11-.13, MMHW 500.5.13-.15 (SHW Cl. 507), and SMM7 R12.3.10-.12. JC types route their chamber unit through the v18 statutory-undertaker supply route infrastructure (CESMM4 Class A.4.3, NRM2 Group 1, MMHW Series 100, SMM7 A53) as a PC sum plus contractor attendance line. Example params: bedding_thickness_mm=150 mm (75–300), bedding_overhang_m=0.1 m (0.075–0.3), surround_thickness_m=0.15 m (0.1–0.3). Example call: {"params": {"bedding_thickness_mm": 150, "bedding_overhang_m": 0.1, "surround_thickness_m": 0.15}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'quantity': {'type': 'integer', 'default': 1}, 'project_ref': {'type': 'string', 'default': 'Utility Chamber'}, 'unit_mass_t': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'chamber_type': {'enum': ['JC1', 'JC2', 'JC3', 'JC4', 'FW6', 'RW9', 'valve_chamber', 'ecv_pit', 'link_box', 'draw_pit'], 'type': 'string', 'default': 'JC2', 'description': 'Ten catalogue chamber types covering the UK utility-estimating palette.'}, 'plan_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'supply_route': {'anyOf': [{'enum': ['contractor_full', 'contractor_install_pc_supply', 'provisional_sum', 'utility_provider_supply', 'employer_direct'], 'type': 'string'}, {'type': 'null'}], 'default': None}, 'bedding_class': {'type': 'string', 'default': '6N'}, 'cover_loading': {'anyOf': [{'enum': ['A15', 'B125', 'C250', 'D400', 'E600', 'F900'], 'type': 'string', 'description': 'BS EN 124 cover-and-frame loading classes.'}, {'type': 'null'}], 'default': None}, 'plan_length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'chainage_label': {'type': 'string', 'default': ''}, 'internal_depth_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'wall_thickness_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'excavation_batter': {'type': 'number', 'default': 0.5}, 'surround_material': {'type': 'string', 'default': '20mm single-size aggregate'}, 'bedding_overhang_m': {'type': 'number', 'default': 0.1}, 'excavation_support': {'enum': ['open_batter', 'vertical'], 'type': 'string', 'default': 'open_batter'}, 'bedding_thickness_mm': {'type': 'integer', 'default': 150}, 'geotextile_full_wrap': {'type': 'boolean', 'default': False}, 'surround_thickness_m': {'type': 'number', 'default': 0.15}, 'cover_clear_opening_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'cover_to_top_of_unit_m': {'type': 'number', 'default': 0.075}, 'working_space_each_side_m': {'type': 'number', 'default': 0.3}, 'sheet_pile_depth_below_formation_m': {'type': 'number', 'default': 0.5}}, 'description': "Parameter form for a utility access chamber.\n\nCatalogue-driven: pick a ``chamber_type`` and the chamber's nominal\nplan dimensions, depth, wall thickness, cover loading and supply\nroute default are read from ``_CATALOGUE``. Any field left as\n``None`` resolves to the catalogue default at ``__post_init__``\ntime; an explicit value wins.\n\nThe ``supply_route`` parameter follows the same rule: ``None`` â\x86\x92\ncatalogue default (UTILITY_PROVIDER_SUPPLY for JC1â\x80\x93JC4,\nCONTRACTOR_FULL for the other six). Setting an explicit value\noverrides â\x80\x94 e.g. setting ``SupplyRoute.CONTRACTOR_FULL`` on a JC2\ncaptures the private-estate case where the chamber is contractor-\nsupplied rather than Openreach-supplied."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_utility_kiosk_base
Compute Utility Kiosk Base BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_manhole. Foundation + kiosk hardware composite for utility cabinets — LV electricity feeder pillars (DNO-supplied), Openreach FTTC cabinets (PIA-supplied), EV rapid-charging plinths, packaged DNO substations, and generic precast plinths. Light-wrapper delegation around pad_foundation for the substructure (excavation, RC pad with pedestal, reinforcement), plus kiosk-specific PC-supply hardware (1 complete unit on UPS route, 4 components — body / door / lock / base-plate — on Employer-PC route). Catalogue-driven supply-route defaults encode that LV pillars and FTTC cabinets are normally utility-provider-supplied complete units, while EV chargers, DNO substations, and generic plinths are normally Employer-PC-nominated per component. Example params: quantity=1 Nr (1–100), blinding_thickness_m=0.075 m (0.05–0.15), working_space_m=0.3 m (0–1). Example call: {"params": {"quantity": 1, "blinding_thickness_m": 0.075, "working_space_m": 0.3}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'top_mat': {'type': 'boolean', 'default': False}, 'cover_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'integer', 'default': 1}, 'kiosk_type': {'enum': ['lv_pillar', 'fttc_cabinet', 'ev_charger', 'dno_substation', 'generic_pad'], 'type': 'string', 'default': 'lv_pillar', 'description': 'The five kiosk types in the launch catalogue.'}, 'project_ref': {'type': 'string', 'default': 'Utility Kiosk Base'}, 'thickness_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'plan_width_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'supply_route': {'anyOf': [{'enum': ['contractor_full', 'contractor_install_pc_supply', 'provisional_sum', 'utility_provider_supply', 'employer_direct'], 'type': 'string'}, {'type': 'null'}], 'default': None}, 'plan_length_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'blinding_grade': {'type': 'string', 'default': 'C8/10'}, 'chainage_label': {'type': 'string', 'default': ''}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'rebar_pitch_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'side_bar_count': {'type': 'integer', 'default': 2}, 'working_space_m': {'type': 'number', 'default': 0.3}, 'top_bar_pitch_mm': {'type': 'integer', 'default': 250}, 'pedestal_height_m': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'rebar_diameter_mm': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}, 'top_bar_diameter_mm': {'type': 'integer', 'default': 10}, 'blinding_thickness_m': {'type': 'number', 'default': 0.075}}, 'description': 'Parameters for a utility kiosk base.\n\nFields marked "(None â\x86\x92 catalogue)" resolve from the catalogue entry\nat ``__post_init__`` time; an explicit non-None value always wins.'}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
compute_vehicle_restraint_system
Compute Vehicle Restraint System (VRS) BoQ
Paid tier only. Calling this without an authenticated CivilQuants account returns TIER_INSUFFICIENT — sign up at https://civilquants.com/pricing or use the free-tier alternative compute_end_area_earthworks. Vehicle restraint system (VRS) for highway works per SHW Cl. 401-419 and BS EN 1317. Discriminates between six structural system types via the vrs_system_type enum: tensioned and untensioned corrugated steel beam, wire rope, in-situ concrete step barrier, precast concrete single-slope, and combined heavy-duty (corrugated beam over concrete kerb upstand). FIRST member of the highway_restraint L2 leaf — opens the brand-new highway L1 category as the 40th assembly. Six variant presets cover the principal UK commercial scenarios: motorway verge TCB N2/W4, motorway central wire rope N2/W6, urban untensioned N2/W2, bridge approach concrete step H2/W1, median precast single-slope H2/W2, and high-containment verge H4a/W4. Routes via three new WorkCategory entries (VEHICLE_RESTRAINT_SYSTEM, VRS_TERMINAL, VRS_TRANSITION) plus reuse of CONCRETE_REINFORCED, REINFORCEMENT, FORMWORK and EXCAVATION_TRENCH for the concrete variants. Codes: CESMM4 X.3 (Class X §3 — crash barriers), NRM2 34.7 (Site works — crash barriers), MMHW 400.1.{ww}.{cl} (Series 400 — Road Restraint Systems, with 2D banding by working_width × containment), SMM7 Q40.5 (Section Q40 — Fencing, crash barriers). 24th use of the classed-then-legacy attribute discrimination pattern; 5th use of the declared-then-banded pattern AND the FIRST 2D-banded handler (MMHW 400.1.{ww}.{cl} bands by both axes simultaneously). Example params: length_m=100 m (12–10000), post_spacing_m=2 m (0.5–8), foundation_width_m=0.9 m (0.2–2). Example call: {"params": {"length_m": 100, "post_spacing_m": 2, "foundation_width_m": 0.9}, "standard": "MMHW"}. Omitted parameters use sensible engineering defaults. Pass deliverables=["xlsx","dxf","pdf"] (any subset) to also receive one-shot download URLs in the same call: Excel BoQ (both tiers, watermarked free) plus the dimensioned DXF (CAD) and PDF drawing sheets (paid tier).
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['params'], 'properties': {'params': {'type': 'object', 'properties': {'length_m': {'type': 'number', 'default': 100.0}, 'quantity': {'type': 'integer', 'default': 1}, 'to_system': {'type': 'string', 'default': 'bridge_parapet'}, 'from_system': {'type': 'string', 'default': 'tensioned_corrugated_beam'}, 'transitions': {'type': 'integer', 'default': 0}, 'wire_strands': {'type': 'integer', 'default': 4}, 'concrete_grade': {'type': 'string', 'default': 'C32/40'}, 'post_spacing_m': {'type': 'number', 'default': 2.0}, 'terminal_class': {'enum': ['P1', 'P2', 'P3', 'P4'], 'type': 'string', 'default': 'P2', 'description': 'BS EN 1317-4 terminal performance class. P1-P4 reflects energy\nabsorption and lateral redirection performance under impact.\nHigher number = more demanding test.'}, 'foundation_type': {'enum': ['driven', 'socketed', 'insitu_foundation', 'precast_slab'], 'type': 'string', 'default': 'driven', 'description': 'Post/barrier foundation type. Drives whether excavation and\nconcrete foundation lines are emitted.\n\nDRIVEN        â\x80\x94 Steel post driven directly into the verge.\n                No excavation or concrete foundation emitted.\n                Conventional for TENSIONED_CORRUGATED_BEAM and\n                UNTENSIONED_CORRUGATED_BEAM on standard verges.\n\nSOCKETED      â\x80\x94 Steel post set into a precast concrete socket;\n                socket embedded in lean-mix concrete foundation.\n                Emits a concrete foundation line (m³). Used where\n                driven installation is not feasible (rock close to\n                surface, contaminated ground, sensitive utilities).\n\nINSITU_FOUND  â\x80\x94 Continuous reinforced concrete strip foundation\n                cast beneath in-situ concrete VRS. Emits\n                CONCRETE_REINFORCED + REINFORCEMENT + FORMWORK\n                lines for the foundation itself. Always paired\n                with CONCRETE_STEP_INSITU.\n\nPRECAST_SLAB  â\x80\x94 Precast concrete VRS units sit on a pre-cast\n                levelled slab foundation; foundation deemed\n                included in the precast supply rate.'}, 'vrs_system_type': {'enum': ['tensioned_corrugated_beam', 'untensioned_corrugated_beam', 'wire_rope', 'concrete_step_insitu', 'concrete_single_slope_precast', 'combined_heavy_duty'], 'type': 'string', 'default': 'tensioned_corrugated_beam', 'description': 'Vehicle restraint system structural type per BS EN 1317-2 / SHW\nCl. 402-404.\n\nTENSIONED_CORRUGATED_BEAM   â\x80\x94 Hot-dip galvanised steel "W-beam"\n    section, tensioned end-to-end via anchor terminals. Steel posts\n    at 2.0m or 4.0m centres (driven or socketed). The dominant UK\n    motorway-verge system per SHW Cl. 402 Working Width 4 (W4)\n    Containment N2. Single-sided.\n\nUNTENSIONED_CORRUGATED_BEAM â\x80\x94 Same W-beam profile but without\n    end-anchored tensioning â\x80\x94 relies on post stiffness rather than\n    cable tension. Lower containment, higher working width. SHW\n    Cl. 402 Working Width 2 (W2) Containment N2. Used on urban\n    dual-carriageways and where containment requirement is\n    moderate.\n\nWIRE_ROPE                   â\x80\x94 3- or 4-strand pre-tensioned steel\n    wire rope between sparse posts (3.2m centres typical). Highest\n    working width for given containment (W6 or higher), narrowest\n    physical footprint. The dominant UK motorway-central-reserve\n    system per SHW Cl. 403. NOT permitted in narrow central\n    reserves where W6 cannot be accommodated.\n\nCONCRETE_STEP_INSITU        â\x80\x94 In-situ reinforced concrete VRS,\n    F-shape or step-shape cross-section per SHW Cl. 404. Highest\n    containment per UK practice (H2 standard, H4a for vulnerable-\n    receptor verges). Working width W1-W2. The dominant UK choice\n    for bridge approaches, viaduct edges, and verges adjacent to\n    watercourses/structures. Carries BS 8666 reinforcement.\n\nCONCRETE_SINGLE_SLOPE_PRECAST â\x80\x94 Precast concrete F-shape units\n    (typically 6m units, bolted to slab foundation or sit-on-grade).\n    Same containment family as CONCRETE_STEP_INSITU but priced as\n    precast supply-and-install. Reinforcement deemed-included in\n    the precast unit price. Used where rapid installation is\n    commercially decisive (rolling roadworks, off-peak working).\n\nCOMBINED_HEAVY_DUTY         â\x80\x94 Tensioned corrugated beam over a\n    concrete kerb upstand or with double-rail layout for H4a\n    containment. SHW Cl. 402 + Cl. 404 hybrid. Used at the\n    outboard side of motorway verges adjacent to schools,\n    residential properties, or sensitive natural features where\n    H4a containment is the design requirement.\n\nThe six system types span the genuinely-different UK commercial\ndecisions a QS would face when pricing a VRS tender.'}, 'wire_tension_kn': {'type': 'integer', 'default': 25}, 'beam_thickness_mm': {'type': 'number', 'default': 4.0}, 'containment_level': {'enum': ['N2', 'H1', 'H2', 'H4a'], 'type': 'string', 'default': 'N2', 'description': 'BS EN 1317-2 containment level. The vehicle mass + speed test\nclass the barrier has been demonstrated to contain. UK practice\ntypically specifies one of:\n\nN2  â\x80\x94 Normal containment (passenger car, 1500kg @ 110km/h)\nH1  â\x80\x94 Higher containment 1 (rigid heavy vehicle, 10000kg @ 70km/h)\nH2  â\x80\x94 Higher containment 2 (single-deck bus, 13000kg @ 70km/h)\nH4a â\x80\x94 Highest containment (rigid lorry, 30000kg @ 65km/h)'}, 'existing_asset_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'terminals_per_run': {'type': 'integer', 'default': 2}, 'foundation_depth_m': {'type': 'number', 'default': 0.6}, 'foundation_width_m': {'type': 'number', 'default': 0.9}, 'working_width_class': {'enum': ['W1', 'W2', 'W4', 'W6'], 'type': 'string', 'default': 'W4', 'description': 'BS EN 1317-2 working width class. The maximum lateral\ndisplacement of the barrier under design impact, measured in metres.\nUK practice typically specifies one of these four classes:\n\nW1  â\x80\x94 â\x89¤ 0.6m  (minimum footprint, concrete VRS only)\nW2  â\x80\x94 â\x89¤ 0.8m  (concrete VRS, untensioned corrugated, narrow median)\nW4  â\x80\x94 â\x89¤ 1.3m  (tensioned corrugated beam typical)\nW6  â\x80\x94 â\x89¤ 2.1m  (wire rope typical)'}, 'precast_unit_length_m': {'type': 'number', 'default': 6.0}, 'reinforcement_kg_per_m': {'type': 'number', 'default': 85.0}, 'concrete_cross_section_m2': {'type': 'number', 'default': 0.45}}, 'description': "Parameters for a single vehicle restraint system run.\n\nGeometry interpretation:\n  - ``length_m`` is the run length along the highway alignment.\n  - ``post_spacing_m`` is the centre-to-centre spacing of supporting\n    steel posts (irrelevant for INSITU and PRECAST_SLAB foundation\n    types). Typical UK values: 2.0m (TCB), 4.0m (TCB W6 variant),\n    3.2m (wire rope), 1.5m (high-containment hybrid).\n  - ``terminals_per_run`` is typically 2 (one at each end of a\n    continuous run); can be 1 for a barrier that returns into a\n    structure at one end.\n  - ``transitions`` is the number of system-type transitions\n    within the run (e.g. to a parapet or to a different VRS type).\n    Zero is normal for a single-system run.\n\nSystem-type-specific attributes (set only those relevant to the\nvariant's ``vrs_system_type``):\n  - ``beam_thickness_mm`` â\x80\x94 corrugated-beam variants only.\n  - ``wire_strands`` / ``wire_tension_kn`` â\x80\x94 wire rope only.\n  - ``concrete_grade`` / ``concrete_cross_section_m2`` /\n    ``reinforcement_kg_per_m`` â\x80\x94 concrete variants only.\n  - ``foundation_width_m`` / ``foundation_depth_m`` â\x80\x94 INSITU_FOUND\n    foundation only.\n  - ``precast_unit_length_m`` â\x80\x94 precast variants only."}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'MMHW'}, 'output_mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup', 'full_json'], 'type': 'string', 'default': 'full_json'}, 'deliverables': {'anyOf': [{'type': 'array', 'items': {'enum': ['xlsx', 'dxf', 'pdf'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
get_document_pipeline
Get the customer-side document pipeline
Obtain the CivilQuants customer-side document pipeline — the toolkit the document-heavy skills (tender review, geotechnical / geo-environmental interpretation) use to chunk a tender pack and render a Word pack on the user's machine. Returns the self-unpacking chunking package, the pipeline discipline, and the python-docx render helpers. Universal (free + paid). NOTE: running the pipeline over real documents requires a code-execution client (Claude Code / Codex / VS Code) — a chat connector can read the toolkit but cannot execute it. The full kit is large (~60 KB); pass component='chunking'|'discipline'|'render' for one part (~20 KB each), or omit it for the whole kit.
Solo lectura
Esquema de entrada
{'type': 'object', 'properties': {'component': {'enum': ['all', 'chunking', 'discipline', 'render'], 'type': 'string', 'default': 'all', 'description': 'Which part to fetch; omit for the whole kit.'}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'type': 'string'}}, 'x-fastmcp-wrap-result': True}
get_project
Get project
Fetch a previously saved CivilQuants project by project_id. When the id is not in context (e.g. a new conversation reopening 'Demo - Cantilever Wall'), pass the project's exact display name in the project_id field instead. If several projects share the name, the error envelope lists the candidate project_ids; call list_projects to browse everything saved. Paid tier only — anonymous callers receive a TIER_INSUFFICIENT envelope.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['project_id'], 'properties': {'project_id': {'type': 'string'}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['project_id', 'name', 'client', 'project_number', 'location', 'description', 'status', 'default_standard', 'currency', 'assemblies'], 'properties': {'name': {'type': 'string'}, 'client': {'type': 'string'}, 'status': {'type': 'string'}, 'currency': {'type': 'string'}, 'location': {'type': 'string'}, 'assemblies': {'type': 'array', 'items': {'type': 'object', 'required': ['id', 'slug', 'label', 'position', 'parameters', 'notes', 'enabled'], 'properties': {'id': {'type': 'string'}, 'slug': {'type': 'string'}, 'label': {'type': 'string'}, 'notes': {'type': 'string'}, 'enabled': {'type': 'boolean'}, 'position': {'type': 'integer'}, 'parameters': {'type': 'object', 'additionalProperties': True}}, 'description': 'Single assembly row inside a fetched project payload.', 'additionalProperties': False}}, 'project_id': {'type': 'string'}, 'description': {'type': 'string'}, 'project_number': {'type': 'string'}, 'default_standard': {'type': 'string'}}, 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
get_skill
Get senior-QS skill methodology
Paid tier only. Fetch a senior-QS skill methodology by slug (see list_skills) and APPLY it to the user's documents — the returned body is the system instruction for you to run the methodology on the customer's tokens; CivilQuants does not run inference. Paid callers get the full methodology; anonymous/free callers get a TIER_INSUFFICIENT upsell body; a rejected token gets an INVALID_TOKEN re-authenticate body. The document-heavy skills assume you can chunk/parse the customer's files and render a Word pack locally — that needs a code-execution client (Claude Code / Codex / VS Code) and the pack from get_document_pipeline; on a chat connector you can still read and reason with the methodology. Sign up at https://civilquants.com/pricing. Example: get_skill(skill="tender_risk_assessment").
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['skill'], 'properties': {'skill': {'type': 'string', 'maxLength': 64, 'description': 'Skill slug from list_skills.'}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'type': 'string'}}, 'x-fastmcp-wrap-result': True}
list_projects
List projects
List every project saved by the calling subscriber — project_id, name, client, status, default standard, assembly count, timestamps. Use this to re-find a saved project from a new conversation when its project_id is no longer in context, then pass the project_id to get_project or recompute_project. Paid tier only — anonymous callers receive a TIER_INSUFFICIENT envelope.
Solo lectura
Esquema de entrada
{'type': 'object', 'properties': {}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['projects'], 'properties': {'projects': {'type': 'array', 'items': {'type': 'object', 'required': ['project_id', 'name', 'client', 'project_number', 'status', 'default_standard', 'currency', 'assembly_count', 'created_at', 'updated_at'], 'properties': {'name': {'type': 'string'}, 'client': {'type': 'string'}, 'status': {'type': 'string'}, 'currency': {'type': 'string'}, 'created_at': {'type': 'string'}, 'project_id': {'type': 'string'}, 'updated_at': {'type': 'string'}, 'assembly_count': {'type': 'integer'}, 'project_number': {'type': 'string'}, 'default_standard': {'type': 'string'}}, 'description': 'One row inside the ``GET /api/v1/mcp/projects`` list response. Narrowed\nshape â\x80\x94 no parameters, no assembly details â\x80\x94 keeps the list endpoint\ncheap to serialise even when an owner has many projects.', 'additionalProperties': False}}}, 'description': 'Response payload for ``GET /api/v1/mcp/projects``.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
list_skills
List senior-QS skills
List the 10 senior-QS skill methodologies CivilQuants exposes (tender review, risk assessment, QS measurement/contract advice, geotechnical + geo-environmental interpretation, earthworks, preliminaries, pavement design, subcontract analysis). Universal discovery — both tiers see the full list. Returns each skill's slug, title, one-line summary and tier; then call get_skill(skill=<slug>) to fetch the methodology body. The skills are paid-tier; a free caller gets a sign-up prompt from get_skill. NOTE: the document-heavy skills (tender review, the interpretation skills) need a code-execution client (Claude Code / Codex / VS Code) plus the chunking pack from get_document_pipeline to run a real tender pack — on a chat connector you can read the methodology but cannot chunk/parse files.
Solo lectura
Esquema de entrada
{'type': 'object', 'properties': {}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'title', 'summary'], 'properties': {'slug': {'type': 'string', 'minLength': 1, 'description': 'Pass this to get_skill.'}, 'tier': {'type': 'string', 'const': 'paid', 'default': 'paid'}, 'title': {'type': 'string', 'minLength': 1}, 'summary': {'type': 'string', 'minLength': 1}}, 'description': 'One row of the skill catalogue surfaced by ``list_skills``.', 'additionalProperties': False}}}, 'x-fastmcp-wrap-result': True}
recompute_project
Recompute project
Re-run every enabled assembly in a saved project and render aggregated BoQs across the requested measurement standards. recompute_project takes no parameter overrides — it re-runs the saved assemblies exactly as stored. To revise a parameter, save an amended copy with save_project (see its description for the recipe) and recompute the new project_id. Paid tier only — anonymous callers receive a TIER_INSUFFICIENT envelope.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['project_id'], 'properties': {'request': {'anyOf': [{'type': 'object', 'properties': {'standard_codes': {'anyOf': [{'type': 'array', 'items': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Body for ``POST /api/v1/mcp/project/{id}/recompute``. Empty body is allowed â\x80\x94\nomits the standards filter and renders against all four.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'project_id': {'type': 'string'}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['project_id', 'standards_rendered', 'assembly_count', 'work_item_count', 'boqs_by_standard', 'procurement_summary', 'assembly_drawings'], 'properties': {'project_id': {'type': 'string'}, 'assembly_count': {'type': 'integer'}, 'work_item_count': {'type': 'integer'}, 'boqs_by_standard': {'type': 'object', 'additionalProperties': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'description', 'unit', 'quantity'], 'properties': {'code': {'type': 'string'}, 'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string'}, 'group': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'sub_group': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'description': {'type': 'string'}, 'nrm1_element': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'nrm1_sub_element': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'nrm1_group_element': {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'default': None}}, 'description': "Slim BoQ row for the recompute response. Matches the engine's own\n``BoQItem`` columns; rate / amount stay null per the freemium-MCP\npricing-is-yours discipline (schema § 1.3).", 'additionalProperties': False}}}, 'assembly_drawings': {'type': 'array', 'items': {'type': 'object', 'required': ['assembly_id', 'slug', 'label', 'position'], 'properties': {'slug': {'type': 'string'}, 'label': {'type': 'string'}, 'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1, 'description': 'Base64-encoded SVG document'}, 'viewbox_x': {'type': 'number', 'description': 'SVG viewBox x in engine units (m)'}, 'viewbox_y': {'type': 'number', 'description': 'SVG viewBox y in engine units (m)'}, 'entity_count': {'type': 'integer', 'minimum': 0, 'description': 'Number of DrawEntities rendered'}, 'viewbox_width': {'type': 'number', 'description': 'SVG viewBox width in engine units (m)', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'description': 'SVG viewBox height in engine units (m)', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm', 'description': 'Engine geometry is in metres. Surfaced here so the client never has to guess; if a future engine switches to mm this becomes the discriminator.'}}, 'description': 'Server-rendered SVG preview of the assembly geometry.\n\nPer G.6.3 / STATUS.md decision 6 (2026-05-19): one source of\ngeometry (`DrawEntity` list emitted by `Assembly.compute`), two\noutput paths (this SVG for inline preview, the `GET .../dxf`\nendpoint for the real CAD download). The browser displays\n`svg_b64` decoded inline; `viewbox` drives client zoom/pan\ncontrols without re-parsing the SVG.\n\n`svg_b64` is base64 of a UTF-8 SVG document with one `<g\nclass="cq-layer cq-layer-<name>">` per layer. Styling defaults are\ninlined so the preview renders without an external stylesheet;\nfront-end CSS may override via the class names.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'position': {'type': 'integer'}, 'assembly_id': {'type': 'string'}}, 'description': "One enabled assembly's drawing payload for the project recompute\nresponse (G.4.4b Step 2).\n\nMirrors the per-assembly drawing surface from\n``POST /api/assemblies/{slug}/compute`` (same ``DrawingRef`` shape,\nsame SVG renderer via ``build_drawing_ref``) so the project view's\ncontact-sheet centre pane renders identically to the single-assembly\ncalculator preview. ``drawing`` is nullable to stay backward-\ncompatible with assemblies that don't emit ``draw_entities`` (older\nshape); the few assemblies emitting an empty list still get a tiny\nplaceholder SVG so the UI never has to special-case absence.", 'additionalProperties': False}}, 'standards_rendered': {'type': 'array', 'items': {'type': 'string'}}, 'procurement_summary': {'type': 'array', 'items': {'type': 'object', 'required': ['category', 'spec', 'quantity', 'unit', 'source_assemblies'], 'properties': {'spec': {'type': 'string'}, 'unit': {'type': 'string'}, 'category': {'type': 'string'}, 'quantity': {'type': 'number', 'minimum': 0}, 'source_assemblies': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "One row of the project's procurement summary (G.4.4b Step 1).\n\nThe procurement summary is the standard-agnostic material rollup keyed\non ``(category, spec, unit)`` â\x80\x94 distinct from ``boqs_by_standard`` (a\nmeasurement-standard projection) and identical across all four\nstandards by construction. Drives the right pane of\n``/workspace/[project_id]`` and the ``Procurement`` sheet of the\nproject XLSX (per launch spec § 3.4.2).", 'additionalProperties': False}}}, 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
render_skill_report
Render Bill of Quantities deliverable
Render previously-computed BoQ results into a deliverable (Excel workbook or Word report). Excel is free with watermark + sheet protection; Word is paid-tier only and returns a TIER_INSUFFICIENT envelope for anonymous callers. The wire shape matches POST /api/v1/mcp/render exactly.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['request'], 'properties': {'request': {'type': 'object', 'required': ['skill', 'compute_results'], 'properties': {'skill': {'type': 'string', 'description': "One of ['civilquants/qs_boq_export', 'civilquants/qs_boq_word_report']. Word skill ('civilquants/qs_boq_word_report') is paid-only; Excel skill is open to free callers with sheet protection + watermark."}, 'options': {'type': 'object', 'properties': {'standards': {'anyOf': [{'type': 'array', 'items': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}}, {'type': 'null'}], 'default': None, 'description': 'Subset of {CESMM4, NRM2, SMM7, MMHW} to render BoQ tabs for. Omit for every standard present in the compute_results.'}, 'include_backup_tabs': {'type': 'boolean', 'default': True, 'description': 'Per launch spec § 3.4.1b â\x80\x94 emit one Backup_<STD>_<NNN> sheet per BoQ row. Excel skill only.'}, 'include_procurement_summary': {'type': 'boolean', 'default': False, 'description': 'Per launch spec § 3.4.1c â\x80\x94 emit an aggregated Procurement_Summary sheet alongside the BoQ tabs. Excel skill only.'}}, 'description': 'Caller-tunable render options per launch spec § 3.4.1 a/b/c.', 'additionalProperties': False}, 'compute_results': {'type': 'array', 'items': {'type': 'object', 'required': ['assembly_slug', 'standard', 'parameters_used', 'boq_rows', 'totals_summary', 'text_summary'], 'properties': {'drawing': {'anyOf': [{'type': 'object', 'required': ['svg_b64', 'viewbox_x', 'viewbox_y', 'viewbox_width', 'viewbox_height', 'entity_count'], 'properties': {'svg_b64': {'type': 'string', 'minLength': 1}, 'viewbox_x': {'type': 'number'}, 'viewbox_y': {'type': 'number'}, 'entity_count': {'type': 'integer', 'minimum': 0}, 'viewbox_width': {'type': 'number', 'exclusiveMinimum': 0}, 'viewbox_height': {'type': 'number', 'exclusiveMinimum': 0}, 'unit_of_drawing': {'type': 'string', 'const': 'm', 'default': 'm'}}, 'description': "Schema § 1.6a â\x80\x94 inline server-rendered SVG preview of the geometry.\n\nThe MCP mirror of the web ``/compute`` response's ``drawing`` field\n(``api.schemas.compute.DrawingRef``): the same on-screen dimensioned\ndrawing both tiers see in the workspace, surfaced on the MCP compute\nresponse so a chat client can render it inline (60th-fire item C). This\nis the on-screen preview â\x80\x94 present on BOTH tiers per the free/paid\nboundary; the downloadable CAD artefacts (DXF / dimensioned PDF) remain\nthe paid differentiator via the export tools.\n\nDefined here rather than importing ``DrawingRef`` because the web\n``schemas`` package imports back into this module (``schemas.render``),\nso reusing it would create an import cycle â\x80\x94 the MCP wire contract keeps\nits own copy, the same pattern as ``BoQRow`` / ``DrawingReference``.", 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'boq_rows': {'type': 'array', 'items': {'type': 'object', 'required': ['work_section', 'description', 'quantity', 'unit', 'attribution'], 'properties': {'rate': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'unit': {'type': 'string', 'minLength': 1}, 'amount': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'audit_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'quantity': {'type': 'number', 'minimum': 0}, 'attribution': {'type': 'string', 'minLength': 1}, 'description': {'type': 'string', 'minLength': 1}, 'work_section': {'type': 'string', 'minLength': 1}}, 'description': "Schema § 1.3 â\x80\x94 a single bill row in the requested standard's format.\n\n`description` is the non-verbatim functional description per spec § 13.9 /\n§ 15 invariant â\x80\x94 NEVER reproduces a standard's verbatim clause text.\n`rate` / `amount` ship null because rates are commodity data the customer\nowns; the engine's job is the measurement, not the pricing.", 'additionalProperties': False}}, 'drawings': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['drawing_type', 'format', 'url', 'sheet_size', 'scale'], 'properties': {'url': {'type': 'string', 'minLength': 1}, 'scale': {'type': 'string', 'minLength': 1}, 'format': {'enum': ['DXF', 'PDF', 'SVG'], 'type': 'string'}, 'layers': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}, 'sheet_size': {'enum': ['A1', 'A2', 'A3', 'A4'], 'type': 'string'}, 'drawing_type': {'enum': ['section', 'plan', 'elevation', 'isometric', 'detail'], 'type': 'string'}}, 'description': 'Schema § 1.6 â\x80\x94 paid-tier drawing artefact pointer.\n\n`url` is an R2-signed URL; expiry is carried in `_meta.deliverables.expires_at`\non the envelope (not duplicated here). `layers` is DXF-only; PDF/SVG\ncallers omit it.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, 'warnings': {'type': 'array', 'items': {'type': 'object', 'required': ['code', 'severity', 'message'], 'properties': {'code': {'type': 'string', 'minLength': 1}, 'detail': {'type': 'object', 'additionalProperties': {'type': 'number'}}, 'message': {'type': 'string', 'minLength': 1}, 'severity': {'enum': ['info', 'advisory', 'caution'], 'type': 'string'}, 'affected_params': {'type': 'array', 'items': {'type': 'string'}}}, 'description': "Schema § 1.8 â\x80\x94 a non-fatal geometry advisory (56th-fire T2).\n\nThe wire projection of the engine's `core.GeometryWarning`. Advisory only:\na warning NEVER changes a measured quantity â\x80\x94 it flags geometry that is\nvalid but likely a mistake (e.g. a stale dependent-height default). Present\non BOTH tiers â\x80\x94 a correctness/safety signal, not a paid feature.", 'additionalProperties': False}}, 'audit_trail': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['id', 'boq_row_index', 'derivation'], 'properties': {'id': {'type': 'string', 'minLength': 1}, 'formula': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'derivation': {'type': 'string', 'minLength': 1}, 'boq_row_index': {'type': 'integer', 'minimum': 0}, 'parameters_referenced': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'Schema § 1.7 â\x80\x94 paid-tier audit-trail entry.\n\nOne entry per BoQ row; `boq_row_index` ties to the row position in\n`ComputeResult.boq_rows`. `derivation` is the human-readable formula\nwalk-through; `formula` is the optional formal expression.', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'text_summary': {'type': 'string', 'maxLength': 2000, 'minLength': 1}, 'assembly_slug': {'type': 'string', 'minLength': 1}, 'totals_summary': {'type': 'object', 'properties': {'entries': {'type': 'object', 'additionalProperties': {'type': 'object', 'required': ['quantity', 'unit'], 'properties': {'unit': {'type': 'string', 'minLength': 1}, 'quantity': {'type': 'number', 'minimum': 0}}, 'description': 'Schema § 1.4 â\x80\x94 single material/work-class total entry.', 'additionalProperties': False}}}, 'description': 'Schema § 1.4 â\x80\x94 totals_summary as a typed wrapper around the free-form dict.\n\nWire shape is a flat object (`{"concrete_m3": {...}, "rebar_t": {...}}`).\nWe model it as `RootModel`-equivalent via `model_config(extra="allow")`\n+ a single `__root__`-style `entries` dict. Pydantic v2 recommends\n`RootModel` for free-form roots; using a wrapper class keeps the import\nsurface uniform with the rest of this module.', 'additionalProperties': False}, 'parameters_used': {'type': 'object', 'properties': {'assumptions': {'type': 'array', 'items': {'type': 'string'}}, 'user_supplied': {'type': 'object', 'additionalProperties': True}, 'engine_defaults': {'type': 'object', 'additionalProperties': True}}, 'description': 'Schema § 1.2 â\x80\x94 the parameter snapshot the engine actually used.\n\nSplits user-supplied values from engine defaults so customers can see\nwhich numbers came from them and which the engine filled in. Every\ndefaulted parameter SHOULD have a corresponding entry in `assumptions`\nâ\x80\x94 the bridge layer enforces this when wrapping engine output.', 'additionalProperties': False}}, 'description': 'Schema § 1.1 â\x80\x94 the typed payload returned inside `MCPResponse[ComputeResult]`.\n\nFree-tier responses omit `drawings` (the downloadable CAD artefact\npointers â\x80\x94 the paid differentiator); the bridge enforces this. The\n`audit_trail` and the inline `drawing` preview are present on BOTH tiers\n(V1 ALIGN / 60th-fire D + C). `text_summary` is bounded to 2000 chars â\x80\x94\nkeeps the LLM-facing summary token-cheap and forces longer narrative into\nBoQ row descriptions where it belongs. `warnings` is the non-fatal\ngeometry advisory list (both tiers).', 'additionalProperties': False}, 'maxItems': 100, 'minItems': 1, 'description': 'Up to 100 ComputeResult entries per call â\x80\x94 comfortably above the 46-assembly v1 catalogue. Caps in-memory render at a sane ceiling to defend against denial-of-wallet from a compromised paid token.'}, 'personalisation': {'type': 'object', 'properties': {'client': {'anyOf': [{'type': 'string', 'maxLength': 200}, {'type': 'null'}], 'default': None}, 'co_brand': {'anyOf': [{'type': 'object', 'required': ['firm_name'], 'properties': {'logo_url': {'anyOf': [{'type': 'string', 'format': 'uri', 'minLength': 1}, {'type': 'null'}], 'default': None, 'description': 'Accepted for the v1 wire contract; logo embedding is deferred. Validated as an http(s) URL today so a future fetch never sees file:// / ftp:// / SSRF payloads.'}, 'firm_name': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'brand_color_hex': {'anyOf': [{'type': 'string', 'pattern': '^#?[0-9A-Fa-f]{6}$'}, {'type': 'null'}], 'default': None, 'description': 'Accepted for the v1 wire contract; theme swap is deferred to a follow-up.'}}, 'description': 'Optional customer dual-branding payload per launch spec § 3.4.0.', 'additionalProperties': False}, {'type': 'null'}], 'default': None, 'description': 'Customer dual-branding payload per launch spec § 3.4.0. Required when `branding_mode` is `customer` or `dual`; must be null when `branding_mode` is `unbranded`.'}, 'prepared_by': {'anyOf': [{'type': 'string', 'maxLength': 200}, {'type': 'null'}], 'default': None}, 'project_name': {'anyOf': [{'type': 'string', 'maxLength': 200}, {'type': 'null'}], 'default': None}, 'branding_mode': {'enum': ['unbranded', 'customer', 'dual'], 'type': 'string', 'default': 'unbranded', 'description': 'Paid-tier branding mode per launch spec § 3.4.0. `unbranded` (default) = clean white. `customer` = customer firm only, CQ stripped. `dual` = customer + CQ side-by-side. Free-tier callers have this field ignored; their output is always CQ-branded + locked + watermarked.'}}, 'description': 'Personalisation injected on the cover sheet per schema § 4.3.', 'additionalProperties': False}}, 'description': 'Wire shape for POST /api/v1/mcp/render.', 'additionalProperties': False}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['watermark_state', 'byte_size', 'skill'], 'properties': {'skill': {'type': 'string', 'description': 'Echoes the resolved skill slug.'}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': 'Reserved for a future PDF skill backend.'}, 'docx_b64': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': 'Base64-encoded .docx document bytes (Word skill, local store mode only).'}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': 'Pre-signed R2 GET URL for .docx (Word skill, R2 store mode).'}, 'xlsx_b64': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': 'Base64-encoded .xlsx workbook bytes (Excel skill, local store mode only).'}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None, 'description': 'Pre-signed R2 GET URL for .xlsx (Excel skill, R2 store mode).'}, 'byte_size': {'type': 'integer', 'minimum': 0, 'description': 'Decoded size of whichever deliverable was rendered.'}, 'watermark_state': {'enum': ['free', 'none'], 'type': 'string', 'description': '`free` when the free-tier sheet protection + watermark is applied; `none` for paid output.'}}, 'description': 'Wire response shape â\x80\x94 schema § 4 RenderResult.\n\nPer Phase 3.4 A.3: each skill has TWO possible delivery modes that\nmap to ``CIVILQUANTS_ARTEFACT_STORE``:\n  * ``local`` (dev default) â\x80\x94 base64-inline in ``xlsx_b64`` / ``docx_b64``\n  * ``r2`` (production) â\x80\x94 pre-signed URL in ``xlsx_url`` / ``docx_url``\nThe validator enforces "exactly one delivery channel per skill" â\x80\x94 a\nsingle render call returns exactly one of {b64, url} for its target\nformat, never both. The other skill\'s fields stay null.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
resolve_assembly_from_description
Resolve assembly from description
Resolve a plain-English job description to candidate catalogue assemblies and the fields you'll need to compute one. Deterministic router — it does NOT return a Bill of Quantities and NEVER guesses parameter values; it returns candidate slugs (plural when ambiguous, with clarifying questions), each assembly's tier, whether it supports compute_multi_section_assembly, and per-field metadata (unit, min/max, default). Then call compute_<slug> (or compute_multi_section_assembly) with the values you fill in. Also known as compute_from_description. Example: {"description":"a 3 m deep manhole","preferred_standard":"MMHW"}.
Solo lectura
Esquema de entrada
{'type': 'object', 'required': ['description'], 'properties': {'description': {'type': 'string'}, 'preferred_standard': {'anyOf': [{'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, {'type': 'null'}], 'default': None}, 'return_resolution_log': {'type': 'boolean', 'default': False}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['query', 'confidence'], 'properties': {'query': {'type': 'string'}, 'questions': {'type': 'array', 'items': {'type': 'string'}}, 'candidates': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'display_name', 'tier', 'category_l1', 'category_l2', 'compute_tool'], 'properties': {'slug': {'type': 'string', 'minLength': 1}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'fields': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'label', 'default', 'group'], 'properties': {'max': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'min': {'anyOf': [{'type': 'number'}, {'type': 'null'}], 'default': None}, 'name': {'type': 'string', 'minLength': 1}, 'unit': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'group': {'type': 'string', 'minLength': 1}, 'label': {'type': 'string', 'minLength': 1}, 'default': {'anyOf': [{'type': 'number'}, {'type': 'integer'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'null'}]}, 'help_text': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'load_bearing': {'type': 'boolean', 'default': False}, 'is_run_length': {'type': 'boolean', 'default': False}}, 'description': 'One Parameters field, with the metadata a caller fills a value from.', 'additionalProperties': False}}, 'category_l1': {'type': 'string'}, 'category_l2': {'type': 'string'}, 'compute_tool': {'type': 'string', 'minLength': 1}, 'display_name': {'type': 'string', 'minLength': 1}, 'standard_note': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'free_alternative': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'suggested_params': {'type': 'array', 'items': {'type': 'object', 'required': ['name', 'value', 'source'], 'properties': {'name': {'type': 'string', 'minLength': 1}, 'unit': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'value': {'type': 'number'}, 'source': {'type': 'string', 'minLength': 1}}, 'description': 'A value the description stated with a clear anchor â\x80\x94 a caller-confirmed\nsuggestion, NOT an authoritative value and never auto-fed to compute.', 'additionalProperties': False}}, 'multi_section_tool': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'supports_multi_section': {'type': 'boolean', 'default': False}}, 'description': 'A candidate assembly the description routed to.', 'additionalProperties': False}}, 'confidence': {'enum': ['high', 'medium', 'low'], 'type': 'string'}, 'resolution_log': {'anyOf': [{'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'score'], 'properties': {'slug': {'type': 'string'}, 'score': {'type': 'number'}, 'matched_terms': {'type': 'array', 'items': {'type': 'string'}}}, 'description': 'One row of the optional resolution log (return_resolution_log).', 'additionalProperties': False}}, {'type': 'null'}], 'default': None}, 'preferred_standard': {'anyOf': [{'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string'}, {'type': 'null'}], 'default': None}}, 'description': 'The typed payload wrapped in MCPResponse[ResolveResult].', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
save_project
Save project
Persist a CivilQuants project with its assembly list. Each call creates a new project — it never overwrites an existing one. To revise a saved project's parameters: call get_project to recover its assemblies, amend the values, then call save_project again with the amended list (a revision-suffixed name like 'Pump Station R02' keeps the history browsable) and run recompute_project on the new project_id — recompute_project takes no parameter overrides. To measure a different assembly type instead, route via resolve_assembly_from_description. Re-find saved work in a later conversation with list_projects or get_project by exact name. Paid tier only — anonymous callers receive a TIER_INSUFFICIENT envelope pointing at https://civilquants.com/pricing.
Esquema de entrada
{'type': 'object', 'required': ['request'], 'properties': {'request': {'type': 'object', 'required': ['name'], 'properties': {'name': {'type': 'string', 'maxLength': 200, 'minLength': 1}, 'client': {'type': 'string', 'default': '', 'maxLength': 200}, 'currency': {'type': 'string', 'default': 'GBP', 'maxLength': 3, 'minLength': 3}, 'location': {'type': 'string', 'default': '', 'maxLength': 300}, 'assemblies': {'type': 'array', 'items': {'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'minLength': 1}, 'label': {'type': 'string', 'default': ''}, 'notes': {'type': 'string', 'default': ''}, 'parameters': {'type': 'object', 'additionalProperties': True}}, 'description': 'One assembly entry inside a project save request.', 'additionalProperties': False}}, 'description': {'type': 'string', 'default': ''}, 'project_number': {'type': 'string', 'default': '', 'maxLength': 60}, 'default_standard': {'enum': ['CESMM4', 'NRM2', 'SMM7', 'MMHW'], 'type': 'string', 'default': 'CESMM4'}}, 'description': 'Body for ``POST /api/v1/mcp/project/save``.', 'additionalProperties': False}}, 'additionalProperties': False}
Esquema de salida
{'type': 'object', 'required': ['result'], 'properties': {'result': {'anyOf': [{'type': 'object', 'required': ['_meta'], 'properties': {'data': {'anyOf': [{'type': 'object', 'required': ['project_id', 'assembly_ids'], 'properties': {'project_id': {'type': 'string'}, 'assembly_ids': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': False}, {'type': 'null'}], 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}, {'type': 'object', 'required': ['_meta'], 'properties': {'data': {'title': 'Data', 'default': None}, '_meta': {'type': 'object', 'required': ['request_id', 'issued_at', 'tier'], 'properties': {'hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'tier': {'enum': ['free', 'paid'], 'type': 'string'}, 'tos_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'issued_at': {'type': 'string', 'minLength': 1}, 'request_id': {'type': 'string', 'minLength': 1}, 'document_id': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'output_mode': {'anyOf': [{'type': 'object', 'required': ['mode', 'omitted_fields', 'retrieve_with'], 'properties': {'mode': {'enum': ['summary', 'material_schedule', 'boq', 'boq_with_backup'], 'type': 'string'}, 'retrieve_with': {'type': 'string', 'minLength': 1}, 'omitted_fields': {'type': 'array', 'items': {'type': 'string'}, 'minItems': 1}}, 'description': 'Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as "capability missing" (the box-culvert "geometry\nbuilder isn\'t firing" scare) rather than "pared for size": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) â\x80\x94 both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\nâ\x80\x94 nothing is withheld, nothing to point at.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'deliverables': {'anyOf': [{'type': 'object', 'required': ['expires_at'], 'properties': {'dxf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'pdf_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'docx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'xlsx_url': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'expires_at': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.3 â\x80\x94 R2 signed URLs (24h TTL).', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'tier_upgrade': {'anyOf': [{'type': 'object', 'required': ['available_tiers'], 'properties': {'pass_credit': {'anyOf': [{'type': 'object', 'required': ['amount_local', 'currency', 'redeemable_until'], 'properties': {'currency': {'type': 'string'}, 'applies_to': {'type': 'string', 'const': 'solo_first_month', 'default': 'solo_first_month'}, 'amount_local': {'type': 'number'}, 'redeemable_until': {'type': 'string'}}, 'description': 'Canonical schema § 0.7 â\x80\x94 pass-credit upgrade hook.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'pricing_url': {'type': 'string', 'default': 'https://civilquants.com/pricing'}, 'current_tier': {'type': 'string', 'const': 'free', 'default': 'free'}, 'available_tiers': {'type': 'array', 'items': {'type': 'object', 'required': ['tier_slug', 'display_name', 'price_local', 'currency', 'billing', 'unlock_summary'], 'properties': {'billing': {'enum': ['one_off', 'monthly', 'annual'], 'type': 'string'}, 'currency': {'enum': ['GBP', 'SGD', 'EUR', 'USD', 'CAD', 'AUD', 'NZD', 'MYR'], 'type': 'string'}, 'tier_slug': {'enum': ['7_day_pass', 'solo', 'studio', 'practice'], 'type': 'string'}, 'price_local': {'type': 'number'}, 'display_name': {'type': 'string'}, 'unlock_summary': {'type': 'string', 'minLength': 1}}, 'description': 'Canonical schema § 0.7 â\x80\x94 single tier in the upgrade carousel.', 'additionalProperties': False}}}, 'description': 'Canonical schema § 0.7 â\x80\x94 present on free-tier responses only.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'upgrade_hint': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'schema_version': {'type': 'string', 'const': '1.0.0', 'default': '1.0.0'}, 'scope_boundary': {'anyOf': [{'type': 'object', 'required': ['produced', 'not_in_scope'], 'properties': {'produced': {'type': 'array', 'items': {'type': 'string'}}, 'not_in_scope': {'type': 'array', 'items': {'type': 'string'}}, 'recommended_companions': {'anyOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.6 â\x80\x94 surfaces what this assembly produces vs not.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}, 'warranty_disclaimer': {'anyOf': [{'type': 'string'}, {'type': 'null'}], 'default': None}, 'rate_limit_remaining': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.2 â\x80\x94 present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == "free"`; absent on paid-tier responses.', 'additionalProperties': False}, 'error': {'anyOf': [{'type': 'object', 'required': ['code', 'message', 'recoverable'], 'properties': {'code': {'enum': ['RATE_LIMIT_EXCEEDED', 'TIER_INSUFFICIENT', 'INVALID_INPUT', 'SCHEMA_VERSION_MISMATCH', 'SCHEMA_INVARIANT_VIOLATION', 'UPSTREAM_TIMEOUT', 'BACKEND_FAILURE', 'IP_BLOCKED', 'RESOURCE_NOT_FOUND', 'RENDER_FAILURE', 'OCR_LOW_CONFIDENCE', 'MANUAL_REVIEW_REQUIRED', 'ACCEPTANCE_REQUIRED', 'INVALID_TOKEN'], 'type': 'string', 'description': 'Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) â\x80\x94 clients use the flag to decide retry vs surface.'}, 'details': {'anyOf': [{'type': 'object', 'additionalProperties': True}, {'type': 'null'}], 'default': None}, 'message': {'type': 'string', 'minLength': 1}, 'recoverable': {'type': 'boolean'}, 'retry_after_seconds': {'anyOf': [{'type': 'integer', 'minimum': 0}, {'type': 'null'}], 'default': None}}, 'description': 'Canonical schema § 0.4 â\x80\x94 error payload returned in `MCPResponse.error`.', 'additionalProperties': False}, {'type': 'null'}], 'default': None}}, 'additionalProperties': False}]}}, 'x-fastmcp-wrap-result': True}
Añadido
get_document_pipeline
17 de September de 2026 a las 12:34
Añadido
get_skill
17 de September de 2026 a las 12:34
Añadido
list_skills
17 de September de 2026 a las 12:34
Añadido
resolve_assembly_from_description
17 de September de 2026 a las 12:34
Añadido
compute_multi_section_assembly
17 de September de 2026 a las 12:34
Añadido
recompute_project
17 de September de 2026 a las 12:34
Añadido
list_projects
17 de September de 2026 a las 12:34
Añadido
get_project
17 de September de 2026 a las 12:34
Añadido
save_project
17 de September de 2026 a las 12:34
Añadido
render_skill_report
17 de September de 2026 a las 12:34
Añadido
compute_single_service_run
17 de September de 2026 a las 12:34
Añadido
compute_combined_services_trench
17 de September de 2026 a las 12:34
Añadido
compute_utility_kiosk_base
17 de September de 2026 a las 12:34
Añadido
compute_utility_chamber
17 de September de 2026 a las 12:34
Añadido
compute_strip_foundation
17 de September de 2026 a las 12:34
Añadido
compute_pad_foundation
17 de September de 2026 a las 12:34
Añadido
compute_kerb_run
17 de September de 2026 a las 12:34
Añadido
compute_gravity_wall
17 de September de 2026 a las 12:34
Añadido
compute_counterfort_wall
17 de September de 2026 a las 12:34
Añadido
compute_cantilever_wall
17 de September de 2026 a las 12:34
Añadido
compute_bored_pile_wall
17 de September de 2026 a las 12:34
Añadido
compute_anchored_wall
17 de September de 2026 a las 12:34
Añadido
compute_rigid_pavement
17 de September de 2026 a las 12:34
Añadido
compute_permeable_pavement
17 de September de 2026 a las 12:34
Añadido
compute_flexible_pavement
17 de September de 2026 a las 12:34
Añadido
compute_traffic_sign
17 de September de 2026 a las 12:34
Añadido
compute_road_marking
17 de September de 2026 a las 12:34
Añadido
compute_vehicle_restraint_system
17 de September de 2026 a las 12:34
Añadido
compute_lighting_column
17 de September de 2026 a las 12:34
Añadido
compute_highway_drainage_channel
17 de September de 2026 a las 12:34