Skip to content

MCP Tools Reference

Complete schema and response format documentation for ucon MCP server tools.


convert

Convert a numeric value from one unit to another.

Parameters

Name Type Required Description
value float Yes The numeric quantity to convert
from_unit string Yes Source unit string
to_unit string Yes Target unit string
custom_units list[dict] No Inline unit definitions
custom_edges list[dict] No Inline conversion edges
kind string No Kind-of-quantity name to annotate the measurement (e.g. "absorbed_dose"). Must exist in the kind lattice and match the source unit's dimension; preserved through conversion and surfaced on the result

Response Schema

Success: ConversionResult

{
  "quantity": 3.107,
  "unit": "mi",
  "dimension": "length",
  "kind": null,
  "uncertainty": null
}

Error: ConversionError

{
  "error": "Dimension mismatch: mass is not length",
  "error_type": "dimension_mismatch",
  "parameter": "to_unit",
  "likely_fix": "Use a mass unit like 'lb' or 'g'"
}

Examples

# Simple conversion
convert(value=5, from_unit="km", to_unit="mi")
# → {"quantity": 3.107, "unit": "mi", "dimension": "length"}

# Composite units
convert(value=10, from_unit="m/s", to_unit="km/h")
# → {"quantity": 36.0, "unit": "km/h", "dimension": "velocity"}

# Kind-annotated conversion
convert(value=2, from_unit="Gy", to_unit="mGy", kind="absorbed_dose")
# → {"quantity": 2000.0, "unit": "mGy", "dimension": "specific_energy", "kind": "absorbed_dose"}

# With inline custom unit
convert(
    value=1,
    from_unit="slug",
    to_unit="kg",
    custom_units=[{"name": "slug", "dimension": "mass", "aliases": ["slug"]}],
    custom_edges=[{"src": "slug", "dst": "kg", "factor": 14.5939}]
)
# → {"quantity": 14.5939, "unit": "kg", "dimension": "mass"}

decompose

Build a factor chain for compute() by analyzing dimensional requirements.

Operates in two modes: query mode for simple conversions, and structured mode for multi-step problems where known quantities bridge dimensional gaps.

Parameters

Name Type Required Description
query string No Simple conversion query (e.g., "500 mL to L", "50 psi to kPa")
initial_unit string No Starting unit string (use with target_unit)
target_unit string No Target unit string (use with initial_unit)
known_quantities list[dict] No Quantities to incorporate into the factor chain

Must provide either query or both initial_unit and target_unit.

Known quantity dict schema:

Field Type Description
value float Numeric value (e.g., 70)
unit string Unit string (e.g., "kg")

Response Schema

Success: DecomposeResult

{
  "initial_value": 500,
  "initial_unit": "mL",
  "target_unit": "L",
  "factors": [
    {"value": 0.001, "numerator": "L", "denominator": "mL"}
  ]
}

initial_value is extracted from the query string (if present) or null for structured mode. The factors list can be passed directly to compute().

Error: ConversionError

{
  "error": "Cannot bridge dimensional gap from 'mcg/(kg*min)' to 'mg/h'",
  "error_type": "dimension_mismatch",
  "parameter": "known_quantities",
  "hints": [
    "Need to add 'mass' (exponent 1) - provide a quantity with this dimension",
    "Add more known_quantities to bridge the gap"
  ]
}

Examples

# Query mode: simple conversion
decompose(query="500 mL to L")
# → {"initial_value": 500, "initial_unit": "mL", "target_unit": "L", "factors": [...]}

# Query mode: composite units
decompose(query="60 mph to km/h")
# → {"initial_value": 60, "initial_unit": "mph", "target_unit": "km/h", "factors": [...]}

# Structured mode: weight-based dosing
# Problem: "5 mcg/kg/min for a 70 kg patient. Rate in mg/h?"
decompose(
    initial_unit="mcg/(kg*min)",
    target_unit="mg/h",
    known_quantities=[{"value": 70, "unit": "kg"}]
)
# → factors for kg cancellation, min→h, mcg→mg

# Structured mode: IV drip rate
# Problem: "1000 mL over 8 hours, 15 gtt/mL tubing. Rate in gtt/min?"
decompose(
    initial_unit="mL",
    target_unit="gtt/min",
    known_quantities=[
        {"value": 8, "unit": "h"},
        {"value": 15, "unit": "gtt/mL"}
    ]
)

