Working session: the same from code
Everything done by hand on the previous pages is tool calls over the MCP
protocol. From code they are made by the client @arxo/law-client: it is
transport only, with no engine and no legal semantics. Answers about the
law come from the server, computation is on the server, the client computes
nothing.
Connect
Section titled “Connect”npm install @arxo/law-clientESM-only, any runtime with fetch and crypto.subtle. No key:
import { createMcpClient } from '@arxo/law-client/mcp';const client = createMcpClient(); // public server, whole corpusSlices by legal order are the same client with another address: a slice has its own catalogue and its own jurisdiction in every answer, and some tools are not served in it at all. So the set of tools is asked of the live server, not taken from a table in the client:
const tools = await client.listTools();The same session
Section titled “The same session”The client has a method per tool plus a general call(name, args). The
session from the previous pages in full:
const found = await client.law_search({ query: 'перерыв для кормления ребёнка до полутора лет, продолжительность перерыва',});const predicate = found.structuredContent.candidates.find(c => c.kind === 'predicate');
const rules = await client.law_rules({ predicate: predicate.id.split('#')[1] });const facts = rules.structuredContent.factsTemplate; // what to submit
const answer = await client.law_ask({ kind: 'truth', package: predicate.package, predicate: predicate.id.split('#')[1], args: ['Айгуль', 'Работодатель'], facts: [ { predicate: 'child_feeding_break_minutes', args: ['Айгуль', 'Работодатель', 20] }, { predicate: 'children_under_eighteen_months', args: ['Айгуль', 1] }, ], legalTime: '2026-09-01', proof: true,});The answer arrives in two forms at once: text — what the server prints
for a human, and structuredContent — the same fields as a document. Code
reads the second.
Three branches code must distinguish
Section titled “Three branches code must distinguish”if (answer.isError) { // you asked the wrong thing: unknown predicate, wrong argument type, // a limit exceeded. answer.text has the reason and a hint. This is not // an answer of the law.} else { const { truthStatus } = answer.structuredContent.answer; if (truthStatus === 'NEITHER') { // the law is silent: look at structuredContent.whyNot — premise statuses } // TRUE_ONLY, FALSE_ONLY, BOTH — pass as they are, with provenance}Collapsing this to a boolean is the most common integration error.
isError is about the call, NEITHER about the law, BOTH about a
contradiction in the material; each has its own handler, and none turns
into “no”.
What to keep
Section titled “What to keep”The answer is reproducible, and code should use that: next to the outcome
keep provenance whole — programHash, caseHash, resultHash,
codeHash, legalTime, jurisdiction. That is enough to repeat the
computation later and get the same bytes, or see what exactly changed: the
law, the case, or the code.
Do not request a proof on every call: proof: true is for those answers
that will go into law_explain or into an archive. The rest have
proofRef.
Your own deployment
Section titled “Your own deployment”The public server is convenient, not mandatory: the same code runs locally, and the client points at it by address. How — in Connect an AI assistant (MCP). What reproducibility of an answer means and what it does not prove — Why this can be trusted.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.