Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
QUERN_FLIGHTNoSet to 0 to turn off flight recording (default is on).
QUERN_REGISTRYNoThe registry path for quern (part of the nondeterminism boundary).

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {
    "mimeTypes": [
      "text/html;profile=mcp-app"
    ]
  }
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
tree_setA

Create or update the node at path (e.g. 'wardrobe/frame'). Fields given replace those fields; missing intermediates become plain groups. A node: {kind, name, params: {name: {value, unit, provenance, tolerance, source}}, links: {name: [paths]}, meta, payload, children}. Geometry lives in payload: {shape: box {size:[w,d,h]} | prism {polygon, height} | cylinder {diameter, height} | mesh {uri} | union|difference|intersection over children, transform: {translate:[x,y,z] mm, rotate_z_deg}}. Numeric shape args may name a param from any ancestor — so a shape written in terms of its params follows them when they are corrected, and cannot disagree with them. Declare what a kind MEANS with tree_vocabulary.

The write answers with any rule it broke — on the branch itself or on one that contains it. Treat that as the verdict: it is the same thing tree_check would tell you, said at the moment you caused it.

tree_getB

Read the Quern at path (default: whole tree), pruned to depth levels if given. Each slice arrives with its own semantics: the kinds present (with the operations they afford — full contract at operation://{kind}/{name}), the rules that apply, the solvers whose reads cover the slice. A workspace may expose derived branches (recomputed from their source on every read) — inspect and link to them, don't edit.

tree_findA

Search the Quern instead of walking it — when the user names an element, locate it in one call. query is a case-insensitive substring over a node's prose — id, name, kind, meta, every string in its payload and the sources its params cite — so the external identifier, definition or field name a user arrives with resolves to its node without knowing the path; kind/has_param match exactly; links_to finds every node referencing a path; payload matches payload FIELDS by value — {"state": "Opened"}, or {"state": ["Opened", "Proposed"]} for any of several — which is how you scope by state without a substring also matching the word in a description; under scopes to a branch; current_only drops nodes another node supersedes (the "what do we hold now?" query). Returns paths + a one-line summary each; then tree_get the one you meant. Purely structural.

tree_briefA

The working set — one line per current entry: kind, path, name, the links it declares, the params still ungrounded, the rules red on it; under headings where the tree has sections (a kind declared section), under=PATH for one branch alone. START HERE on an unfamiliar tree. This is the table of contents and tree_get is the chapter: reading a tree by tree_get('') costs its whole history to find the dozen claims that still bind, which is the cost this exists to refuse. What is settled is counted in a trailer rather than spent on — all=True shows superseded entries instead of omitting them, fat=True appends each entry's word count and sorts by it (the curation view: the first line is the first thing to tighten). Vocabulary-blind, like every verb here — kinds are labels, and nothing in it knows what a debt is.

tree_deleteB

Delete the node at path, with its whole branch.

tree_commitA

Apply a change-set — [{op: 'set'|'delete', path, node?}] — atomically, under authoring's one invariant: the committed tree's red set never changes silently. Green stays green; a set that would CREATE reds is refused whole (nothing written) and returns them by name; commit deliberately by naming each in acknowledge — the acknowledgment is recorded on the root. Use this over bare tree_set when a change should stand or fall with its consequences; drafts that are legitimately incomplete belong in one change-set with what completes them.

tree_vocabularyA

The tree's semantics, as data. No arguments: list every kind defined (stored + pinned packages + the domain's starter kinds). With kind + description: define or refine what that kind means, and optionally what its params/links stand for and what operations it affords — name: {contract, description, params_doc, medium}, binding the kind to a solver contract that makes sense on it (fetch the full contract at operation://{kind}/{name}, execute with tree_solve). Nothing branches on kinds — they mean exactly what this vocabulary says.

tree_ruleA

The tree's checks, as data. No arguments: list the rules. With name + expr: register one — a boolean expression whose builtins are STRUCTURAL only (param, nodes, params_of, count, sum/len/abs/min/max, ctx, superseded, unsupported(p, rel) — how many of what p leans on via rel are superseded or gone, so a rule can ask whether a claim's supports still stand — uses/where_used, the reuse folds rollup(under, mult, value) / tally(under, kind, mult) — mult/value name params, data not schema — the trace verbs over event subtrees: before(a, b) document order, preceding/following(p, kind?) earlier/later siblings, index(p), at(parent, i), parent(p) — so a scenario whose children are events is checkable ('the confirmation email precedes the charge') — and and/or/not) plus one bridge to meaning: solve('contract', args…), e.g. solve('geometry/bbox_h', 'pieces/x'). Contracts come from packages. Scope with kind (per node of that kind; its params + self in scope) or path; neither = global. Rules run in tree_check; remove deletes one.

tree_checkA

Run every applicable rule at or under path — the domain's data checks. Structural only; domain summaries (e.g. geometry's bounding box / volume via tree_measure) are registered by the domain's own tools, not here.