# Structured mode: concentration-based infusion
# Problem: "Dopamine 5 mcg/kg/min for 80 kg patient. Drug is 400 mg in 250 mL. mL/h?"
decompose(
    initial_unit="mcg/(kg*min)",
    target_unit="mL/h",
    known_quantities=[
        {"value": 80, "unit": "kg"},
        {"value": 250, "unit": "mL"},
        {"value": 400, "unit": "mg"},
    ],
)
# → 400 mg placed in denominator (constraint solver), plus mcg→mg and min→h
#   bridging factors (auto-bridged). compute(initial_value=5, factors=...) == 15.0 mL/h

# Structured mode: dosing with count rate
# Problem: "25 mg/kg/day for 15 kg child, divided into 3 doses/day. mg per dose?"
# Note: express count as a rate (ea/d), not bare ea
decompose(
    initial_unit="mg/(kg*d)",
    target_unit="mg",
    known_quantities=[
        {"value": 15, "unit": "kg"},
        {"value": 3, "unit": "ea/d"},
    ],
)
# → compute(initial_value=25, factors=...) == 125.0 mg

# Chain with compute:
result = decompose(query="3 TB to GiB")
compute(
    initial_value=result.initial_value,
    initial_unit=result.initial_unit,
    factors=result.factors
)

compute

Perform multi-step factor-label calculations with dimensional tracking.

Parameters

Name Type Required Description
initial_value float Yes Starting numeric quantity
initial_unit string Yes Starting unit string
factors list[dict] Yes Conversion factor chain
custom_units list[dict] No Inline unit definitions
custom_edges list[dict] No Inline conversion edges

Factor dict schema:

Field Type Description
value float Numeric coefficient (default: 1.0)
numerator string Numerator unit string
denominator string Denominator unit string (may include numeric prefix)

Response Schema

Success: ComputeResult

{
  "quantity": 349.2,
  "unit": "mg/ea",
  "dimension": "mass/count",
  "steps": [
    {"factor": "154 lb", "dimension": "mass", "unit": "lb"},
    {"factor": "(1 kg / 2.205 lb)", "dimension": "mass", "unit": "kg"},
    {"factor": "(15 mg / kg*day)", "dimension": "mass/time", "unit": "mg/d"},
    {"factor": "(1 day / 3 ea)", "dimension": "mass/count", "unit": "mg/ea"}
  ]
}

Examples

# Weight-based dosing calculation
compute(
    initial_value=154,
    initial_unit="lb",
    factors=[
        {"value": 1, "numerator": "kg", "denominator": "2.205 lb"},
        {"value": 15, "numerator": "mg", "denominator": "kg*day"},
        {"value": 1, "numerator": "day", "denominator": "3 ea"},
    ]
)
# → {"quantity": 349.2, "unit": "mg/ea", "dimension": "mass/count", "steps": [...]}

# IV drip rate
compute(
    initial_value=1000,
    initial_unit="mL",
    factors=[
        {"value": 15, "numerator": "drop", "denominator": "mL"},
        {"value": 1, "numerator": "1", "denominator": "8 hr"},
        {"value": 1, "numerator": "hr", "denominator": "60 min"},
    ],
    custom_units=[{"name": "drop", "dimension": "count", "aliases": ["gtt"]}]
)
# → {"quantity": 31.25, "unit": "gtt/min", ...}

discover

Unified discovery across everything the session can see. Consolidates the eight list_* tools behind a single topic parameter; each topic's items carry the same entry schema as the corresponding legacy tool.

Parameters

Name Type Required Description
topic string Yes One of units, scales, dimensions, constants, formulas, quantity_kinds, kind_formulas, extended_bases
dimension string No Filter by dimension (topics: units, quantity_kinds)
category string No Filter by category (topics: constants, quantity_kinds)
include_builtin bool No Include built-in entries (topic: quantity_kinds; default true)

Filters that do not apply to the requested topic are rejected with error_type: "invalid_filter" rather than silently ignored.

Response Schema

Success: DiscoverResult

{
  "topic": "units",
  "count": 20,
  "filters": {"dimension": "length"},
  "items": [
    {"name": "angstrom", "shorthand": "Å", "aliases": ["Å", "angstroms"], "dimension": "length", "scalable": true}
  ]
}

Error: DiscoverError

{
  "error": "Filter 'dimension' does not apply to topic 'scales'",
  "error_type": "invalid_filter",
  "topic": "scales",
  "likely_fix": "Topics accepting 'dimension': quantity_kinds, units"
}

Typed errors from the underlying lookup (unknown dimension, unknown constant category) pass through unchanged as ConversionError / ConstantError.

Examples

# Units of a given dimension
discover(topic="units", dimension="length")
# → {"topic": "units", "count": 20, "filters": {"dimension": "length"}, "items": [...]}

# The 8 exact (SI defining) constants
discover(topic="constants", category="exact")
# → {"topic": "constants", "count": 8, ..., "items": [{"symbol": "Kcd", ...}, ...]}

