Skip to main content
Glama

law_ask

Read-only

Put a question to formalised law. When the answer is "not established" it carries whyNot — the engine's why_not report: the candidate rules and the state of every conjunct (satisfied / not satisfied / undetermined); the missing facts are visible there and need not be guessed. BEFORE THE FIRST call obtain the predicate names through law_search (a question in your own words → addresses) or law_packages (the signatures of a known instrument) — an invented name will be rejected. If the tool returned an error or "not established", THAT IS THE ANSWER: pass it to the user and do not substitute general knowledge about the law of some other country. But "I found no suitable instrument" is NOT an answer until law_search has been asked: silence of the catalogue is a property of searching by title, not a conclusion about the corpus. kind='truth' — whether a fact is established; kind='collect' — enumerate the records; kind='deadline' — compute a time limit on the official calendar; kind='positions' — which DUTIES arose from the facts and what their statuses are; kind='why_not' — the why_not report on the same goal, whatever the status of the answer. The answer carries the rules applied, the warnings and the provenance with hashes; truth/collect also carry a signature block for presentation. The server does not guess: where a norm is not formalised, the answer is "not established" or an error.

Input Schema

NameRequiredDescriptionDefault
argsNothe arguments of the predicate in the order of its signature; with kind='collect' exactly one of them is the selection variable ?name (for example ['urn:x:water', 'urn:x:mix', '?value']), the rest are values. Values follow the parameter type: an entity — 'urn:…' or a short name; Date — 'YYYY-MM-DD'; Money — '<number> <currency>' ('43250 KZT'); Quantity — '<number> <unit>' with the unit exactly as the package spells it; a constant of the package — its name
calcNokind='calc': a tree {op,left,right}, op ∈ add|sub|mul|div|le|lt|ge|gt|eq|ne (the synonyms divide/multiply/plus/minus and the signs are accepted); the leaves are 5 | '3932 KZT' | '2 mrp' | {lookup: 'mrp', args: [2026]} — a statutory value from the corpus; aggregates are {aggregate: 'sum', element: '?v', over: [{predicate, args with '?variables'}]} over the facts given in facts
daysNodeadline: the length of the period
kindNothe kind of question (truth by default)
unitNo
afterNodeadline: the date of the event
factsNofacts of the case: [{predicate, args, provenance, negated?, package?, judgment?}]. provenance is required and must be an object; {} is allowed. Its fields are optional: {origin?, evidence?: StableId, span?: {page?, quote?, offset?}, extractor?: {name, version?, confidence?}, observedAt?, recordedAt?}. origin defaults to case_input. evidence and observedAt are not required; the extractor is lowered to was_generated_by and a document to was_derived_from. confidence is a decimal string; the package EvidencePolicy reads the threshold, not the host. package resolves an ambiguous short name; args use the same notation as the args of the question
proofNoreturn the evaluation field with the proof graph in the answer — a ready-made input for law_explain (kind truth|collect; by default a summary without the graph)
cutoffNodeadline: the hour operations close
contextNoExpliziter Zeitkontext: timezone ist ein IANA-Name; decisionTime und knowledgeTime sind vollständige Instants mit UTC oder Offset und werden unverändert übernommen. Mit context ist legalTime erforderlich; ein Profil kann alle Felder verlangen
focusedNokind='truth': ask as focused_truth — the same answer as the full truth, but the proof and the warnings cover only the cone of the question; the answer carries evaluationKind and the slice hashes (focus); the cone in focus is reduced to coneHash and the predicate count, the full cone manifest comes in evaluation.focusManifest with proof=true. A slice is not an audit document: law_prepare_answer does not accept it for publication
packageNonarrow the question to one package of law
versionNothe exact package version pinned by the client (open('name@version')); if it differs from the profile composition the host refuses instead of answering with another version
evidenceNocase documents, section 74, evidence_item nodes. One document is referenced from provenance.evidence of many facts. payload.confidence is data for the EvidencePolicy; the engine does not evaluate the number
afterTimeNodeadline: the time of filing
legalTimeNothe date of the law (YYYY-MM-DD)
predicateNowhat is being asked, e.g. 'duty_amount'
responseModeNofull (default) — the complete answer. compact is accepted for compatibility: this server builds no short reply and returns the same complete answer in both modes; there is no fullAnswer reference and no stored snapshot of the answer.
supportEdgesNosupport edges, section 75, support_edge nodes: from is the document id, to is the fact literal, relation is supports or refutes. Admission is decided by the package EvidencePolicy, not by the host
deadlinePolicyNothe policy for counting time limits expressed in days: the StableId of a deadline policy declared in the world of the question (e.g. 'urn:kz:corpus:clir:administrative-code#AC_WORKING_DAY_TERMS'), or its short name when exactly one declaration carries it. An inline object {start_count: 'same_day'|'next_day', include_end: true|false, roll: 'no_roll'|'next_working_day'|'previous_working_day'[, month_end: 'last_day_of_month']} is accepted only by a 0.1 world; a 0.2 world refuses it, and the refusal names the declared policies. Without a policy a norm carrying a time limit answers MISSING_POLICY — the policy is set by the law of procedure and the server never assumes one. The snapshot of the official calendar for working days is supplied by the server itself whenever an instrument counts them.
evidencePolicyNoStableId of an evidence_policy node, section 78.2. Without it, previous calls keep their behaviour. The confidence threshold is a rule of that policy, not an argument of the call
selectedInterpretationsNonamed readings; for an exactly_one group choose exactly one StableId out of law_packages/law_rules

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changed
    • changedInput schema / properties / args / description
      Previous value: -"the arguments of the predicate in the order of its signature; with kind='collect' exactly one of them is the selection variable ?name (for example ['urn:x:water', 'urn:x:mix', '?value']), the rest are values. Values follow the parameter type: an entity — 'urn:…' or a short name; Date — 'YYYY-MM-DD'; Money — '<number> <currency>' ('43250 KZT'); Quantity — '<number> <unit>' with the unit exactly as the package spells it ('25 calendar_year', '30 meter'; law_packages shows the units of the constants, units are never converted — §49); a constant of the package — its name"New value: +"the arguments of the predicate in the order of its signature; with kind='collect' exactly one of them is the selection variable ?name (for example ['urn:x:water', 'urn:x:mix', '?value']), the rest are values. Values follow the parameter type: an entity — 'urn:…' or a short name; Date — 'YYYY-MM-DD'; Money — '<number> <currency>' ('43250 KZT'); Quantity — '<number> <unit>' with the unit exactly as the package spells it; a constant of the package — its name"
    • changedInput schema / properties / calc / description
      Previous value: -"kind='calc': a tree {op,left,right}, op ∈ add|sub|mul|div|le|lt|ge|gt|eq|ne (the synonyms divide/multiply/plus/minus and the signs are accepted); the leaves are 5 | '3932 KZT' | '2 mrp' | {lookup: 'mrp', args: [2026]} — a statutory value from the corpus; aggregates §59 are {aggregate: 'sum', element: '?v', over: [{predicate, args with '?variables'}]} over the facts given in facts"New value: +"kind='calc': a tree {op,left,right}, op ∈ add|sub|mul|div|le|lt|ge|gt|eq|ne (the synonyms divide/multiply/plus/minus and the signs are accepted); the leaves are 5 | '3932 KZT' | '2 mrp' | {lookup: 'mrp', args: [2026]} — a statutory value from the corpus; aggregates are {aggregate: 'sum', element: '?v', over: [{predicate, args with '?variables'}]} over the facts given in facts"
    • addedInput schema / properties / context
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Expliziter Zeitkontext: timezone ist ein IANA-Name; decisionTime und knowledgeTime sind vollständige Instants mit UTC oder Offset und werden unverändert übernommen. Mit context ist legalTime erforderlich; ein Profil kann alle Felder verlangen",
      +  "properties": {
      +    "decisionTime": {
      +      "type": "string"
      +    },
      +    "knowledgeTime": {
      +      "type": "string"
      +    },
      +    "timezone": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "timezone",
      +    "decisionTime",
      +    "knowledgeTime"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / deadlinePolicy / description
      Previous value: -"the §86 policy for counting time limits expressed in days: {start_count: 'same_day'|'next_day', include_end: true|false, roll: 'no_roll'|'next_working_day'|'previous_working_day'[, month_end: 'last_day_of_month' — for months and years only]}. Without it a norm carrying a time limit answers with a DEADLINE_POLICY_* warning — the policy is set by the law of procedure and the server never assumes one. The snapshot of the official calendar §85 for working days is supplied by the server itself whenever an instrument counts them."New value: +"the policy for counting time limits expressed in days: the StableId of a deadline policy declared in the world of the question (e.g. 'urn:kz:corpus:clir:administrative-code#AC_WORKING_DAY_TERMS'), or its short name when exactly one declaration carries it. An inline object {start_count: 'same_day'|'next_day', include_end: true|false, roll: 'no_roll'|'next_working_day'|'previous_working_day'[, month_end: 'last_day_of_month']} is accepted only by a 0.1 world; a 0.2 world refuses it, and the refusal names the declared policies. Without a policy a norm carrying a time limit answers MISSING_POLICY — the policy is set by the law of procedure and the server never assumes one. The snapshot of the official calendar for working days is supplied by the server itself whenever an instrument counts them."
    • changedInput schema / properties / deadlinePolicy / type
      Previous value: -"object"New value: +[
      +  "string",
      +  "object"
      +]
    • changedInput schema / properties / facts / description
      Previous value: -"facts of the case: [{predicate, args, negated?, package?, provenance?, judgment?}]. package resolves an ambiguous short name. provenance is {origin?, evidence?: StableId, span?: {page?, quote?, offset?}, extractor?: {name, version?, confidence?}, observedAt?, recordedAt?}. origin defaults to case_input (section 73; extraction adds no origin value): the extractor is lowered to a was_generated_by edge, the document to was_derived_from. confidence is a decimal string; the threshold is read by the package EvidencePolicy (field confidence), not by the engine. A fact with an extractor and no evidence is accepted as case_input and yields the warning FACT_WITHOUT_EVIDENCE. A call without provenance is unchanged. args use the same notation as the args of the question"New value: +"facts of the case: [{predicate, args, provenance, negated?, package?, judgment?}]. provenance is required and must be an object; {} is allowed. Its fields are optional: {origin?, evidence?: StableId, span?: {page?, quote?, offset?}, extractor?: {name, version?, confidence?}, observedAt?, recordedAt?}. origin defaults to case_input. evidence and observedAt are not required; the extractor is lowered to was_generated_by and a document to was_derived_from. confidence is a decimal string; the package EvidencePolicy reads the threshold, not the host. package resolves an ambiguous short name; args use the same notation as the args of the question"
    • addedInput schema / properties / facts / items
      Added value: +{
      +  "properties": {
      +    "args": {
      +      "type": "array"
      +    },
      +    "predicate": {
      +      "type": "string"
      +    },
      +    "provenance": {
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "predicate",
      +    "args",
      +    "provenance"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / properties / focused / description
      Previous value: -"kind='truth': ask as focused_truth (§181.3) — the same answer as the full truth, but the proof and the warnings cover only the cone of the question; the answer carries evaluationKind and the slice hashes (focus); the cone in focus is reduced to coneHash and the predicate count, the full cone manifest comes in evaluation.focusManifest with proof=true. A slice is not an audit document: law_prepare_answer does not accept it for publication"New value: +"kind='truth': ask as focused_truth — the same answer as the full truth, but the proof and the warnings cover only the cone of the question; the answer carries evaluationKind and the slice hashes (focus); the cone in focus is reduced to coneHash and the predicate count, the full cone manifest comes in evaluation.focusManifest with proof=true. A slice is not an audit document: law_prepare_answer does not accept it for publication"
    • changedInput schema / properties / selectedInterpretations / description
      Previous value: -"named readings §152; for an exactly_one group choose exactly one StableId out of law_packages/law_rules"New value: +"named readings; for an exactly_one group choose exactly one StableId out of law_packages/law_rules"
  2. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the description is free to add the behaviour that matters: "not established" answers carry a whyNot report with candidate rules and conjunct states, answers carry rules, warnings and provenance hashes, version pinning causes refusal rather than silent substitution, and the server never assumes a missing norm or deadline policy. These are non-obvious traits an agent cannot get from the annotations.

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

Conciseness4/5

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

Front-loaded with the core purpose, then prerequisites, then kind semantics, then return shape — a sensible order. It is long and somewhat repetitive (the "not established is the answer" point is made twice, once in capitals), but nearly every sentence carries operational content.

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

Completeness5/5

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

For a 22-parameter, nested-schema tool with no output schema, the description still covers the prerequisites, the meaning of the answer modes, the content of the returned answer (rules, warnings, provenance hashes, signature block) and the failure semantics. Only the calc path is left entirely to the schema, which is a small residual gap.

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

Parameters4/5

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

Schema coverage is 95%, so the baseline is 3, but the description adds genuine meaning by explaining the semantics of the kind values (truth vs collect vs deadline vs positions vs why_not) and the role of law_search/law_packages in filling predicate and args. It omits kind='calc' from that enumeration even though a dedicated calc parameter exists, leaving the most structurally complex branch unglossed.

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

Purpose4/5

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

States a specific verb and resource ("Put a question to formalised law") and enumerates the question kinds, so an agent knows this is the main evaluation entry point. It does not, however, contrast itself with close siblings such as law_case_ask, law_query or law_argue, so the agent must infer the boundary.

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

Usage Guidelines5/5

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

Explicitly states the prerequisite (obtain predicate names via law_search or law_packages before the first call, because an invented name is rejected), what to do with errors and "not established" results (pass to the user, do not substitute general legal knowledge), and the trap that an empty catalogue search is not a negative answer. That is a when/when-not/alternative map rather than a hint.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.