rule narrows the run to the rule(s) named. That is the "is this still wrong?" question — one rule, one node, asked after doing something about it — and it costs that rule's reads instead of the whole tree's. Naming a rule also prints what each evaluation READ: every param, solve, linked and ctx call with its arguments and the value it returned, so a red arrives with the values behind it. A name no rule carries is an error, never an empty pass.

tree_rollA

What the tree holds now, as {path, kind, digest} per node — and, given a roll you kept from last time, what changed since.

Every rule runs against the tree as it is, so no rule can see what was REMOVED: a deleted node is not red, it is absent. The roll is what makes absence and silent rewriting mechanical. Keep the roll this returns; hand it back as against on the next read and you get vanished (on the roll, no longer here), rewritten (still here, still its kind, no longer saying what it said — the digest covers name, payload and each param's value, and deliberately not grounding or meta, so re-reading an unchanged record is not a change) and rekinded (here, under a different kind).

excused spares paths whose removal was intended, and spares their whole subtree. The comparison is against the roll you hold, never against git — a gate diffing a committed roll is quern.roll.audit, not this.

tree_solverA

The tree's artifacts, as data — capabilities you submit, stored by content hash and served from artifact://{sha}. No arguments: list them. With name + wasm_b64 (base64 of the content, whatever the medium): register one. medium says what the content is — 'wasm' (default): sandboxed compute; ABI: export 'memory', 'alloc(len)->ptr', 'run(ptr,len)->(ptr<<32|len)'; input JSON {path, slice, params}; output {diagnostics:[str], proposals:[{path, param, value, note?}]}; run it with tree_solve (fuel + memory only: no filesystem, network or imports), and it never writes the tree — it proposes, you apply with tree_set. 'web': a self-contained HTML/JS bundle a host renders against a node slice, for the user. 'prose': instructions an agent follows with the generic verbs. Only wasm output may enter the tree as derived — the other media serve experience and guidance, never values. reads declares the only branch prefixes wasm may see.

tree_solveA

Run a registered solver on a branch it may read — sandboxed wasm, or a native contract a package ships (native contracts see the effective tree; wasm sees only the slice at path). Returns diagnostics and proposals — each proposal carries a ready-to-apply Quantity stamped provenance='derived' with the solver's identity, so a computed number is distinguishable from a measured one. Nothing is written: apply the proposals you accept with tree_set. Clients may instead fetch a wasm module at solver:// and run the same ABI locally.

tree_packageA

The semantic package library — capitalized vocabulary, rules and solvers, shared across every account on this server. No arguments: list the library and this workspace's pins. install='name@version' pins a package — its whole dependency closure applies (its requires, transitively), your own entries always winning; a broken closure (missing dep, two versions of one name) is refused at pin time. The pin records the package's content digest, so it keeps meaning these exact semantics even against another library. uninstall removes the pin. publish submits {name, version, description, requires: [{name, version}], vocabulary, rules, solvers: [{name, description, reads, wasm_b64, medium: wasm|web|prose}], examples}. Publishing is proof-gated: every rule must be exercised by the package's own examples and pass — examples run with the requires closure staged beneath, so extending packages prove themselves in the semantics they will live in; every wasm solver must meet the ABI (web/prose artifacts are stored content-addressed, served from artifact://{sha}, never executed). requires pin exact versions of already-published packages. Versions are immutable — ship a new one to evolve.

tree_appA

Open the Quern navigator — an interactive view of the tree and its semantics (kinds, params with provenance, links, rules) where the user can browse and coedit. Returns the root slice; the UI then navigates and edits through the same tree_* tools you use.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
Quern navigator

TDQS

A3.9/5.0

Scored across 14 tools

Disambiguation4/5

Most verbs have distinct purposes, and the descriptions sharply separate read modes (tree_get, tree_brief, tree_find, tree_roll) from write modes (tree_set, tree_commit). However, tree_solver versus tree_solve and the adjacent semantic tools (tree_vocabulary, tree_rule, tree_solver, tree_package) could cause brief hesitation.

Naming Consistency5/5

All 14 tools consistently use the tree_ prefix plus a snake_case verb/noun, e.g. tree_get, tree_set, tree_commit, tree_vocabulary. The convention is predictable across reads, writes, checks, and semantic operations.

Tool Count5/5

Fourteen tools are well-scoped for a rich tree workspace covering CRUD, search, validation, atomic commits, semantics, solvers, packages, and UI. Each tool maps to a distinct operational layer without feeling padded.

Completeness4/5

The surface covers the core lifecycle: read/search, create/update/delete, validation, atomic commit, semantic vocabulary/rules, solvers, and package sharing. Minor gaps exist around explicit move/rename/copy or import/export operations, though these can be approximated with existing set/delete and package tools.

Maintenance

ActivityActive
ResponsivenessResponsive