# Session-defined quantity kinds only
discover(topic="quantity_kinds", include_builtin=False)

define

Define a session-scoped entity: a unit, a conversion edge, a constant, a quantity kind, or an extended dimensional basis. Consolidates the deprecated define_unit / define_conversion / define_constant / define_quantity_kind / extend_basis tools behind one kind-keyed surface. Definitions persist until reset_session().

Parameters

Name Type Required Description
kind "unit" | "conversion" | "constant" | "quantity_kind" | "basis" Yes What to define
name string kinds: unit, constant, quantity_kind, basis Entity name (constant: full descriptive name)
dimension string kinds: unit, quantity_kind Dimension name or expression
aliases list[string] No Alternative names (kinds: unit, quantity_kind)
scalable boolean No Whether SI prefixes attach (kind: unit; default true)
src, dst string kind: conversion Source/destination unit names
factor number kind: conversion Multiplier: dst = src × factor + offset
offset number No Affine offset (kind: conversion; default 0.0)
symbol string kind: constant Short symbol (e.g., "vₛ")
value number kind: constant Numeric value in the given unit
unit string kind: constant Unit string (e.g., "m/s")
uncertainty number No Standard uncertainty (kind: constant)
source string No Data source reference (kind: constant)
description string No Human-readable description (kind: quantity_kind)
category string No Classification (kind: quantity_kind; default "session")
disambiguation_hints list[string] No Distinguishing tips (kind: quantity_kind)
parent string No Parent kind in the hierarchy (kind: quantity_kind)
join_policy "lca" | "refuse" No Join behavior (kind: quantity_kind; default "lca")
base string No Starting basis (kind: basis; default "SI")
additional_components list[object] No New basis components with name/symbol/description (kind: basis)

Returns

The same result and error models as the corresponding legacy tool (UnitDefinitionResult, ConversionDefinitionResult, ConstantDefinitionResult, QuantityKindDefinitionResult, ExtendedBasisResult, and their typed errors). A DefineError for an unknown kind or missing required parameters:

{
  "error": "Missing required parameter(s) for kind 'conversion': factor",
  "error_type": "missing_parameter",
  "kind": "conversion",
  "likely_fix": "Example: define(kind=\"conversion\", src=\"slug\", dst=\"kg\", factor=14.5939)"
}

Examples

define(kind="unit", name="slug", dimension="mass", aliases=["slug"])
define(kind="conversion", src="slug", dst="kg", factor=14.5939)
define(kind="constant", symbol="vₛ", name="speed of sound", value=343, unit="m/s")
define(kind="quantity_kind", name="entropy_change", dimension="energy/temperature")
define(kind="basis", name="thermodynamic",
       additional_components=[{"name": "thermal", "symbol": "Φ", "description": "Thermal marker"}])

system

Inspect or restrict the active unit system. Consolidates the deprecated restrict_system / diff_systems / check_compatibility tools behind one action-keyed surface.

Parameters

Name Type Required Description
action "restrict" | "diff" | "check_compatibility" Yes What to do
dimensions list[string] No Dimension names to keep (action: restrict)
units list[string] No Unit names to keep (action: restrict)

Returns

The same dict payload as the corresponding legacy tool. An error dict for an unknown action:

{
  "error": "Unknown action: 'explode'",
  "error_type": "unknown_action",
  "likely_fix": "Valid actions: restrict, diff, check_compatibility"
}

Examples

system(action="restrict", dimensions=["length", "time"])
# → {"success": true, "dimensions": ["length", "time"], "unit_count": ..., ...}

system(action="diff")
# → {"success": true, "units": {"added": 0, ...}, "dimensions": {...}, ...}

system(action="check_compatibility")
# → {"compatible": true}

list_units

Deprecated: use discover(topic="units"). Scheduled for removal in v1.0.0.

List available units, optionally filtered by dimension.

Parameters

Name Type Required Description
dimension string No Filter by dimension name

Response Schema

Success: list[UnitInfo]

[
  {
    "name": "meter",
    "shorthand": "m",
    "aliases": ["m"],
    "dimension": "length",
    "scalable": true
  },
  {
    "name": "foot",
    "shorthand": "ft",
    "aliases": ["ft", "feet"],
    "dimension": "length",
    "scalable": false
  }
]

Examples

# List all units
list_units()

# Filter by dimension
list_units(dimension="mass")
# → [{"name": "gram", ...}, {"name": "kilogram", ...}, ...]

list_scales

Deprecated: use discover(topic="scales"). Scheduled for removal in v1.0.0.

List available scale prefixes.

Parameters

None.

Response Schema

Success: list[ScaleInfo]

[
  {"name": "peta", "prefix": "P", "factor": 1e15},
  {"name": "tera", "prefix": "T", "factor": 1e12},
  {"name": "giga", "prefix": "G", "factor": 1e9},
  {"name": "mega", "prefix": "M", "factor": 1e6},
  {"name": "kilo", "prefix": "k", "factor": 1000.0},
  {"name": "gibi", "prefix": "Gi", "factor": 1073741824.0},
  {"name": "mebi", "prefix": "Mi", "factor": 1048576.0},
  {"name": "kibi", "prefix": "Ki", "factor": 1024.0}
]

list_dimensions

Deprecated: use discover(topic="dimensions"). Scheduled for removal in v1.0.0.

List available physical dimensions.

Parameters

None.

Response Schema

Success: list[str]

[
  "acceleration", "amount_of_substance", "angle", "angular_momentum",
  "area", "capacitance", "catalytic_activity", "charge", "conductance",
  "conductivity", "count", "current", "density", "dynamic_viscosity",
  "electric_field_strength", "energy", "entropy", "force", "frequency",
  "gravitation", "illuminance", "inductance", "information",
  "kinematic_viscosity", "length", "luminous_intensity", "magnetic_flux",
  "magnetic_flux_density", "magnetic_permeability", "mass", "molar_mass",
  "molar_volume", "momentum", "none", "permittivity", "power", "pressure",
  "ratio", "resistance", "resistivity", "solid_angle",
  "specific_heat_capacity", "temperature", "thermal_conductivity", "time",
  "velocity", "voltage", "volume"
]

check_dimensions

Check if two units have compatible dimensions.

Parameters

Name Type Required Description
unit_a string Yes First unit string
unit_b string Yes Second unit string

Response Schema

Success: DimensionCheck

{
  "compatible": true,
  "dimension_a": "mass",
  "dimension_b": "mass"
}

Examples

# Compatible units
check_dimensions(unit_a="kg", unit_b="lb")
# → {"compatible": true, "dimension_a": "mass", "dimension_b": "mass"}

# Incompatible units
check_dimensions(unit_a="kg", unit_b="m")
# → {"compatible": false, "dimension_a": "mass", "dimension_b": "length"}

define_unit

Deprecated: use define(kind="unit"). Scheduled for removal in v1.0.0.

Register a custom unit for the session.

Parameters

Name Type Required Description
name string Yes Canonical unit name
dimension string Yes Dimension name (use list_dimensions())
aliases list[str] No Shorthand symbols

Response Schema

Success: UnitDefinitionResult

{
  "success": true,
  "name": "slug",
  "dimension": "mass",
  "aliases": ["slug"],
  "message": "Unit 'slug' registered for session. Use define_conversion() to add conversion edges."
}

Examples

define_unit(name="slug", dimension="mass", aliases=["slug"])
define_unit(name="nautical_mile", dimension="length", aliases=["nmi", "NM"])

define_conversion

Deprecated: use define(kind="conversion"). Scheduled for removal in v1.0.0.

Add a conversion edge between units.

Parameters

Name Type Required Description
src string Yes Source unit name/alias
dst string Yes Destination unit name/alias
factor float Yes Conversion multiplier: dst = src * factor

Response Schema

Success: ConversionDefinitionResult

{
  "success": true,
  "src": "slug",
  "dst": "kg",
  "factor": 14.5939,
  "message": "Conversion edge 'slug' -> 'kg' (factor=14.5939) added to session."
}

Examples

# After define_unit("slug", "mass", ["slug"])
define_conversion(src="slug", dst="kg", factor=14.5939)

# Now convert() can use the new unit
convert(value=1, from_unit="slug", to_unit="lb")

list_constants

Deprecated: use discover(topic="constants"). Scheduled for removal in v1.0.0.

List available physical constants, optionally filtered by category.

Parameters

Name Type Required Description
category string No Filter by category: "exact", "derived", "measured", "session", "all"

Response Schema

Success: list[ConstantInfo]

[
  {
    "symbol": "c",
    "name": "speed of light in vacuum",
    "value": 299792458,
    "unit": "m/s",
    "dimension": "velocity",
    "uncertainty": null,
    "is_exact": true,
    "source": "CODATA 2022",
    "category": "exact"
  },
  {
    "symbol": "G",
    "name": "Newtonian constant of gravitation",
    "value": 6.6743e-11,
    "unit": "m³/(kg·s²)",
    "dimension": "gravitation",
    "uncertainty": 1.5e-15,
    "is_exact": false,
    "source": "CODATA 2022",
    "category": "measured"
  }
]

Error: ConstantError

{
  "error": "Unknown category: 'invalid'",
  "error_type": "invalid_input",
  "parameter": "category",
  "hints": ["Valid categories: exact, derived, measured, session, all"]
}

Categories

Category Description Count
exact SI defining constants (2019 redefinition) 7
derived Derived from exact constants 3
measured Experimentally measured (with uncertainty) 7
session User-defined via define_constant() varies

Examples

# List all constants
list_constants()
# → [{"symbol": "c", ...}, {"symbol": "h", ...}, ...]

# Filter by category
list_constants(category="exact")
# → [{"symbol": "c", ...}, {"symbol": "h", ...}, ...] (7 exact constants)

# Session constants only
list_constants(category="session")
# → [] (empty until define_constant() is called)

define_constant

Deprecated: use define(kind="constant"). Scheduled for removal in v1.0.0.

Define a custom constant for the current session.

Parameters

Name Type Required Description
symbol string Yes Short symbol (e.g., "vₛ", "Eg")
name string Yes Full descriptive name
value float Yes Numeric value in given units
unit string Yes Unit string (e.g., "m/s", "J")
uncertainty float No Standard uncertainty (None for exact)
source string No Data source reference

Response Schema

Success: ConstantDefinitionResult

{
  "success": true,
  "symbol": "vₛ",
  "name": "speed of sound in dry air at 20°C",
  "unit": "m/s",
  "uncertainty": null,
  "message": "Constant 'vₛ' registered for session."
}

Error: ConstantError

{
  "error": "Symbol 'c' is already defined as 'speed of light in vacuum'",
  "error_type": "duplicate_symbol",
  "parameter": "symbol",
  "hints": ["Use a different symbol or use the built-in constant"]
}

Error Types

Error Type Description
duplicate_symbol Symbol exists in built-in or session constants
invalid_unit Unit string cannot be parsed
invalid_value Value is NaN, Inf, or non-numeric

Examples

# Define speed of sound
define_constant(
    symbol="vₛ",
    name="speed of sound in dry air at 20°C",
    value=343,
    unit="m/s"
)

# Define with uncertainty
define_constant(
    symbol="g_local",
    name="local gravitational acceleration",
    value=9.81,
    unit="m/s^2",
    uncertainty=0.01,
    source="measured on site"
)

# Now visible in session constants
list_constants(category="session")
# → [{"symbol": "vₛ", ...}, {"symbol": "g_local", ...}]

reset_session

Clear all custom units, conversions, and constants.

Parameters

None.

Response Schema

Success: SessionResult

{
  "success": true,
  "message": "Session reset. All custom units, conversions, and constants cleared."
}

list_formulas

Deprecated: use discover(topic="formulas"). Scheduled for removal in v1.0.0.

List registered domain formulas with their dimensional constraints.

Parameters

None.

Response Schema

Success: list[FormulaInfoResponse]

[
  {
    "name": "bmi",
    "description": "Body Mass Index",
    "parameters": {
      "mass": "mass",
      "height": "length"
    }
  }
]

Examples

list_formulas()
# → [{"name": "bmi", "description": "Body Mass Index", "parameters": {"mass": "mass", "height": "length"}}]

call_formula

Invoke a registered formula with dimensionally-validated inputs.

Parameters

Name Type Required Description
name string Yes Formula name (from list_formulas())
parameters dict[str, dict] Yes Parameter values (see format below)

Parameter value format:

{
  "mass": {"value": 70, "unit": "kg"},
  "height": {"value": 1.75, "unit": "m"},
  "factor": {"value": 2.5}
}
  • Use {"value": ..., "unit": "..."} for dimensioned quantities
  • Use {"value": ...} for dimensionless quantities

Response Schema

Success: FormulaResult

{
  "formula": "bmi",
  "quantity": 22.86,
  "unit": "kg/m²",
  "dimension": "derived(mass/length²)",
  "kind": null,
  "uncertainty": null
}

When formula arithmetic produces a kind-annotated Number (kind-aware inputs composing through a registered kind formula), kind carries the resulting kind name; otherwise it is null.

Error: FormulaError

{
  "error": "Missing required parameter: 'height'",
  "error_type": "missing_parameter",
  "formula": "bmi",
  "parameter": "height",
  "expected": "length",
  "hints": ["Parameter 'height' expects dimension: length"]
}

Error Types

Error Type Description
unknown_formula Formula name not found in registry
missing_parameter Required parameter not provided
invalid_parameter Parameter format incorrect or unit unknown
dimension_mismatch Parameter has wrong dimension
execution_error Formula raised an exception

Examples

# Call BMI formula
call_formula(
    name="bmi",
    parameters={
        "mass": {"value": 70, "unit": "kg"},
        "height": {"value": 1.75, "unit": "m"}
    }
)
# → {"formula": "bmi", "quantity": 22.86, "unit": "kg/m²", ...}

# Dimensionless parameter
call_formula(
    name="scale_value",
    parameters={
        "x": {"value": 10, "unit": "m"},
        "factor": {"value": 2.5}
    }
)
# → {"formula": "scale_value", "quantity": 25.0, "unit": "m", ...}

Registering Formulas

Formulas are registered in Python code using @register_formula:

from ucon import Number, Dimension, enforce_dimensions
from ucon.tools.mcp.formulas import register_formula

@register_formula("bmi", description="Body Mass Index")
@enforce_dimensions
def bmi(
    mass: Number[Dimension.mass],
    height: Number[Dimension.length],
) -> Number:
    return mass / (height * height)

The @enforce_dimensions decorator enables runtime dimension checking. Parameter constraints are extracted automatically and exposed via list_formulas().


Error Types

All tools may return ConversionError with these error types:

Error Type Description Example
unknown_unit Unit string not recognized "kilgoram" typo
dimension_mismatch Units have incompatible dimensions kg to m
no_conversion_path No edge path between units Custom unit without edge
invalid_input Malformed parameter Missing required field
computation_error Runtime calculation failure Division by zero

Error Response Schema

{
  "error": "Human-readable error message",
  "error_type": "unknown_unit",
  "parameter": "from_unit",
  "step": 2,
  "likely_fix": "Did you mean 'kilogram'?",
  "hints": ["Check spelling", "Use list_units() to see available units"]
}
Field Type Description
error string Human-readable message
error_type string Machine-readable error category
parameter string Which parameter caused the error
step int For compute(), which factor step failed (0-indexed)
likely_fix string Suggested correction (typos, dimension swaps)
hints list[str] Additional guidance

Kind-of-Quantity (KOQ) Tools

These tools disambiguate physically distinct quantities that share the same dimensional signature. For background, see Kind-of-Quantity.


define_quantity_kind

Deprecated: use define(kind="quantity_kind"). Scheduled for removal in v1.0.0.

Register a quantity kind for semantic disambiguation.

Parameters

Name Type Required Description
name string Yes Unique identifier (e.g., "reaction_gibbs_energy")
dimension string Yes Dimension string (e.g., "energy/amount_of_substance" or "M·L²·T⁻²·N⁻¹")
description string No Human-readable description
aliases list[str] No Alternative names
category string No Classification (default: "session")
disambiguation_hints list[str] No Tips for distinguishing from similar kinds
parent string No Parent kind name (must already exist in the lattice). The child inherits its dimension and sits below the parent in the kind hierarchy
join_policy string No Policy when joining distinct descendants at this kind: "lca" (default) lifts to the lowest common ancestor; "refuse" blocks the join

Response Schema

Success: QuantityKindDefinitionResult

{
  "success": true,
  "name": "reaction_gibbs_energy",
  "dimension": "energy/amount_of_substance",
  "vector_signature": "M·L²·T⁻²·N⁻¹",
  "category": "session",
  "parent": null,
  "join_policy": "lca",
  "message": "Quantity kind 'reaction_gibbs_energy' registered for session."
}

Error: KOQError

{
  "error": "Quantity kind 'gibbs_energy' is already defined",
  "error_type": "duplicate_kind",
  "parameter": "name",
  "hints": ["Use a different name or use the built-in kind"]
}

Examples

# Define a thermodynamic quantity kind
define_quantity_kind(
    name="reaction_gibbs_energy",
    dimension="energy/amount_of_substance",
    description="Gibbs energy change for a chemical reaction at constant T,P",
    aliases=["delta_G_rxn"],
    disambiguation_hints=["Use ΔG = ΔH - TΔS formula"]
)

# Define entropy change (distinct from heat capacity, same dimension)
define_quantity_kind(
    name="entropy_change",
    dimension="energy/temperature",
    description="Change in entropy for a process",
    aliases=["delta_S"],
    category="thermodynamic"
)

# Place a kind in the hierarchy under a built-in parent
define_quantity_kind(
    name="committed_dose",
    dimension="specific_energy",
    description="Dose integrated over 50 years post-intake",
    parent="dose_equivalent",
    join_policy="lca"
)
# → {"success": true, "name": "committed_dose", "vector_signature": "L²·T⁻²",
#    "parent": "dose_equivalent", "join_policy": "lca", ...}

declare_computation

Deprecated: use validate_result(declared_kind=...). Scheduled for removal in v1.0.0.

Declare computational intent before performing a calculation.

Establishes the expected quantity kind before using compute() or other calculation tools. After computation, use validate_result() to verify the result matches the declaration.

Parameters

Name Type Required Description
quantity_kind string Yes Name of quantity kind (from define_quantity_kind)
expected_unit string Yes Expected unit for the result (e.g., "kJ/mol")
context dict[str, str] No Optional context (e.g., {"temperature": "298 K"})

Response Schema

Success: ComputationDeclaration

{
  "declaration_id": "a1b2c3d4-...",
  "quantity_kind": "gibbs_energy",
  "expected_unit": "kJ/mol",
  "expected_dimension": "M·L²·T⁻²·N⁻¹",
  "status": "valid",
  "warnings": [],
  "compatible_kinds": ["enthalpy", "chemical_potential", "activation_energy"],
  "message": "Computation declared: expecting 'gibbs_energy' in kJ/mol"
}

Error: KOQError

{
  "error": "Unknown quantity kind: 'gibs_energy'",
  "error_type": "unknown_kind",
  "parameter": "quantity_kind",
  "hints": [
    "Available kinds: gibbs_energy, enthalpy, entropy_change...",
    "Use define_quantity_kind() to register quantity kinds"
  ]
}

Examples

# Declare intent to compute Gibbs energy
declare_computation(
    quantity_kind="gibbs_energy",
    expected_unit="kJ/mol",
    context={"temperature": "298.15 K", "pressure": "1 bar"}
)

# Declare entropy calculation
declare_computation(
    quantity_kind="entropy_change",
    expected_unit="J/K"
)

validate_result

Validate that a computed result matches the declared quantity kind.

Call this after compute() to verify dimensional, kind, and semantic consistency. Uses the active declaration from declare_computation() if declared_kind is not specified.

Beyond dimension equality, validate_result enforces kind: two units can share a dimension yet denote physically distinct quantities (Sv vs Gy both carry L²·T⁻²). The result's kind is recovered in three layers:

  1. UNIT_KIND_CONVENTIONS — a small module-level table for units whose kind is fixed by convention (Sv→dose_equivalent, Gy→absorbed_dose, Bq→radioactive_activity).
  2. Declared-kind membership — the declared kind appearing among the lattice's candidates for the result dimension counts as a verified match.
  3. Leaf-candidate filtering + lattice join — otherwise lattice.join() checks compatibility; a refused join fails validation at high confidence.

When the kind cannot be pinned, validation still passes on dimension but reports confidence: "low" and lists kind_candidates.

Parameters

Name Type Required Description
value float Yes The computed numeric value
unit string Yes The result unit string
declared_kind string No Kind to validate against (uses active declaration if None)
reasoning string No Reasoning text for semantic consistency checking

Response Schema

Success: ValidationResult

{
  "passed": true,
  "value": -228.6,
  "unit": "kJ/mol",
  "declared_kind": "gibbs_energy",
  "actual_dimension": "M·L²·T⁻²·N⁻¹",
  "expected_dimension": "M·L²·T⁻²·N⁻¹",
  "dimension_match": true,
  "result_kind": "gibbs_energy",
  "kind_match": true,
  "kind_candidates": [],
  "semantic_warnings": [],
  "confidence": "high",
  "explanation": "Result validated as 'gibbs_energy' (kind verified)",
  "suggestions": []
}

result_kind is the kind recovered from the result unit (or null when it cannot be determined); kind_match is true/false when enforcement could run and null when the kind is ambiguous; kind_candidates lists the possibilities in the ambiguous case.

Kind mismatch (dimension matches, kinds refuse to join):

{
  "passed": false,
  "value": 40.0,
  "unit": "Sv",
  "declared_kind": "absorbed_dose",
  "actual_dimension": "L²·T⁻²",
  "expected_dimension": "L²·T⁻²",
  "dimension_match": true,
  "result_kind": "dose_equivalent",
  "kind_match": false,
  "kind_candidates": [],
  "semantic_warnings": [],
  "confidence": "high",
  "explanation": "Kind mismatch: declared 'absorbed_dose' but result unit implies 'dose_equivalent'. These share dimension 'L²·T⁻²' but are physically distinct and cannot be conflated.",
  "suggestions": ["Use a unit associated with 'absorbed_dose', not 'dose_equivalent'."]
}

With semantic warnings:

{
  "passed": true,
  "value": -228.6,
  "unit": "kJ/mol",
  "declared_kind": "gibbs_energy",
  "actual_dimension": "M·L²·T⁻²·N⁻¹",
  "expected_dimension": "M·L²·T⁻²·N⁻¹",
  "dimension_match": true,
  "result_kind": "gibbs_energy",
  "kind_match": true,
  "kind_candidates": [],
  "semantic_warnings": [
    "Reasoning mentions 'ΔH' which is associated with 'enthalpy', but declared kind is 'gibbs_energy'"
  ],
  "confidence": "medium",
  "explanation": "Dimension matches but reasoning may indicate different quantity",
  "suggestions": ["Review reasoning to ensure it matches the declared quantity kind"]
}

Error: KOQError

{
  "error": "No active computation declaration",
  "error_type": "no_active_declaration",
  "parameter": null,
  "hints": [
    "Use declare_computation() before validate_result()",
    "Or specify declared_kind parameter"
  ]
}

Examples

# Validate using active declaration
validate_result(
    value=-228.6,
    unit="kJ/mol",
    reasoning="Calculated ΔG = ΔH - TΔS at 298 K"
)

# Validate with explicit kind
validate_result(
    value=91.5,
    unit="J/K",
    declared_kind="entropy_change",
    reasoning="Computed ΔS = Q/T for isothermal heat transfer"
)

# Kind enforcement: correct dimension, wrong kind
validate_result(value=40, unit="Sv", declared_kind="absorbed_dose")
# → {"passed": false, "kind_match": false, "result_kind": "dose_equivalent", ...}

list_quantity_kinds

Deprecated: use discover(topic="quantity_kinds"). Scheduled for removal in v1.0.0.

List built-in and session-defined quantity kinds.

Built-in kinds come from the KindLattice shipped in comprehensive.ucon.toml (27 entries); session kinds come from define_quantity_kind(). Session kinds take priority on name collision.

Parameters

Name Type Required Description
dimension string No Filter by dimension (name like "energy/amount_of_substance" or vector notation "M·L²·T⁻²·N⁻¹")
category string No Filter by category. Built-in kinds all report category "builtin", so category="builtin" selects exactly the built-in set
include_builtin bool No Include built-in lattice kinds (default true). Set false to see only session-defined kinds

Response Schema

Sorted list of kind dicts:

[
  {
    "name": "absorbed_dose",
    "dimension_name": "specific_energy",
    "dimension_vector": "L²·T⁻²",
    "description": "",
    "aliases": [],
    "category": "builtin",
    "disambiguation_hints": [],
    "parent": "specific_energy",
    "join_policy": "lca",
    "source": "builtin"
  }
]

parent names the kind's parent in the lattice (or null at a root); join_policy is "lca" or "refuse"; source is "builtin" or "session".

Examples

# Everything: built-ins plus session kinds
list_quantity_kinds()

# Only the kinds sharing a dimension
list_quantity_kinds(dimension="specific_energy")

# Only session-defined kinds
list_quantity_kinds(include_builtin=False)

list_kind_formulas

Deprecated: use discover(topic="kind_formulas"). Scheduled for removal in v1.0.0.

List registered kind formulas from the FormulaRegistry.

Kind formulas define how kinds compose under arithmetic (e.g. multiplying an absorbed_dose by a radiation_weighting_factor yields a dose_equivalent). They are the sanctioned crossings between kinds that validate_result would otherwise refuse to conflate.

Parameters

None.

Response Schema

Sorted list of formula dicts:

[
  {
    "name": "radiation_weighting",
    "expression": "D * w_R",
    "input_kinds": {"D": "absorbed_dose", "w_R": "radiation_weighting_factor"},
    "output_kind": "dose_equivalent",
    "generalizes": false,
    "commutative": true
  }
]

Examples

list_kind_formulas()
# → [{"name": "radiation_weighting", "expression": "D * w_R", ...}]

KOQ Error Types

Error Type Description
unknown_kind Quantity kind name not recognized
duplicate_kind Attempting to redefine existing kind
dimension_mismatch Result dimension doesn't match declared kind
no_active_declaration validate_result() called without prior declare_computation()
invalid_unit Unit string cannot be parsed
unknown_parent parent kind passed to define_quantity_kind() does not exist in the lattice
invalid_join_policy join_policy is not "lca" or "refuse"

KOQ Workflow

The recommended workflow for KOQ-aware computations:

# 1. Define the quantity kind (if not already defined)
define_quantity_kind(
    name="entropy_change",
    dimension="energy/temperature",
    description="Change in entropy for a thermodynamic process"
)

# 2. Perform calculation (using compute() or manually)
# ... calculation logic ...

# 3. Validate the result against the declared kind
validate_result(
    value=91.5,
    unit="J/K",
    declared_kind="entropy_change",
    reasoning="Calculated ΔS = Q/T = 25000 J / 273.15 K"
)
# → {"passed": true, "confidence": "high", ...}

This workflow catches errors where the numeric result and units are correct, but the physical quantity is misidentified (e.g., computing heat capacity when entropy change was intended).