@littlebigbrain/mcp
A Model Context Protocol server for searching, inspecting, loading, validating, and managing little big brain graphs plus their workflows, embeddings, reviews, evals, and models.
Query graphs with plain-language questions, SPARQL, structured queries, semantic search, analysis, and helpers like
names,describe,commit_at, andcompare.Inspect graphs, schemas, ontology, entities, publication status, and files, including parsed document pages and line boxes.
Import or extend RDF/OWL, commit records/facts, retract facts, and record search feedback; destructive changes require human approval.
Configure native ontologies, apply starter ontologies, publish SHACL validation, suggest ontology changes, and store rewrite profiles/examples.
Manage embeddings and fit-from-text sources, including previewing, declaring, refreshing, and deleting them.
Create, preview, run, pause, resume, revise, test, or delete workflows, including developer workflows with triggers, shards, schedules, streams, and budgets.
File, answer, batch-answer, comment on, and withdraw human review items.
Label and run evals, manage golden queries and datasets, compare experiments, and review model checks.
Read model choices/activity and start, stop, switch, or revert model trials.
Connect via hosted OAuth or local stdio/HTTP, with destructive actions gated by approval.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@littlebigbrain/mcpsearch for entities related to 'Project Apollo'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@littlebigbrain/mcp
Model Context Protocol (MCP) server for little big brain, a search platform for AI applications such as chatbots, search tools, and agents.
Connect an MCP client to search your data, follow relationships, and read the facts behind an answer. The tools also let you load data and define validation rules.
Documentation · Quickstart · Issues
Connect
Create a stack in the console, then choose a hosted connection or a local process.
Hosted connection
For clients that support remote MCP with OAuth, use this URL and sign in with
your little big brain account. Replace <stack-slug> with your stack's slug:
https://mcp.littlebigbrain.com/mcp/<stack-slug>For clients that use an mcpServers JSON configuration:
{
"mcpServers": {
"lbb": {
"url": "https://mcp.littlebigbrain.com/mcp/<stack-slug>"
}
}
}This connection uses account sign-in and does not require a stack API key.
The connection guide
includes client-specific setup, including the origin URL and X-LBB-Stack header
for Codex.
Local process
Requires Node.js 18+. Copy the complete endpoint and a stack API key from Connect in the console, then add them to your client's MCP configuration:
{
"mcpServers": {
"lbb": {
"command": "npx",
"args": ["-y", "@littlebigbrain/mcp"],
"env": {
"LBB_BASE_URL": "https://<your-complete-stack-host>",
"LBB_API_KEY": "<your-stack-api-key>"
}
}
}
}The client starts the server and communicates through standard input and output
(stdio). Keep the key in your local configuration. Set LBB_GRAPH to change
the default graph from main.
A call that deletes or removes data asks you to approve it in the client. A
client that cannot show the question gets the error approval_required, and
nothing is sent. Set LBB_MCP_DESTRUCTIVE=allow in the server's environment
to run such calls without a question.
Related MCP server: RDF4J MCP Server
Run a first query
This example stores three facts in a graph named quickstart: a service writes
to a database, and each has a label. The graph is created on its first write.
Ask your client to call lbb_rdf with these arguments:
{
"action": "import",
"graph": "quickstart",
"format": "ntriples",
"source": "<https://example.org/auth-service> <https://example.org/writesTo> <https://example.org/user-db> .\n<https://example.org/auth-service> <http://www.w3.org/2000/01/rdf-schema#label> \"Auth Service\" .\n<https://example.org/user-db> <http://www.w3.org/2000/01/rdf-schema#label> \"User Database\" .",
"idempotency_key": "mcp-quickstart-v1"
}Now ask which database does Auth Service write to? The lbb_query call is:
{
"mode": "sparql",
"graph": "quickstart",
"consistency": "strong",
"query": "SELECT ?database WHERE { <https://example.org/auth-service> <https://example.org/writesTo> ?db . ?db <http://www.w3.org/2000/01/rdf-schema#label> ?database } ORDER BY ?database LIMIT 10"
}The result contains one row on a fresh graph:
database |
User Database |
The query follows a stored relationship to its database label. Strong consistency lets it read the import without waiting for a background index job.
An agent without a SPARQL query can pass the question in plain words:
{
"mode": "question",
"graph": "quickstart",
"question": "Which database does Auth Service write to?"
}The server answers in plain words (POST /v1/query/ask). A router model picks
the kind of question. A reasoning model runs queries in a bounded loop, reads
their rows, and answers. The result holds answer (text, citations, the
IRIs the answer names, and chart, how to draw the rows, when the server
gave one), steps, the route, and the query and rows the answer stands on. next continues that query with mode: "sparql". A
question takes about 8 s. Each question uses model tokens and counts toward a
daily limit of the stack, so the tool does not retry a failed call.
The server finds the names in the question in the graph and lists them in
linked. When the question is about records you already know, pass their
IRIs in anchor (at most 10): the queries use them directly. A question
about a date reads the last commit written by the end of that day; pass
timeline ([{date, as_of_commit_seq, label?}]) when the commits stand for
other dates. A question that asks what changed returns history.added,
history.removed and history.changed, with history.totals.
When the tool call carries a _meta.progressToken, the server sends a
progress notification for each step, for example Route: lookup (router, 0.92) or Step 2, sparql SELECT ?db: 1 row. The result is the same. Cancel
the call to stop the server's work.
To write the queries yourself, use names, describe, commit_at and
compare, then mode: "sparql".
For your own data, start with lbb_inspect using action: "guide" or
action: "ontology". Imported Resource Description Framework (RDF) data keeps
its original identifiers; inspect it with SPARQL when choosing query predicates.
Tools
Tool | Purpose |
| Read the schema, graph status, and entities. |
| Ask a question in plain words, run SPARQL queries, search by meaning (also inside a SPARQL query with |
| Import RDF documents or add facts with SPARQL |
| Inspect search setup and preview the text to embed. |
| Set up or refresh embeddings, or change the embedding model. |
| Delete an embedding and its stored vectors. |
| Inspect fit from text and preview the text the fit reads. |
| Declare, dry-run or refresh a fit source. |
| Delete a fit source; its suggestions stay. |
| List the starter workflows this server offers and the workflows created from them on a graph (triggered workflows), read one with its status, and preview a new one. Read the workflows with triggers (target type, shards, routing, window, trigger) and what each watch has not sent yet, with origins. |
| Create a workflow from a starter workflow on a class (a developer workflow with its workflow type, owned outputs and batch), ask it to run now, or pause and resume a developer workflow. Define a workflow with triggers of your worker (shards, routing field, window) and run it now. |
| Delete a triggered workflow, or a workflow with triggers by its name. What it wrote stays. |
| List the files of a graph, all or by parse status or a part of the name, and read the parsed pages of one: each line with its id, its box on the page and its text. |
| Write legacy JSON facts, explicitly commit versioned records, retract facts, or record search feedback. |
| Define record types and relationships, list and apply ontology starters (CRM, documents, work), publish validation rules, or keep the graph's notes and worked examples for questions in plain words ( |
| Label query results and check whether later queries return the expected answers. Read the model checks of a graph, and agree with or correct a check that the user confirmed. |
| Read which model each use runs (question answers, query routing, search rerank, ontology fit, eval labels), and the trials that test other models against the graph's ground truth. |
| Start or stop a trial, switch a use to a tested model that meets the bar, or revert to LBB's model. |
| Compare retrieval settings, read model training datasets, or read a month of managed-model activity. |
See search by meaning for embedding setup. To define constraints with the Shapes Constraint Language (SHACL), see query and validation.
Legacy mode=facts follows the graph's existing first-write restrictions; a
graph first written through lbb_rdf refuses that legacy JSON path. Explicit
mode=records uses the separate versioned contract described below and does not
activate or convert an existing graph. RDF updates support additive INSERT DATA;
see the RDF guide for format and
update limits.
Versioned records commits
Use explicit lbb_commit mode: "records" with a nested records body whose
version is records/1. The server must recognize records_commit_v1 and the
graph must already have qualified support; protocol recognition does not
activate a graph or offer a graph-type choice. Ordinary/missing/unactivated
graphs keep their typed refusal. There is no creation, conversion or activation
option here. This requires the matching client release containing
records.commit; publish that client before releasing this MCP update.
{
"mode": "records",
"records": {
"version": "records/1",
"entities": [{
"id": "https://example.org/service/auth",
"add": {"https://example.org/title": {
"@value": "Auth Service",
"@type": "http://www.w3.org/2001/XMLSchema#string"
}}
}]
},
"idempotency_key": "auth-title:v1"
}The complete object is forwarded without dropping unknown fields, lowercasing
IRIs, coercing literals or resolving schema keys locally. The server validates
it strictly. Do not mix legacy facts/embeddings/properties/retract/feedback or
dry_run/backfill arguments into records mode, even with empty or false values.
expected_graph_epoch adds an exact decimal incarnation guard.
An explicit idempotency key wins. When omitted, MCP derives a stable content key
from the original body, graph and epoch guard. The snapshot and key are fixed
before approval and transport retries. Keep the same original body/key after a
lost reply; do not use a new key to investigate an unknown result. An exhausted
POST transport failure or malformed success returns record_outcome_unknown,
outcome: "unknown" and the original idempotency_key, without legacy fallback.
A capability failure sends no POST and cannot become a write acceptance.
Typed server errors keep their original code/status and also retain the recovery
key; the tool does not invent an acceptance or refusal verdict for them.
Edits that may remove support use the existing destructive approval policy:
set, unset, remove, delete, replace_scope, or a relationship with
asserted: false. A set may replace an existing field. The question names the
graph and source owner/scope; refusal sends no API request. Add-only work needs
no destructive approval. The existing person-controlled
LBB_MCP_DESTRUCTIVE=allow setting applies; no body field can bypass approval.
The server remains responsible for current authority and reserved source owners.
Success returns the complete original receipt as compact JSON and structured
content. Resolved IDs, schema, projection counts, no-op and replay are never
compacted. Support can change with zero visible additions/removals. Acceptance,
publication and class embedding readiness are separate observations. MCP keeps
its 80,000 UTF-8 byte output ceiling: an unexpected oversized valid receipt reports
record_accepted_output_limit with outcome: "accepted", sequence and key so the
full receipt can be recovered through the SDK/HTTP API. It never calls that
known acceptance a failed mutation or unknown outcome. Oversized error messages
are explicitly flagged while preserving ordinary typed codes/status.
The records body is bounded to one MiB and its escaped recovery key to 8 KiB at the MCP boundary; the server's smaller total-request/idempotency limits still apply. These limits do not expand any graph/source budget or enable admin erasure.
Pages and saved queries
When a result includes next, pass those arguments to the same tool to read the
next page. Continue until next is absent. row_limit sets a maximum; large
values can make a page shorter.
SPARQL queries keep the same commit across pages. Save the query and its returned
commit sequence to check an answer later, then use as_of_commit_seq to select
that version. See history and replay
for retention and evidence handling.
Embed the server
To serve the tools from your own Node.js process:
import { createMcpHttpServer } from "@littlebigbrain/mcp";
createMcpHttpServer({
baseUrl: process.env.LBB_BASE_URL!,
mcpPath: "/mcp",
allowedHosts: ["127.0.0.1", "localhost", "::1"],
}).listen(8080, "127.0.0.1");Clients connect to http://127.0.0.1:8080/mcp and send a stack API key in
Authorization: Bearer <key>. See the
Node.js integration guide
for HTTP options and integration with an existing MCP server.
Development
From a clone of this repository:
npm ci
npm run build
npm run typecheck
npm testLicense
Available Tools
22 toolslbb_commitADestructiveIdempotent
Write graph facts, retract them, or label ranked results. Explicit mode=records forwards a strict records/1 body, with exact IRIs/terms and the original receipt. It requires an existing support-enabled graph; protocol recognition never activates or converts a graph. Record edits that may remove support (set/unset/remove/delete/replace_scope or asserted=false) ask for approval. mode=facts writes triplets/embeddings/properties; mode=retract removes a wrongly-added fact (by edge or by entity) without a full reset; mode=search_feedback stores query/result relevance labels (Feedback grades: 3=ideal/good, 1=partial, 0=bad; include query, search_id when available, target, rank, score). Explicit idempotency_key wins; when omitted, MCP derives a stable content hash so content-identical retries dedupe. Facts mode defaults edge_idempotency to append; pass skip_unchanged for re-runnable backfills. A retract asks the person to approve the links and records it removes first. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | ||
| graph | No | Graph to target; defaults to the connection's graph | |
| dry_run | No | Validate a facts commit and return its structured SHACL report without writing. Only supported for mode=facts. | |
| records | No | Explicit mode=records only: the unchanged RecordCommitRequest object with version=records/1. Unknown fields are preserved for strict server validation; no native IRI normalization or scalar coercion. Cannot mix legacy write arguments. | |
| triplets | No | ||
| observed_at | No | Backfill timestamp (RFC3339). Records this commit AS OF that instant: stamps transaction time and defaults each triplet's valid_time.start. Replay history in order with observed_at per commit so as-of reads by date work. Omit for live writes. | |
| retract_edges | No | mode=retract: specific edges to remove, matched by (source, relation, target). | |
| idempotency_key | No | ||
| search_feedback | No | ||
| edge_idempotency | No | Defaults to append in MCP. Use skip_unchanged for backfills; it skips exact current-edge duplicates and drops evidence-only repeats. | |
| retract_entities | No | mode=retract: entities whose every current edge is removed (a current-state tombstone; the record and its history are kept for as_of reads). | |
| entity_embeddings | No | ||
| entity_properties | No | Typed scalar attributes per entity. Each item is { type, name, properties }. `properties` is a flat map of field -> value, e.g. { "type": "PERSON", "name": "Ada Lovelace", "properties": { "h_index": 52, "title": "VP", "last_contact": "2026-06-26" } }. Values are coerced to each field's declared type, so a string like "2026-06-26" lands in a date_time field and "52" in an i64 field. (The verbose form [{ field, value: { i64: 52 } }] is also accepted.) Register a field first with lbb_configure evolve_ontology add_property; the commit response echoes written_properties so you can confirm what landed. | |
| expected_graph_epoch | No | mode=records only: exact decimal graph incarnation guard. Protocol support does not activate this graph. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the full approval flow: support-removing edits ask the person via MCP form elicitation, decline yields approval_declined, a non-interactive client yields approval_required, and LBB_MCP_DESTRUCTIVE=allow bypasses it. It also explains idempotency-key content-hash derivation and edge_idempotency defaults, and that retract is a current-state tombstone preserving history. This is exactly the context annotations alone cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and mode enumeration are front-loaded, but the body is one dense paragraph across four modes and 14 parameters. The approval mechanism is restated twice ('A retract asks the person to approve ... first' followed by the fuller server/elicitation explanation), adding length without new information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, nested, multi-mode mutation tool with no output schema, the description covers prerequisites, approval outcomes, idempotency, and partial return signals (original receipt, written_properties echo, SHACL report for dry_run). It leaves the facts-mode success payload and other error codes unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 64% schema coverage, the description adds real meaning beyond the schema: mode selection semantics, records-body strictness ('unknown fields are preserved ... no native IRI normalization'), retract by edge vs. by entity, the 3/1/0 feedback grading scale, and idempotency_key/edge_idempotency behavior. It omits observed_at and dry_run entirely, relying on their schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names specific verbs and resources ('Write graph facts, retract them, or label ranked results') and then enumerates the four modes, so an agent immediately knows this is the mutation entry point. It never names a sibling tool (e.g., lbb_query for reads), so sibling differentiation is left implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each mode is given a use case: facts for triplets/embeddings/properties, retract for 'a wrongly-added fact ... without a full reset', search_feedback for storing relevance labels, and records for the strict body path. It also states the prerequisite ('requires an existing support-enabled graph') and backfill guidance (skip_unchanged). It stops short of routing to alternative tools for reads or embedding management.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_configureADestructive
Manage native schema metadata. Actions: define_ontology (friendly spec with super_types), evolve_ontology (ordered edits including add_super_types), list_starters (the base ontologies crm, documents and work, each with its status on the graph: absent, partial or applied, what applying adds, and conflicts), apply_starter (add what the graph lacks of a starter in one ontology version; a relation the graph has is widened; refused with starter_conflict when the graph holds a term differently; dry_run previews), publish_schema (SHACL activation), suggest_ontology_change (file a change for a person to review instead of applying it; prefer it when the graph's owner reviews ontology changes, and list the result with lbb_inspect action=ontology_suggestions; facts files graph facts for review, which accepting commits after the change, and change may be empty when facts is set), get_rewrite_profile and set_rewrite_profile (the graph's notes and up to 20 worked question-to-SPARQL examples that lbb_query mode=question reads for every question; pass the version you read as expected_version). define, evolve, publish and set_rewrite_profile support dry_run previews. Definition/import here extracts native metadata; it does NOT store the complete RDF/OWL document as queryable graph facts. Use lbb_rdf import for full OWL and lbb_rdf update for additive INSERT DATA revisions; RDF deletions are unsupported. Publish_schema accepts unchanged ontology plus shapes; use define/evolve for native ontology changes. Publication enqueues durable conformance; a preview does not validate the whole graph. An evolve_ontology that removes (remove_entity_type, remove_relation, or narrow_relation with remove_domain or remove_range) and a publish_schema with desired_mode=reject ask the person to approve first; a dry_run does not ask. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Idempotency key ([A-Za-z0-9-_.:/]); filing again with the same key revises the suggestion | |
| ops | No | Ontology changes to apply in order (additive, in-place edits, or subtractive) | |
| agent | No | Your name as the producer, shown to reviewers | |
| facts | No | Graph facts a person confirms: accepting commits them after the change (at most 200 triplets and property rows together). Records graphs only | |
| graph | No | Graph to create or redefine | |
| notes | No | What the data means for questions: which property holds the current state, what 'me' or 'my' means, which records to leave out. At most 8,000 characters | |
| title | No | Short imperative text, e.g. 'Add class Contractor' | |
| action | Yes | Selects the variant (one of: define_ontology, publish_schema, evolve_ontology, list_starters, apply_starter, suggest_ontology_change, get_rewrite_profile, set_rewrite_profile). | |
| anchor | No | The class, property or relation the change is about | |
| change | No | The ontology operations a person applies by accepting, in order (same shapes as evolve_ontology ops). Up to 128; may be empty or absent when facts is set | |
| format | No | ||
| shapes | No | ||
| source | No | ||
| dry_run | No | Preview the exact definition without creating a graph or writing metadata. | |
| starter | No | Starter id: crm, documents or work (list_starters names them) | |
| evidence | No | What you saw: record count, fields, up to 20 sample records | |
| examples | No | Up to 20 worked examples: a question and the query that answers it on this graph | |
| ontology | No | ||
| rationale | No | Why the ontology needs the change; cite what you saw | |
| relations | No | ||
| desired_mode | No | ||
| entity_types | No | ||
| merge_default | No | ||
| expected_version | No | The version get_rewrite_profile returned (0 for none): another stored version answers 409 conflict and stores nothing | |
| confirm_restrictive | No | ||
| allow_data_conflicts | No | Deprecated compatibility flag; does not bypass conflicts. Preview subtractive changes with dry_run=true, repair the reported conflicts, then apply. | |
| expected_ontology_version | No | Refuse when the graph's ontology version differs |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the destructiveHint annotation: it discloses that removal ops and desired_mode=reject trigger MCP form elicitation, that nothing is sent on decline (approval_declined) or when the client cannot render the question (approval_required), and the LBB_MCP_DESTRUCTIVE=allow escape hatch. It also notes that publication enqueues durable conformance and that a preview does not validate the whole graph. It stops short of saying what happens to existing data on tombstoning, which the schema covers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence front-loads the purpose, but the body is a single run-on block of parenthetical clauses chained with semicolons, making the eight actions hard to scan. Content largely earns its place, but the lack of any list or paragraph break hurts retrievability for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 27-parameter, eight-variant, destructive, no-output-schema tool, the description covers the highest-risk hidden behaviors: approval gating, dry_run semantics, starter conflicts, and the RDF-vs-native boundary. It leaves several less-risky parameters undiscussed, but those are described in the schema at 67% coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 27 parameters and 67% schema coverage, the description adds real meaning for the tricky ones: expected_version must be the version get_rewrite_profile returned, facts are committed only after acceptance and change may be empty when facts is set, starter ids are crm/documents/work, and ops are applied in order including add_super_types. Many parameters (anchor, graph, shapes, format, ontology.source, entity_types, relations, merge_default, confirm_restrictive) get no mention, so it does not fully compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific framing ('Manage native schema metadata') and then defines each of the eight actions in concrete verb+resource terms (define_ontology, apply_starter, publish_schema, suggest_ontology_change, get/set_rewrite_profile). It actively separates itself from siblings: 'Use lbb_rdf import for full OWL and lbb_rdf update for additive INSERT DATA revisions' and 'use define/evolve for native ontology changes' rather than publish_schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing is given for the ambiguous cases: prefer suggest_ontology_change 'when the graph's owner reviews ontology changes' and list the result via lbb_inspect action=ontology_suggestions; use lbb_rdf import for full OWL; use define/evolve instead of publish_schema for native changes. It also states when apply_starter is refused (starter_conflict) and that dry_run is available on define, evolve, publish and set_rewrite_profile.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_embeddingsARead-only
Search setup, read only: embeddings declared on classes (an embedding on a class covers its subclasses; one model per graph). list shows each embedding's status (serving and building version, backfill progress, lag) and the graph's model; get shows one; preview shows every candidate fact of a class with its coverage and examples, and the exact text of sample instances, and stores nothing. Declare, refresh, or change the model with lbb_embeddings_manage; search with lbb_query mode=search. list is the first step of planning a search (lbb_inspect action=guide has the recipe).
| Name | Required | Description | Default |
|---|---|---|---|
| dim | No | ||
| from | No | preview/declare: the fields, e.g. ["label", "description", "calls/label"]. Omit for the automatic choice; on an existing embedding, omit to keep its fields. | |
| iris | No | preview: the instances to show instead of a sample. | |
| name | No | get: the embedding name. | |
| class | No | preview/declare: the class IRI. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| model | No | model: the graph's new model. preview/declare: omit it; a graph has one model (the graph's, or the platform's default for the first embedding). | |
| title | No | preview/declare: the field that names each hit, e.g. "display_name". Omit for the ontology's name property (skos:prefLabel, a property declared rdfs:subPropertyOf rdfs:label, else rdfs:label); on an existing embedding, omit to keep its name. preview reports title_source and, when the labels read as keys, title_suggestion. | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| sample | No | ||
| exclude | No | preview/declare: fields to drop from the automatic choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, the description explains that preview stores nothing, describes what list returns (serving/building version, backfill progress, lag, graph model), and clarifies embedding inheritance behavior. These details materially improve the agent's ability to predict behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the purpose and action meanings, and most sentences earn their place by distinguishing actions or alternatives. It is somewhat dense and run-on in the middle, but for a 12-parameter tool the length is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
It covers the essential behavior, action semantics, sibling routing, and preview side effects, which is strong given the absence of an output schema. Some parameter details and response-shaping options are left entirely to the schema, so it is not fully exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 75%, so the schema already carries most parameter meaning. The description adds useful semantics for the action parameter by explaining what list, get, and preview do, but it does not add much detail for the other parameters such as dim, sample, detail, iris, or exclude.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific scope: read-only search setup for class embeddings, including subclass coverage and one-model-per-graph behavior. It then distinguishes the list, get, and preview actions clearly, so an agent can understand the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes mutations to lbb_embeddings_manage and search execution to lbb_query mode=search, and it says list is the first step of planning a search. The reference to lbb_inspect action=guide provides a concrete next step for the recipe.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_embeddings_deleteADestructiveIdempotent
Delete an embedding: its name and its vectors (index-gc removes the stored runs). Its class stops being searchable until it is declared and built again. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The embedding name. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| detail | No | Response detail level. Defaults to compact. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond the annotations, which only flag destructive/idempotent: the description discloses what is irreversibly destroyed, the searchability consequence afterward, the human-approval gate via MCP form elicitation, the two failure outcomes (approval_declined sends nothing, approval_required sends nothing), and the LBB_MCP_DESTRUCTIVE=allow environment escape hatch. This is exactly the context an agent needs before invoking a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the destructive action and its scope, then the consequences, then the approval mechanics. Three sentences carry a lot of distinct information with little waste, though the final sentence stacks two error codes plus an environment variable and reads slightly dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 3-parameter schema, no output schema, and destructive annotations, the description covers the action, side effects, approval flow, and failure modes thoroughly. The only gap is the response shape — nothing indicates what a successful delete returns or how 'detail' affects it — which is a minor omission for a delete tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all three parameters documented including the detail enum and the graph default, so the schema carries the parameter burden. The description adds no parameter-level meaning — it does not explain what 'graph' or 'detail' mean in the delete context — so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Delete an embedding') and goes further to enumerate exactly what is removed: the name, the vectors, and the stored runs via index-gc. It also describes the post-condition ('Its class stops being searchable until it is declared and built again'), which an agent could not infer from the name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear this is a destructive, approval-gated operation and explains what happens in the decline/unavailable-client branches, which is real usage context. However, it never routes the agent between this tool and siblings like lbb_embeddings_manage or lbb_embeddings — there is no explicit 'use this when you want to remove, use that to modify' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_embeddings_manageA
Declare or refresh an embedding, or change the graph's model. Run lbb_embeddings action=preview first and show the user the text it will embed. declare sets the class, the fields (one-hop property paths such as label, description, calls/label; omit for an automatic choice); a new embedding takes the graph's model, and another model is refused. On an existing embedding it changes only what you name, and a changed recipe builds a new version while the old one serves. model moves every embedding of the graph to model: each builds a new version, and the graph switches when all are ready (a search never mixes two models). refresh runs one step of the embed job now (it also runs by itself after each published commit).
| Name | Required | Description | Default |
|---|---|---|---|
| dim | No | ||
| from | No | preview/declare: the fields, e.g. ["label", "description", "calls/label"]. Omit for the automatic choice; on an existing embedding, omit to keep its fields. | |
| name | No | The embedding name (refresh: required). | |
| class | No | preview/declare: the class IRI. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| model | No | model: the graph's new model. preview/declare: omit it; a graph has one model (the graph's, or the platform's default for the first embedding). | |
| title | No | preview/declare: the field that names each hit, e.g. "display_name". Omit for the ontology's name property (skos:prefLabel, a property declared rdfs:subPropertyOf rdfs:label, else rdfs:label); on an existing embedding, omit to keep its name. preview reports title_source and, when the labels read as keys, title_suggestion. | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| exclude | No | preview/declare: fields to drop from the automatic choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare this is a non-read-only, non-destructive, closed-world write; the description adds substantial behaviour beyond that: a changed recipe builds a new version while the old one keeps serving, model switching is deferred until every embedding is rebuilt so 'a search never mixes two models,' and refresh executes exactly one step of the embed job that otherwise runs automatically after each published commit. It also imposes a human-in-the-loop confirmation requirement absent from any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The capability statement is front-loaded and every sentence carries operational content rather than filler. It is a dense single block, though, and the versioning/model-switch sentences are long enough that an agent must parse carefully to separate per-action rules.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter mutation with no output schema, the description covers ordering, versioning, job execution and model immutability rules well. The notable gap is the `dim` parameter, which has neither a schema description nor any mention in the prose, so an agent gets no guidance on when a dimension must be supplied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 80% schema coverage the baseline is 3, and the description earns more by explaining semantics the schema does not: one-hop property path syntax for fields, that omitting fields on an existing embedding preserves them, and the constraint that a new embedding must adopt the graph's model while any other model is refused. It leaves `dim` and `graph` entirely unaddressed, which are the two weakest-documented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb set and resource: 'Declare or refresh an embedding, or change the graph's model.' The three action values (declare/refresh/model) are each distinguished from one another and from the read-only sibling lbb_embeddings, which is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite workflow: 'Run lbb_embeddings action=preview first and show the user the text it will embed,' which routes the agent to the sibling before writing. It also explains what each action does so the agent can pick one. It stops short of stating when this tool should not be used at all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_evalsA
Managed evals: ground truth for the questions an app asks and the searches it runs. A query run with request (lbb_query, also mode=question) records a trace: the question, the query that answered it, the type of that query (query_type: sparql, hybrid = search by meaning with conditions, search = search by meaning alone) and one item per result (hit or row); trace reads it back with the item ids. label has two forms. On a question's trace, valid alone judges the whole answer: valid=true makes the trace's query the golden query of the question; valid=false with sparql gives the right query, which becomes the golden query; valid=false alone marks the answer wrong; route with valid=true (or valid=false with sparql) names the route the question expects, and valid=true alone takes the trace's route. item + valid (or items) judges one result, a citation of the answer: the ground truth of the hits of a search by meaning, and a result marked wrong must not come back for any type. golden freezes a stored query or a search (every result it returns now is relevant). run checks every golden at the current commit: a question is asked again through the query rewriter, then the type of the query it wrote is compared with the expected type, its rows with the rows of the golden query at the same commit (query_check), and its results with the judged results, and the router's pick with the golden's route (route_check, which does not change the verdict); a search is done again; new results open a review trace. run_answers checks your own app's answers instead: ask each question golden's request with your own loop, then send answers=[{golden, sparql, route}] (route = the route of lbb_query mode=question with route mode, sparql absent for an unanswerable question, error for a failure); the server runs each query and checks it the same way, and the runs form the app's own series (runner; results with runner reads them). judge lets the platform's judge model (the hosted frontier model) label unlabeled results. summary, traces, goldens, results, and settings read state. Model checks: a judge model checks a sample of the model calls LBB makes for the graph (rerank, route, ask = the answer of a question, rewrite, fit, propose, label). checks_summary reads a month per job and model (checks, score, right, partly, wrong, reviews) and the judge's agreement with people; checks lists the month's checks, newest first, with the judge's verdict, score and reason and the ground truth (truth). review_check records a person's review of one check (call_id): agree=true keeps the judge's verdict; agree=false with verdict (and an optional score, reference and note) corrects it. The review becomes the call's ground truth, so show the check to the user and review only what the user confirmed. Datasets: named sets of examples with the outputs a correct run gives, which workflow tests and template evals share. The kind values holds per item an input text (name, text, iri), the property values a correct run writes (values) and those it must leave out (leave_out). datasets lists the graph's datasets, newest first, without their items (one page with next_cursor); datasets_get reads one (id) with its items; datasets_export returns it as a template's samples, records (records.json) and expected (expected.json). datasets_create makes one with name and items (at most 500), install (the settings it is graded with: each property's value type, units, context) and about, or from a workflow test's answers with source={kind: test, id}. datasets_items adds items to a dataset (id); an item with the name of one it holds replaces it. Delete a dataset with lbb_evals_delete, which asks the person first. A dataset ends with its graph. Experiments: two configurations of a workflow, A and B, on the items of a dataset, with the difference of B against A and its 95% interval. A is the workflow as it runs now; b changes one part: {model: {use: extract or decide, model: {provider, model, effort}}} (a model from lbb_model_choice action=choices options) or {revision: wrev_…} (a kept settings revision), not both. Each arm runs as a workflow test that writes nothing to the graph and spends model budget; each item is graded against the dataset's labels. experiments_estimate shows the cost first (items, the cost of both arms, the limit, the budget left): call it, show the user the figures, and start only what the user confirmed. experiments_create starts one (workflow, dataset, b, optionally max_items up to 200 and max_cost_usd up to 100, default 5); poll experiment (id) until its status is done, failed or cancelled, and read report.delta with ci_low and ci_high (outcome too_few under 10 items, else better, worse or same) and the item rows. experiments lists them (workflow, dataset, status, one page with next_cursor); experiments_cancel stops one, keeping what it compared. None of them changes the workflow or the graph. To use B, make the change with the experiment's id: lbb_model_choice_manage action=put_choice (or lbb_workflows_manage action=activate) with experiment, after the user confirmed; it fails with experiment_outdated when the workflow moved since.
| Name | Required | Description | Default |
|---|---|---|---|
| b | No | experiments_estimate, experiments_create: what B changes in A: {model: {use, model: {provider, model, effort}}} or {revision}, not both. | |
| by | No | label: who labels (an agent name). | |
| id | No | datasets_get, datasets_export, datasets_items: the dataset's id (ds_…). experiment, experiments_cancel: the experiment's id (exp_…). | |
| job | No | checks: only the checks of one job. | |
| item | No | label: the result id (a hit's `id`, or an item id from trace) to label with `valid`. | |
| kind | No | datasets_create: what the items hold: values (the default). | |
| name | No | datasets_create: the dataset's name. | |
| note | No | label / review_check: why. review_check: at most 2,000 characters. | |
| about | No | datasets_create: what the dataset is, in sentences. | |
| after | No | checks: the next_after of the previous page. | |
| agree | No | review_check: true = the judge is right, false = correct it with verdict. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| items | No | label: several results at once, each {id, valid, note}. datasets_create, datasets_items: the examples, at most 500, each {name, text, values, leave_out, iri, case}; values and leave_out hold {property, value, accept, stated, quote, reason, source}; source says which person's answer gave a label (kind test or review, id, at): send it back as read, or leave it out. | |
| limit | No | ||
| month | No | checks_summary / checks: the month, yyyy-mm (UTC). Defaults to the current month. | |
| route | No | label: with valid=true, or valid=false with sparql, the route the question expects. | |
| score | No | review_check with agree=false: the right score, 0 to 1. Omit for the judge's score of that verdict. | |
| top_k | No | golden: the top_k of a search golden. | |
| valid | No | label: true = the result answers the request (thumbs up), false = it does not. Without item or items, on a question's trace: the whole answer is right (true) or wrong (false). | |
| action | Yes | ||
| cursor | No | datasets, experiments: the next_cursor of the page before. | |
| detail | No | Response detail level. Defaults to compact. | |
| runner | No | run_answers / results: your app's name, lower-case letters, digits and -, at most 40 characters (default app). results without runner reads the server's runs. | |
| source | No | datasets_create: {"kind": "test", "id": <test id>}: the answers of a workflow test become the items, and its settings the install. | |
| sparql | No | golden: the query to freeze (the search text for surface=search). label: with valid=false and no item, the right query for the question; the server checks and runs it once. | |
| status | No | experiments: only the experiments with this status. | |
| answers | No | run_answers: one answer per question golden your app asked: golden (its id), sparql (the query whose rows hold the answer; leave it out when the question is unanswerable), entailment, as_of_commit_seq, route (as the router returned it), reply, error (your app failed), cost_micro_usd. | |
| call_id | No | review_check: the check's `call` id, from checks. | |
| dataset | No | experiments_estimate, experiments_create: the dataset (ds_…) whose items both arms run. experiments: only the experiments on this dataset. | |
| install | No | datasets_create: the settings it is graded with. | |
| request | No | golden: the user's words the query answers. | |
| surface | No | golden: which surface the query runs on (default sparql). | |
| verdict | No | checks: only the checks whose ground truth has this verdict. review_check with agree=false: the right verdict. | |
| reviewed | No | checks: true = only the checks a person reviewed, false = only the others. | |
| trace_id | No | trace / label / judge: the trace id from lbb_query. | |
| workflow | No | experiments_estimate, experiments_create: the workflow to compare. experiments: only the experiments of this workflow. | |
| embedding | No | golden: the embedding, for surface=search. | |
| golden_id | No | accept / delete: the golden id. | |
| max_items | No | experiments_estimate, experiments_create: run the dataset's first items only (default 200). | |
| reference | No | review_check with agree=false: the right answer. A rerank or label check: {"grades": {"<hit id>": 0..3}}; a route or fit check: {"picks": {"<question id>": "<option>"}}. | |
| unlabeled | No | traces: only traces without a label. | |
| consistency | No | run / run_answers / accept: strong reads the head, eventual the last published commit. | |
| max_cost_usd | No | experiments_estimate, experiments_create: the cost limit of both arms in US dollars (default 5). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare non-readonly, non-destructive, closed-world behavior. The description adds substantial operational context: run_answers executes each query server-side, experiments spend model budget and write nothing to the graph, review_check becomes the call's ground truth, run checks at the current commit, and dataset deletion lives in a sibling tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is front-loaded and the length is justified by 43 parameters and 26 actions, but it is delivered as one dense paragraph with little formatting. Many clauses are necessary, yet the wall-of-text presentation makes scanning harder than it should be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still explains what state reads return, what checks_summary contains, how experiment report.delta and confidence intervals work, and how run_answers results form a series. Given the complexity, it is complete enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 95%, but the description still adds meaning beyond the schema: the two label forms, b's model/revision mutual exclusion, the answers shape for run_answers, source={kind:test,id} for dataset creation, and reference structures for review_check. It also explains parameter combinations such as valid=false with sparql.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence establishes a specific domain: managed evals as ground truth for app questions and searches, then names the major resources (traces, labels, goldens, checks, datasets, experiments). It also distinguishes sibling behavior by routing dataset deletion to lbb_evals_delete, though the 26-action scope prevents a single compact verb-resource summary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use run versus run_answers, when to call experiments_estimate before experiments_create, when deletion belongs to lbb_evals_delete, and how to apply an experiment via lbb_model_choice_manage after user confirmation. It provides the kind of when/when-not/alternative guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_evals_deleteADestructiveIdempotent
Delete an Evals dataset by id, with its items. A later datasets_get or datasets_export of it answers 404, and the next save of its workflow test makes a new dataset. The server reads the dataset first, so the question names it and its item count. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The dataset's id (ds_…). | |
| graph | No | Graph to target; defaults to the connection's graph | |
| detail | No | Response detail level. Defaults to compact. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It goes well beyond the annotations by explaining that items are deleted, subsequent gets/exports return 404, the next workflow save creates a new dataset, and the server reads the dataset first to name it and its item count. It also details the approval flow, decline and blocked-client outcomes, and the LBB_MCP_DESTRUCTIVE=allow override.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the action and consequence, then proceeds through approval behavior. Each sentence adds operational information for a destructive tool, and none are wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive operation with no output schema, the description covers data loss scope, downstream effects, approval requirements, decline outcomes, and environment override behavior. An agent has enough context to call it correctly and understand the risks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents id, graph, and detail. The description confirms deletion is by id but adds no meaning about graph targeting or detail-level behavior beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Delete an Evals dataset by id, with its items.' This clearly distinguishes it from the read-oriented sibling lbb_evals and tells the agent exactly what entity is removed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by explaining post-deletion effects and what happens on later gets/exports, but it never explicitly states when to use this versus alternatives or when not to use it. The routing context is adequate but incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_filesARead-only
Files of the graph, read only. A file is a document the graph holds (its bytes and a Document entity). A file a workflow run wrote (a generated file, with an origin and an expires_at) has no Document and no Document IRI. It expires unless a person keeps it, so the list shows it only after that, and it is never evidence for a fact. The documents.parse workflow (lbb_workflows) reads the text layer of each PDF into pages with every line and its box. list shows 50 files a call, newest upload first, with their sha256, name, size, Document IRI and parse (status parsed, unsupported or failed, page_count); when more follow, next names the after of the next call (with the same filters). parse_status keeps the files of one parse status; waiting is a file not parsed yet. name keeps the files whose name holds a text, in any case. A filtered list reads the Documents of the published generation and names its commit (as_of_commit_seq). A file uploaded, renamed or parsed a moment ago can be missing from it until publication. pages reads parsed pages of one file (sha256, or name for an exact file name): from is the first 0-based page index (the page of a region and of a DocEntry or DocMention), to the page after the last one (default from+1). Each line comes as <line id> [x0,y0,x1,y1] <text>: the id is p-l, both from 1, and the box is normalized to the page (0 to 1, origin top left). contains keeps the lines that hold a text; max_lines caps the lines (default 200). When lines were left out, next names the from and line_offset of the next call. A file not parsed yet answers file_not_parsed.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | pages: the page index after the last one. Default from+1; at most 50 pages per call. | |
| from | No | pages: the first page index, 0-based. Default 0. | |
| name | No | list: only the files whose name holds this text, in any case. pages: the file's exact name, when you do not have its sha256. | |
| after | No | list: the next 50 files, from a previous call's next (pass the same parse_status and name). | |
| graph | No | Graph to target; defaults to the connection's graph | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| sha256 | No | pages: the file's SHA-256 (64 hex characters). | |
| contains | No | pages: only the lines whose text holds this, ignoring case. | |
| max_lines | No | pages: the most lines to return. Default 200. | |
| line_offset | No | pages: lines of the first page to skip, from a previous call's next. | |
| parse_status | No | list: only the files of this parse status; waiting is a file not parsed yet. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, the description discloses publication lag ('a moment ago can be missing from it until publication'), generation/commit snapshot semantics (as_of_commit_seq), generated-file expiration and non-evidentiary status, pagination page-size limits, and the file_not_parsed error response. This is genuinely rich behavioral context an agent cannot get from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and sentences largely earn their place, but the block is dense and sprawling, mixing list semantics, pages semantics, and snapshot caveats with little structural separation. It is information-heavy to the point of being hard to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates fully: it names the list return fields (sha256, name, size, Document IRI, parse status/page_count), the exact pages line format, pagination continuation fields, and error behavior. An agent has everything needed to call both actions correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 92%, but the description still adds substantial meaning: from is 0-based and equals the page of a region/DocEntry/DocMention, to defaults to from+1, the line-format and p<page>-l<line> id scheme with normalized boxes, contains ignores case, max_lines default 200, and how next maps to after/from/line_offset. It meaningfully supplements the schema rather than repeating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource ('Files of the graph, read only') and then defines what a file is, distinguishing document-backed files from workflow-generated files. It clearly delineates the two actions (list vs pages) so an agent knows exactly what each does, and it names lbb_workflows as the parse producer, giving sibling context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is spelled out per action: 'list shows 50 files a call, newest upload first' and 'pages reads parsed pages of one file'. Filters (parse_status, name), pagination conditions, and the generated-file expiration rule are described. There is no explicit 'use X instead of Y' routing against siblings, keeping it below a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_fit_sourcesARead-only
Fit from text, read only: fit sources declared on classes. A fit source names the fields of a class that hold text (transcripts, documents); the server reads every instance, proposes ontology changes (classes, properties, relations) with verbatim quotes, checks them, and files them as ontology suggestions with origin id fit:. list shows each source's status (progress, lag, instances read, proposals kept and dropped, suggestions per status, this month's spend, last error) and the stack's monthly budget; get shows one; preview shows the fields, every candidate field of the class and the text of sample instances, calls no model and stores nothing. Declare, refresh or dry-run with lbb_fit_sources_manage; list the suggestions with lbb_inspect action=ontology_suggestions.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | preview/declare/dry_run: the fields that hold the text, as embedding paths (transcript, label, about/label, <https://…>). Omit for the long text facts of the class. | |
| iris | No | preview: the instances to show instead of a sample. | |
| name | No | get: the fit source name. | |
| class | No | preview/declare/dry_run: the class IRI whose instances hold the text. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| sample | No | ||
| context | No | preview/declare/dry_run: one sentence about the text, e.g. "interviews with employees about their work processes" (at most 500 characters). | |
| exclude | No | preview/declare/dry_run: fields to drop from the automatic choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only, but the description adds substantial context: the server reads every instance, proposes ontology changes with verbatim quotes, checks them, and files suggestions under origin id fit:<name>. It also discloses that preview calls no model and stores nothing, and explains what list returns, including progress, lag, spend, and budget.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core read-only purpose, then moves through list/get/preview and alternatives. It is appropriately sized for a complex 10-parameter tool, though the long semicolon-heavy sentence could be easier to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description does much of the return-value work by explaining list status fields and budget, get behavior, and preview behavior. Combined with the read-only annotation, it gives enough context for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high at 80%, so the schema already carries much of the parameter meaning. The description adds useful action-specific context, especially for preview/declare/dry-run fields and the role of context and exclude, though it does not explicitly explain every parameter such as sample or iris beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific read-only resource and process: fit sources declared on classes, which read instances and propose ontology changes. It clearly distinguishes list/get/preview behavior and names sibling tools for related operations, so an agent can identify the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use lbb_fit_sources_manage for declare, refresh, or dry-run, and lbb_inspect action=ontology_suggestions to list suggestions. It also distinguishes preview as a no-model, no-storage operation, giving clear when-to-use guidance versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_fit_sources_deleteADestructiveIdempotent
Delete a fit source: the fit stops reading its class. The suggestions it filed stay. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The fit source name. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| detail | No | Response detail level. Defaults to compact. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the destructiveHint/idempotentHint annotations: it discloses what is destroyed vs preserved (suggestions stay), the required approval via MCP form elicitation, the decline path (approval_declined, nothing sent), the client fallback (approval_required), and the environment override LBB_MCP_DESTRUCTIVE=allow. This is unusually rich behavioral context for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and consequence, then layers the approval mechanics. Every sentence is substantively useful, though the approval-flow prose is dense and could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with no output schema, it fully covers consequences, the human approval requirement, error states, and the escape hatch. An agent has everything needed to call it correctly and predict outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so name, graph, and detail are already documented in the schema. The description adds no parameter-specific meaning (no clarification of what 'name' references or how 'detail' affects the approval output), so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Delete a fit source') and immediately clarifies the effect ('the fit stops reading its class. The suggestions it filed stay'), which distinguishes it from list/manage siblings like lbb_fit_sources and lbb_fit_sources_manage. An agent knows exactly what operation this is without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description describes consequences and the approval flow, implying this is a careful destructive action, but never states when to use this versus the manage sibling or when-not to use it. The usage context is implied rather than made explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_fit_sources_manageA
Declare, dry-run or refresh a fit source (fit from text). Run lbb_fit_sources action=preview first and show the user the text the fit reads. dry_run runs the models on the first part of up to 3 instances (at most 60 s; truncated when one did not finish) and returns every proposal with its quote, its support score and what the checks made of it; it files nothing but spends model budget. declare sets the class, the fields and the context; the job then reads every instance and files suggestions (an existing source changes only what you name). refresh asks the job to run now and returns the status at once; the job also runs by itself after each published commit, so poll lbb_fit_sources action=get for progress. Nothing changes the ontology until a person accepts a suggestion.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | preview/declare/dry_run: the fields that hold the text, as embedding paths (transcript, label, about/label, <https://…>). Omit for the long text facts of the class. | |
| name | No | The fit source name (refresh: required). | |
| class | No | preview/declare/dry_run: the class IRI whose instances hold the text. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| context | No | preview/declare/dry_run: one sentence about the text, e.g. "interviews with employees about their work processes" (at most 500 characters). | |
| exclude | No | preview/declare/dry_run: fields to drop from the automatic choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read-only/destructive/open-world axes, and the description adds real behavioral depth on top: dry_run files nothing but costs model budget and truncates at 60s/3 instances, declare files suggestions and only rewrites named fields, refresh returns immediately while the job also self-triggers after commits. The crucial safety fact — 'Nothing changes the ontology until a person accepts a suggestion' — is stated explicitly and is consistent with destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the verb triad and each sentence adds a distinct operational fact, so little is wasted. It is, however, a single dense run-on paragraph with semicolon-chained clauses, which makes it harder to scan than a short bulleted action breakdown would be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description steps in and sketches the returns for both dry_run (proposals with quote, support score, check results) and refresh (immediate status), plus the async follow-up via lbb_fit_sources action=get. Combined with the mutation/side-effect disclosure, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 88%, so the schema already documents `from`, `name`, `class`, `context`, `exclude` and `detail` well. The description adds only indirect hints ('sets the class, the fields and the context', 'only what you name'), leaving `graph` and `detail` unaddressed beyond the schema. Baseline 3 is appropriate when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb triad plus resource ('Declare, dry-run or refresh a fit source') and then defines each action separately, so the agent knows exactly what the tool does. It does not name the sibling `lbb_fit_sources` as the alternative preview surface in a way that distinguishes them cleanly — it only says to 'Run lbb_fit_sources action=preview first', which is a reference rather than a differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite sequence ('Run lbb_fit_sources action=preview first and show the user the text'), when to pick each action, and how to follow progress ('poll lbb_fit_sources action=get'). It also warns that dry_run spends model budget, which is a use-vs-avoid condition, not just a description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_inspectARead-only
Read graph context and exact graph facts. Actions: guide, graphs, publication, ontology, ontology_conformance, schema, ontology_search, metadata, entity, ontology_suggestions. graphs works before bootstrap; ontology_suggestions lists the ontology change suggestions that wait for review (or were decided); fact_count is how many graph facts (triplets and entity property rows) accepting one commits, and identity_count how many identities it links. publication reports whether writes are queryable. ontology and schema return complete entries with page_size, section and cursor; follow next until absent. schema reads active native ontology/SHACL metadata without running validation. Query asserted RDF/OWL axioms separately with lbb_query. ontology_conformance serves the durable report referenced by the pinned published root. entity with iri, or version=records/1 and entity_id or entity_type+key, returns a complete exact-term record, separate assertions and snapshot from RDF. as_of_commit_seq pins retained history; schema-bound historical selection is currently unsupported. Oversized records fail rather than truncate. Omitting the new selectors preserves the native attributes/relationships view. Use lbb_query with SPARQL property paths for precise path selection.
| Name | Required | Description | Default |
|---|---|---|---|
| iri | No | Authoritative full RDF IRI; selects the lossless records/1 read. | |
| key | No | Stable key with entity_type, resolved from the activated schema at the read snapshot. | |
| name | No | ||
| as_of | No | Unsupported for entity; use as_of_commit_seq for a retained commit snapshot. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | ||
| query | No | Ontology concept, term, or relation to search | |
| top_k | No | ||
| action | Yes | Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, ontology_suggestions, entity). | |
| cursor | No | Opaque lbb_inspect continuation. Repeat action and pass the returned next arguments; rejects changed metadata. | |
| detail | No | Response detail level. Defaults to compact. | |
| limits | No | Lossless records/1 section bounds. Exceeding a bound refuses the read instead of truncating it. | |
| status | No | Only suggestions in this state; default all | |
| section | No | Optional top-level array to inspect, e.g. entity_type_defs, relation_defs, property_defs, classes, or relations. Omit to page through all sections. | |
| version | No | ||
| entity_id | No | Entity id (hex); alternative to entity_type+name | |
| page_size | No | Maximum complete metadata entries per page; defaults to 50. Nested fields are never truncated; an oversized single entry returns serialized_json fragments to concatenate and parse. | |
| consistency | No | ||
| entity_type | No | ||
| schema_revision | No | Expected opaque schema revision for a records/1 read. | |
| as_of_commit_seq | No | Snapshot pin: reproduce the node's attributes and relationships as of this commit_seq. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint annotation by disclosing important behavior: oversized records fail instead of truncating, page_size returns complete entries and may emit serialized_json fragments to concatenate, as_of_commit_seq pins retained history, schema-bound historical selection is unsupported, and omitting selectors preserves the native attributes/relationships view. These are exactly the behavioral traits an agent needs before calling the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loads the purpose and action list, then attaches high-value operational details to specific actions. Every sentence carries information and there is little redundancy. A bulleted action breakdown could improve scanability, but the content is appropriately sized for a 21-parameter multi-action tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of an output schema and the tool's complexity, the description supplies substantial return-value and failure-mode context for many actions, including ontology, schema, entity, publication, and ontology_conformance. It does not explain every action, such as guide or metadata, and some parameter interactions remain implicit, but it is largely complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 71% schema description coverage and 21 parameters, the schema already documents many inputs. The description adds meaningful semantics for key parameters such as page_size, section, cursor, as_of_commit_seq, entity_id, entity_type+key, and records/1 selectors. It does not clarify every parameter, such as detail, consistency, or status, but it substantially compensates for the remaining gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Read graph context and exact graph facts," then enumerates the available actions. It also distinguishes this tool from lbb_query for RDF/OWL axiom queries and SPARQL property paths. The multi-action nature makes it broader than a single-purpose tool, but the purpose is still clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete routing guidance such as "graphs works before bootstrap," "schema reads active native ontology/SHACL metadata without running validation," and "Use lbb_query with SPARQL property paths for precise path selection." It also states that schema-bound historical selection is unsupported and that as_of should not be used for entity reads. It lacks a fully explicit when-not-to-use-this-tool rule, but the alternatives are clearly named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_model_choiceARead-only
Model choice, read only: which model each use of a model on the graph runs, and trials that test other models against the graph's ground truth (the checked calls: a person's review, else the judge's verdict). options shows per use the model it runs now (current), LBB's model (default), a switch (switched), its checked calls, and the models a trial can test with their efforts, prices and whether the server holds their key; available=false with a reason when trials cannot run. trials lists the trials, newest first, each with its report: calls compared, both models' right share, mean score (0 to 1), cost per call and median time, the difference with its 95% interval (delta, ci_low, ci_high), outcome (too_few, better, same, worse) and qualifies (meets the bar: at least 20 calls, at most 5 points worse at the low end, no more failures, cheaper or better). trial reads one trial with its compared calls; trial_call reads one call with both answers and the ground truth. switches lists the switched uses. choices lists the model choices of the workflow uses (extract, decide, embed): without workflow the environment's row of each use and each workflow's own choice; with workflow the row in force for each of its uses (its own, else the environment's, else the default). A row has scope (environment or workflow), model, source (person or default), since, by, the model before, the use's default and options (the models it can run, with efforts, list prices and whether the server holds their key). One page in data: has_more and next_cursor page it with cursor and limit. Start, stop, switch or revert, and set or remove a choice, with lbb_model_choice_manage.
| Name | Required | Description | Default |
|---|---|---|---|
| job | No | trials: only the trials of this use. | |
| use | No | choices: one use. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | trials: at most this many, newest first (default 20); choices: rows per page (default 50). | |
| action | Yes | ||
| cursor | No | choices: the next_cursor of the page before. | |
| detail | No | Response detail level. Defaults to compact. | |
| call_id | No | trial_call: a call id from the trial's calls. | |
| trial_id | No | trial / trial_call: the trial id. | |
| workflow | No | choices: a named workflow: the rows in force for it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true, the description adds substantial context beyond the annotation: trial eligibility (available=false with a reason), trial outcome categories, qualification thresholds, pagination via has_more/next_cursor, and the exact fields returned per action. It does not contradict the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and no sentence is pure fluff, but the description is a long, dense paragraph that is difficult to scan across six actions and ten parameters. Some phrasing, such as the pagination sentence, could be clearer and more structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex ten-parameter read tool with no output schema, the description explains each action's returned data, trial fields, pagination, and failure behavior. It provides enough detail for an agent to call the correct action and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high at 90%, but the description adds action-specific meaning: job restricts trials to a use, use restricts choices to one use, trial_id/call_id identify the requested trial or call, and workflow selects rows in force for that workflow. It also clarifies limit/cursor paging behavior beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (model choice) and states it is read-only, then enumerates the concrete actions: options, trials, trial, trial_call, switches, and choices. It clearly distinguishes this read tool from the mutation sibling lbb_model_choice_manage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains what each action returns and explicitly routes start/stop/switch/revert and set/remove operations to lbb_model_choice_manage. It does not give detailed criteria for choosing among the read actions, but their purposes are sufficiently clear from the described outputs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_model_choice_manageA
Model choice, writes. start tests a candidate model on the uses in jobs (without jobs, every use it can do that has checked calls): the server answers those checked calls again with the candidate and scores it and the model in use against the same ground truth. It changes no model and spends at most the trial budget ($3.00 by default) of model and judge cost; an open trial of the same use and candidate comes back as it is. Pick candidates from lbb_model_choice action=options (provider anthropic with an effort, or typesafe jev-latest). A trial runs by itself: poll lbb_model_choice action=trial until its status is no longer running. stop ends a trial; it keeps what it compared. switch makes the trial's use run its candidate on this graph from the next call on; only a trial that qualifies and compared with the model in use switches (ask to a Claude model, route to a Jev model). Show the user the trial's report (score, difference and interval, cost per call, time) and switch only what the user confirmed. revert puts the use back on LBB's model. put_choice chooses the model of a workflow use (use extract or decide, provider, model, effort) for the environment, or for one workflow with workflow: the next calls run it. Pick the model from the row's options in lbb_model_choice action=choices, show the user the price per million tokens of the model in use and of the new one, and set only what the user confirmed. delete_choice removes a choice: the use runs the environment's choice, else its default; it answers {id, object, deleted: true}. Both change only the model of future calls and remove no data, so neither asks for approval.
| Name | Required | Description | Default |
|---|---|---|---|
| job | No | revert: the use to put back on LBB's model. | |
| use | No | put_choice / delete_choice: the workflow use. | |
| days | No | start: the days the trial takes new checks (default 14). | |
| jobs | No | start: the uses to test it on. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| model | No | start / put_choice: the model id, e.g. claude-haiku-5-5 or jev-latest. | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| effort | No | start / put_choice: the effort of a Claude model. | |
| target | No | start: the calls to compare (default 40). | |
| provider | No | start: the candidate's provider; put_choice: the model's provider (mock only on a local server). | |
| trial_id | No | stop / switch: the trial id. | |
| workflow | No | put_choice / delete_choice: a named workflow of the graph; absent for the environment. | |
| experiment | No | put_choice: an experiment (exp_…) whose B this choice applies, with workflow; use and the model are B's change. The workflow must still run the experiment's A, else experiment_outdated; when it runs B already, nothing changes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations setting readOnlyHint=false and destructiveHint=false, the description adds substantial extra context: start changes no model and spends at most the trial budget ($3.00 by default), stop keeps comparisons, switch only applies to qualifying trials, and put_choice/delete_choice change only the model of future calls and remove no data. This is behaviorally rich and consistent with 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is dense but largely earns its place across six actions and fourteen parameters. However, it is delivered as a single run-on paragraph without delimiters or bullets between actions, which makes it harder to scan than necessary for a multi-action tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 14-parameter, six-action tool with no output schema, the description covers the important action behaviors, budget limit, polling workflow, confirmation policy, and delete_choice's return shape. It does not explain return values for most other actions, but the annotations and high-coverage schema fill much of the remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 93%, and the schema already maps each parameter to its relevant actions and explains enums. The description reinforces that action mapping in prose but adds little parameter meaning beyond what the schema already provides, so the high-coverage baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific domain ('Model choice, writes') and then enumerates each action's verb and resource: start tests a candidate model, stop ends a trial, switch makes a use run its candidate, revert puts a use back, put_choice chooses a workflow model, and delete_choice removes a choice. It also distinguishes this write-oriented tool from the read-oriented sibling lbb_model_choice, which supplies options, choices, and trial status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives action-specific when-to-use guidance and names the alternatives: pick candidates from lbb_model_choice action=options, poll lbb_model_choice action=trial until status is no longer running, and use switch only for a qualifying trial with the correct Claude/Jev pairing. It also states confirmation requirements for switch and put_choice, so the agent knows both when and how to invoke each action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_modelsCRead-only
Read model-training inputs or compare retrieval configurations over one pinned published snapshot, or read what the managed models did. shadow_eval takes the API ShadowEvalRequest body; dataset actions return bounded training examples at an optional signal split. activity reads one month of the stack's model use (all graphs): calls, items, estimated tokens and cost per feature (index, search, fit, judge, training, rerank, rewrite, trial, workflows) and model, by day and by graph, the workflows' calls per workflow and job (by_workflow), the months with activity, and the model each feature uses now.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | ||
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | ||
| month | No | activity: the month, yyyy-mm (UTC). Defaults to the current month. | |
| action | Yes | ||
| detail | No | Response detail level. Defaults to compact. | |
| split_seq | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is consistent with the description's purely read-oriented actions (no contradiction), and the description adds useful behavior beyond annotations: bounded training examples at an optional signal split, one pinned snapshot, activity defaulting to the current month. It omits permissions, pagination/limit behavior, and the 'compact/standard/full' detail implications, so it is additive but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The whole definition is a single dense run-on paragraph mixing all four actions, with the activity sentence ending in a long parenthetical feature list. It is not front-loaded per action and forces the reader to re-parse to figure out which clauses belong to shadow_eval versus the dataset actions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, four-action, nested-body tool with no output schema, the description does sketch what activity returns (calls, items, tokens, cost per feature and model, by day and by graph), which is valuable. It still leaves limit semantics, detail-level behavior, and per-action parameter applicability unstated, so it is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 43% schema coverage, the description does compensate partially: it explains that body is the API ShadowEvalRequest payload and that split_seq selects an optional signal split, neither documented in the schema. But it says nothing about limit or the detail enum's effect, and the action-to-parameter mapping (which params apply to which action) is left to inference.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names all four actions and gives each a concrete verb+resource: shadow_eval compares retrieval configurations over a pinned snapshot, the dataset actions return training examples, activity reports model usage. However, it never distinguishes this tool from close siblings such as lbb_evals or lbb_model_choice, so an agent cannot tell from the description alone why it should pick this tool for eval work rather than one of those.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use / when-not-to-use guidance and no alternative named. The only routing signal is implicit in the action names themselves ('shadow_eval', 'suggest_dataset', 'extractor_dataset', 'activity'), which the schema already exposes as an enum, so the description adds almost nothing about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_queryARead-only
Analytical and expert reads. Modes: question (a question in plain words), structured (SPARQL-subset JSON body), sparql (SPARQL text), search (instances by meaning over every searchable class; filter narrows by class and relationship; every hit checked against the graph), analyze, and four tools for writing your own queries: names, describe, commit_at, compare. names: before a query that names an entity (a person, a company), find its IRI with text=; use the first candidate, not a CONTAINS match on the name. describe: before a query on classes or properties you have not seen, read them with question= (or classes/properties as IRIs): how many sampled instances hold each property (a filter on a rare one returns few rows), the values of small classes such as stages, examples and schema statements. commit_at: for a question about a date, find the commit of date=YYYY-MM-DD (or moment=RFC 3339), then run mode=sparql as_of_commit_seq=. compare: for what changed between two points, run one SELECT at before and after (default the latest) with key=[the entity variable]; added, removed and changed come with totals and pages (next). Use mode=question when you have a question in plain words and no SPARQL query: the server picks the kind of question (route), runs queries in a bounded loop, reads their rows, and answers in plain words (about 8 s). The result holds the answer with citations and a chart hint (kind, x, y: columns of the rows), the steps, the route, and the query and rows the answer stands on. Continue or correct that query with mode=sparql. Each question uses model tokens and counts toward a daily limit of the stack. SPARQL is the query language; search finds what the words describe. SPARQL text can also search by meaning inside the query with ?x https://littlebigbrain.com/search#similarTo "words", so the other patterns filter and join the hits in one query; the result's search field reports the plan. To plan a search: lbb_embeddings action=list, then SPARQL for a class's relationships on a sample, then mode=search with explain=true to check the resolved filter before the real search (lbb_inspect action=guide has the queries). Use the exact IRIs returned by names, describe or RDF. Native records use content-addressed entity IRIs, https://littlebigbrain.com/r/NAME relations and https://littlebigbrain.com/class/NAME types (lowercased); imported RDF may use any vocabulary. Never build an entity IRI from a display name. Structured and text queries pin one published watermark for the request.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | compare: the variables that identify a row's entity, e.g. ["contact"]. With a key the rows are paired: added and removed hold the entities at one point only, changed the entities whose values differ. Without one whole rows are compared. | |
| body | No | Structured SPARQL-subset request body. Shape: { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having?, order_by?, select?, limit?, distinct? }. Each pattern term is { var: "x" } or a fixed { entity: { entity_type, name } }; `predicate` is a relation name and is case-insensitive here (FOR_CLIENT and for_client both resolve — unlike SPARQL text, which needs the lowercased IRI local name). FILTER — `filters` is a list of conditions, each of exact shape { "compare": { "op": <op>, "left": <term>, "right": <term> } } (or { "and": [<filter>…] }, { "or": [<filter>…] }, { "not": <filter> }). `op` is one of eq | ne | lt | le | gt | ge (NOT the symbols =,<,>). Each <term> is exactly one of { "var": "x" }, { "property": { "var": "x", "field": "amount" } } (a typed scalar attribute), or { "value": <typed> } — and <typed> is exactly one wrapper: { "str": "…" }, { "i64": 5 }, { "f64": 0.9 }, { "bool": true }, { "date_time": "2026-01-01" } (RFC3339), or { "entity": { "entity_type": "T", "name": "N" } }. Complete runnable example — deals whose amount ≥ 1000000: { "patterns": [{ "subject": { "var": "d" }, "predicate": "for_client", "object": { "var": "c" } }], "filters": [{ "compare": { "op": "ge", "left": { "property": { "var": "d", "field": "amount" } }, "right": { "value": { "f64": 1000000 } } } }] }. Comparisons use the field's real declared type (numbers as numbers, datetimes as instants), so they run server-side. GROUP BY supports both entity-identity keys (group_by: ["s"]) and typed scalar keys via group_keys: a property value ({ property: { var, field, as } }) or a calendar bucket of a datetime property ({ date_bucket: { var, field, granularity: year|month|week|day|hour, as } }). Scalar keys come back per group under value_keys[as] — so a per-area breakdown or a commits-per-month time series is one server-side query, no client-side bucketing. Worked example -- commits per area per month in one query: { "patterns": [{ "subject": { "var": "c" }, "predicate": "committed_to", "object": { "var": "repo" } }], "group_keys": [{ "date_bucket": { "var": "c", "field": "committed_at", "granularity": "month", "as": "m" } }, { "property": { "var": "c", "field": "area", "as": "area" } }], "aggregates": [{ "func": "count", "as": "n" }], "order_by": [{ "var": "m" }] } -- area and committed_at are typed entity attributes (set via entity_properties; readable flat under attributes, never a nested metadata blob), and each group returns value_keys.m + value_keys.area + aggregates.n. `having: [...]` takes the same filter shape over the aggregated groups (e.g. { "compare": { "op": "gt", "left": { "var": "n" }, "right": { "value": { "i64": 10 } } } }). A `combinators` key (UNION/OPTIONAL/MINUS/EXISTS) is rejected here; express those with SPARQL text under mode=sparql. Cheap aggregate count: pair an equality having (e.g. { "compare": { "op": "eq", "left": { "var": "n" }, "right": { "value": { "i64": 4 } } } }) with row_limit: 1 -- the response row_page.total reports how many groups match without materializing them all, so you read the count off row_page.total instead of paging every matching row. For snapshot pinning use the top-level `as_of_commit_seq` argument or the same body field. Valid-time `as_of` and `as_of_valid_time` selectors are unsupported and rejected before HTTP. | |
| date | No | commit_at: YYYY-MM-DD; the last commit written by the end of that day (UTC). | |
| mode | Yes | Selects the variant (one of: structured, sparql, question, search, analyze, names, describe, commit_at, compare). | |
| text | No | search: the query text (required); embedded with the graph's model. names: the question, or the names, to find (required). | |
| after | No | compare: the later point; defaults to the latest commit. | |
| as_of | No | Unsupported in structured and SPARQL text modes; use as_of_commit_seq for a retained commit snapshot. | |
| chart | No | ||
| field | No | ||
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | question: rows each query of the server's loop returns, 1 to 1,000. Defaults by detail: compact=20, standard=100, full=1000. names: candidates per name, 1 to 10 (default 5). compare: entries of each list per page, 1 to 1,000 (defaults by detail: 20, 100, 500). | |
| probe | No | Clusters to read (default 4·√clusters, at least 8). More reads cost latency and find more. | |
| query | No | SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. Imported RDF retains its exact, case-sensitive IRIs. Use returned IRIs unchanged; lbb_inspect action=entity iri=<full IRI> reads any subject with records/1. The following convention applies only to native records: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> "Acme"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo "card payments" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding "name" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks. compare: the SELECT to run at both points; leave out LIMIT. | |
| route | No | question: the kind of question, when you know it. Omit it and the router model picks it. | |
| top_k | No | ||
| anchor | No | question: entity IRIs the question is about, at most 10 (for example the record the user has open). The server reads each one, and its queries use these IRIs directly instead of matching their names. | |
| before | No | compare: the earlier point (required): {"as_of_commit_seq": n}, {"date": "YYYY-MM-DD"} or {"moment": "RFC 3339"}. | |
| cursor | No | Opaque cursor from a previous lbb_query row page; reruns the original query at the next offset. | |
| detail | No | Response detail level. Defaults to compact. | |
| filter | No | Conditions every hit must meet: {"class": …} or {"via": …, "to": …}. The response's filter shows how each condition resolved; an unknown relationship or name answers with the options. | |
| metric | No | ||
| moment | No | commit_at: RFC 3339, e.g. 2026-06-18T12:00:00Z; the last commit written at or before it. | |
| rerank | No | true: the managed rerank model (Jev) orders the best hits by how well each answers the text, and each hit gets its relevance (0 to 1); adds about 0.3 s. false: the similarity order. Omit it to follow the graph's search setting. | |
| sparql | No | ||
| classes | No | describe: class IRIs to describe, at most 20. | |
| context | No | question: notes for the model, at most 8,000 characters: what the data means, units, names to prefer. | |
| explain | No | Plan without running: the scope, the resolved filter, and the allowed count. No model call. | |
| include | No | text: return the embedded text of each hit. | |
| request | No | The user's own words behind this query (managed evals). When present the server records an eval trace and the result carries its trace_id; label the rows valid or not with lbb_evals action=label. Omit on continuation pages. | |
| max_rows | No | compare: rows to read per point, 1 to 50,000 (default 20,000). Past it the result says truncated. | |
| question | No | question: the question in plain words (required), 1 to 4,000 characters. The server's model runs queries on this graph, reads their rows, and answers. describe: the question whose classes and properties to describe. | |
| timeline | No | question: dated points that stand for the graph's commits, at most 200. A question about a date reads the commit of the latest point on or before it. Use it when the commits stand for other dates than the days they were written (a demo's milestones, an import of old records); without it the server reads the last commit written by the end of that day. | |
| embedding | No | One embedding by name (see lbb_embeddings action=list). Omit it to search every searchable class of the graph; each hit names its class. | |
| row_limit | No | Maximum query rows to return in this page. Defaults by detail: compact=20, standard=100, full=1000. | |
| entailment | No | Reasoning over the pinned RDF generation. Defaults to none. owl includes RDFS, inverse relationships and the supported OWL profile. | |
| properties | No | describe: property IRIs to describe, at most 50. | |
| consistency | No | Read consistency. strong requires publication through head; a pending response is retryable. | |
| compare_cursor | No | compare: the cursor of the page before, from next; pass it with the same arguments. | |
| min_indexed_seq | No | Read-after-write publication floor. Preserved across cursor pages. | |
| as_of_commit_seq | No | Snapshot pin: evaluate the body as of this commit_seq, hiding later commits. Errors if past head. Top-level alias for the body's `as_of_commit_seq` (either works for this one). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true, the description discloses important behavior: question mode runs model-backed queries in a bounded loop, takes about 8 seconds, consumes model tokens against a daily limit, and returns answers with citations, steps, route, and query rows. It also notes rerank latency, snapshot pinning semantics, consistency behavior, and that structured/text queries pin one published watermark.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the mode list and then provides substantial useful detail, but it becomes a dense, run-on block with repeated guidance about IRIs, search, and planning. For a 40-parameter tool some length is justified, yet several sentences restate schema-level conventions and could be moved into the schema or omitted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, nine modes, nested body shape, and lack of an output schema, the description is complete enough to use correctly. It explains result fields for question, search, compare, and pagination, plus snapshot, consistency, model-cost, and IRI-handling behaviors that an agent needs before calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already high at 88%, so the baseline is 3. The description adds meaningful mode-level semantics and cross-parameter workflow guidance for names, describe, commit_at, compare, filter usage in search, as_of_commit_seq, and search planning. Some parameters such as graph, chart, field, metric, and top_k are not explained in the description, leaving a small gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates every mode with a specific verb and resource: question answering, structured SPARQL-subset queries, SPARQL text, semantic search, analysis, name lookup, class/property description, commit lookup, and comparison. It also explicitly distinguishes itself from siblings such as lbb_inspect, lbb_embeddings, and lbb_evals. An agent can identify both the tool's broad role and each mode's purpose without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing guidance: use mode=question when you have plain words and no SPARQL, continue or correct with mode=sparql, call names before a query that names an entity, call describe before querying unseen classes/properties, use commit_at for date questions, and use compare for before/after changes. It also names alternatives and prerequisites, such as lbb_embeddings action=list for search planning and lbb_inspect action=guide for query examples.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_rdfADestructiveIdempotent
Store and extend complete RDF/OWL documents through MCP. import accepts Turtle/N-Triples/N-Quads/TriG without conversion; update executes INSERT DATA for additive edits. Replacing/removing axioms is unsupported; use a new versioned LBB graph for a revised document. Named RDF graphs are unsupported; Turtle/N-Triples use the default graph, and dataset formats must contain only default-graph quads. These write graph facts, distinct from lbb_configure's native schema metadata. A first RDF write selects RDF-native storage, which refuses later property-graph commits; choose the write workflow before bootstrap. Retries deduplicate by content unless idempotency_key is supplied. A completed write schedules publication; inspect action=publication and verify using lbb_query entailment=owl. An update with DELETE, CLEAR, DROP, MOVE or COPY asks the person to approve it first; the question quotes the operations that remove. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| graph | No | Graph to target; defaults to the connection's graph | |
| action | Yes | Selects the variant (one of: import, update). | |
| detail | No | Response detail level. Defaults to compact. | |
| format | No | ||
| source | No | Complete RDF document. Preserves OWL axioms, RDF lists, labels, comments, and external IRIs as graph facts. | |
| update | No | SPARQL INSERT DATA text to add axioms. Submitted unchanged. DELETE/WHERE/CLEAR and named graphs are currently unsupported and fail without mutation. | |
| base_iri | No | ||
| idempotency_key | No | ||
| blank_node_scope | No | Stable document scope for blank labels across import chunks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=true, but the description goes well beyond them: it explains content-based retry deduplication unless idempotency_key is set, the irreversible storage-mode selection that refuses later property-graph commits, named-graph rejection, approval gating via MCP form elicitation, and the approval_declined / approval_required / LBB_MCP_DESTRUCTIVE=allow outcomes. This is exactly the extra context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and variant behavior are front-loaded and nearly every sentence adds operational value for a 9-parameter mutation tool. There is mild redundancy in the approval passage, which states twice that the person is asked to approve destructive update operations, and the sentences are long and dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive write tool with no output schema, the description covers storage-mode consequences, format restrictions, approval flows, failure modes (approval_required, approval_declined), and post-write publication verification. An agent has what it needs to call this safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
At 67% schema coverage the description meaningfully extends the schema: it pins 'update' to SPARQL INSERT DATA, clarifies that 'source' is a complete document preserving OWL axioms, and explains idempotency_key and graph/default-graph constraints. base_iri and detail are not addressed, so it stops short of full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Store and extend complete RDF/OWL documents') and immediately differentiates the two variants (import vs update with INSERT DATA). It also names siblings it is not: 'distinct from lbb_configure's native schema metadata' and 'verify using lbb_query entailment=owl'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance per variant (import for whole documents, update for additive INSERT DATA) and explicit when-not guidance ('Replacing/removing axioms is unsupported; use a new versioned LBB graph'). It also routes to alternatives (lbb_query for verification, lbb_configure for schema metadata) and warns to choose the write workflow before bootstrap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_reviewsARead-only
Review items, read only: questions for a person (human in the loop) that workflows, integrations, agents and people file. Kinds and their decisions: change (accept an ontology change, identities or facts: accept, reject, cant_tell), value (confirm one value of a property, question.property and question.value: accept, correct with the right value, reject, cant_tell; accept and correct commit the value), choice (pick one of question.options: choose with option, cant_tell), grade (grade question.output on the scale question.options: choose with option, cant_tell), answer (answer question.prompt in words: accept with the text in note, cant_tell). Status is open, answered or withdrawn. Scope is live (default) or test: a test item writes nothing. list returns one page as the server sends it ({object, data, has_more, next_cursor}), the latest update first: pass next_cursor as cursor, with the same filters, for the next page. get reads one item (rev_…) with its question, evidence, answer and effects. patterns groups the live items that ask one decision, the largest first. Evals files the questions of model checks (origin_id evals:checks), calibration sessions (evals:calibration), golden queries (evals:golden) and the values the two arms of an experiment differ on (evals:datasets) as grade and choice items; eval_id keeps the items of one record (for evals:datasets, the dataset), and their answer is the record's label. An item of evals:datasets asks whether one value is right or wrong, and the origin names the dataset item, the property and the value. File, answer, comment on or withdraw items with lbb_reviews_manage.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | get: the item's id, rev_… (or the sg_… of a change). | |
| key | No | list: the items filed under this producer key, or these keys (at most 100). | |
| run | No | list: the items of the run that asked. | |
| kind | No | list: one kind, or a list of kinds. | |
| type | No | patterns: only the patterns of this kind of suggestion. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | list: items per page, at most 5, 20 or 100 by detail (compact, standard, full) and by default that many, so the page comes back whole. | |
| scope | No | list: live (the default) or test. | |
| action | Yes | ||
| cursor | No | list: the next_cursor of the page before. | |
| detail | No | Response detail level. Defaults to compact. | |
| status | No | list, patterns: only the items in this state. | |
| eval_id | No | list, patterns: the items Evals filed for one record (eval.id): a calibration session, a model call's check, a golden, a dataset. | |
| workflow | No | list: the items of the workflow that asked. | |
| origin_id | No | list, patterns: the producer's id, for example starter:areas. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description stays consistent while adding real operational context: list returns one page shaped as {object, data, has_more, next_cursor} with newest first, cursor must be reused with the same filters, scope=test writes nothing, and limit is capped by detail level. These are behaviors not derivable 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is dense with useful information, but it arrives as one long run-on paragraph mixing purpose, decision taxonomy, pagination, and Evals provenance. It is front-loaded on purpose but not scannable; splitting the kind/decision table from the paging contract would cost nothing and gain a lot.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 15-parameter, three-action tool with no output schema, the description covers the return shape of list, the contents of get (question, evidence, answer, effects), and the grouping behavior of patterns, which is what an agent needs before calling. Minor gaps remain around how filters compose across key/run/workflow/origin_id.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 93%, so the baseline is 3, but the description adds genuine meaning on top: what cursor must be paired with, that scope=test is non-writing, what the decisions mean per kind (accept/correct/reject/cant_tell and their commit effects), and that eval_id scopes to one record. The graph parameter and some filter interplay remain schema-only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Review items, read only') and then enumerates the five item kinds with their decisions, which is far beyond restating the name. It also explicitly separates itself from the sibling that mutates: 'File, answer, comment on or withdraw items with lbb_reviews_manage.' An agent can pick this over lbb_reviews_manage without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The read-only boundary and the routing to lbb_reviews_manage for all writes is an explicit when-not rule. It also explains each of the three actions (list/get/patterns) and the pagination contract. It does not differentiate this from adjacent read siblings such as lbb_evals or lbb_inspect, which is the remaining gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_reviews_manageADestructive
File, answer, comment on or withdraw review items. Show the item to the user and answer only what the user decided. Kinds and their decisions: change (accept an ontology change, identities or facts: accept, reject, cant_tell), value (confirm one value of a property, question.property and question.value: accept, correct with the right value, reject, cant_tell; accept and correct commit the value), choice (pick one of question.options: choose with option, cant_tell), grade (grade question.output on the scale question.options: choose with option, cant_tell), answer (answer question.prompt in words: accept with the text in note, cant_tell). Status is open, answered or withdrawn. Scope is live (default) or test: a test item writes nothing. An answer that accepts or corrects a value item, or accepts a change item, commits facts or applies an ontology change (which can remove types and relations): the server reads the items and asks the person to approve first, with the count and the effect. Any other answer, such as the grade or choice of an item Evals filed, asks nothing. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow. create files an item of kind value, choice, grade or answer (kind, title, question, and optionally subject, evidence, rationale, key, scope, facts, origin); the same key again updates it, and an answered item comes back unchanged. File an ontology change with lbb_configure action=suggest_ontology_change. answer records the person's answer (decision, with value for correct, option for choose, note). An item has one answer: the same answer again returns the item, another one answers 409 review_answered. revision is the revision the person saw; a later one answers 409 review_stale. answer_batch gives one answer to up to 500 ids. comment adds text to an item's discussion. withdraw takes back an item you filed, with a reason. Each write sends an idempotency key, and a retry after a network failure or a 5xx sends the same key, so the write happens once.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | answer, comment, withdraw: the item's id (rev_…). | |
| ids | No | answer_batch: 1 to 500 item ids. | |
| key | No | create: your key for the item; the same key again updates it. Default: from the kind, subject and question. | |
| eval | No | create: the model check, calibration or test that asks. | |
| kind | No | create: the kind of question. | |
| text | No | comment: the comment, 1 to 4,000 characters. | |
| wait | No | create: the engine identity and turn of a run that waits for the answer as the signal review.<id>. | |
| facts | No | create, a value item: the facts that accept or correct commits, as lbb_commit takes them (at most 200 triplets and property rows together). | |
| graph | No | Graph to target; defaults to the connection's graph | |
| scope | No | create: live (default) or test (writes nothing). | |
| title | No | create: the question in words, at most 200 characters. | |
| action | Yes | ||
| answer | No | answer, answer_batch: the answer, { decision, value, option, note }. | |
| author | No | comment: who writes it. | |
| detail | No | Response detail level. Defaults to compact. | |
| origin | No | create: the producer. Default {"kind": "agent", "id": "mcp agent"}. | |
| reason | No | withdraw: why, at most 1,000 characters. | |
| subject | No | create: the record the question is about. | |
| evidence | No | create: the quotes you read, and where they are. | |
| question | No | create: what the item asks, by kind. | |
| revision | No | answer: the revision of the item the person saw. | |
| workflow | No | create: the workflow run and step that asks. | |
| rationale | No | create: why a person sees it, at most 4,000 characters. | |
| evidence_hash | No | create: a mark of the evidence (a document version, a hash of the text). Asking again with other evidence and another proposal reopens an answered item. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Far beyond the annotations: it discloses that accepting a change or accepting/correcting a value commits facts or applies an ontology change that can remove types and relations, that approval flows through MCP form elicitation with approval_declined and approval_required outcomes, and that LBB_MCP_DESTRUCTIVE=allow bypasses the client question. It also names 409 review_answered and 409 review_stale and the idempotency-key retry contract, all consistent with destructiveHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is well front-loaded, but the body is a dense block that restates the approval flow twice ('the server reads the items and asks the person to approve first' and again 'The server asks the person to approve it through the client'), and mixes create, answer, comment and withdraw semantics without paragraphing. Every fact is defensible but the packaging makes it hard to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 24-parameter, five-action tool with nested objects and no output schema, the description covers actions, per-kind decisions, approval and error outcomes, scope and idempotency. It never indicates what a successful response contains beyond 'returns the item' / 'comes back unchanged', which is a real gap given the absence of an output schema, though the detail parameter partially signals shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 96%, so the schema already documents most parameters and the baseline is 3. The description still adds real meaning the schema does not: which decision each kind accepts, that value/option/note are conditional on the decision, that 'the same key again updates it' for create, that an item has exactly one answer, and the 1-500 bound on answer_batch.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names five concrete verbs against one resource ('File, answer, comment on or withdraw review items'), mapping directly onto the action enum, and the resource is distinguishable from the read-only sibling lbb_reviews. The follow-up detail on kinds and decisions sharpens rather than restates the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Strong internal routing: it states when to use each action, that an ontology change must go through lbb_configure action=suggest_ontology_change instead of create, and that test scope writes nothing. It never explicitly contrasts this tool with the sibling lbb_reviews (read) or lbb_commit for direct commits, so a small inference is left to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_workflowsARead-only
Starter workflows and triggered workflows, read only. A starter workflow is a template; a triggered workflow is a workflow created from one on the graph. It watches a class: when a published commit adds or changes instances of the class (or changes the watched fields), the workflow reads them and does its work. search.embed keeps an embedding of the class (the same as lbb_embeddings); ontology.fit reads text fields and files ontology suggestions (the same as lbb_fit_sources); workflow (a developer workflow) sends the new and changed instances to a workflow of the developer's worker as trigger messages, and that code writes the facts the workflow owns. documents.parse reads uploaded PDF files into pages with line boxes, documents.link connects mentions of the same thing across the documents (it writes DocEntry and DocMention instances and links each mention to the entry that defines or describes it), documents.map proposes each link as a FactProposal in the graph's own ontology (fact_subject, fact_predicate, fact_object, fact_confidence, fact_evidence) for a review workflow, and values.extract fills chosen properties from text, each value with a quote; read the files and their pages with lbb_files. starters lists the starter workflows this server offers with their group, settings and whether each can run here. list shows every triggered workflow of the graph with its state (backfilling, ready, paused, failed, unavailable), lag, counters, this month's spend and last error; get shows one (starter and name) with its own status in details (for workflow: the messages sent, the instances waiting, the message in flight and whether it is paused). preview shows what creating one would do (the resolved watch, the instance count and the workflow's own preview; for workflow, the first messages it would send), calls no model and stores nothing. workflows lists the same workflows as workflows with triggers (/v1/workflows/named): each one's target workflow type (LBB's own are lbb.* types), its shards (engine identities starter. and starter..), its routing field, its window, its one watch trigger, its status and each shard's inbox, one page in data (has_more and next_cursor page them with cursor and limit); name for one. queue (name) shows what a workflow's watch has not sent yet: each waiting instance with its shard and its origin (a backfill, a commit range with the watched fields and the requests that changed it, a run now, a schema change), the pass in progress, and per shard its message in flight and its first unfinished turns with their origins; the items are in data, and has_more and next_cursor page them with cursor and limit. run_results (name) shows what the workflow's runs did with each input, newest run first: the input's IRI and label, its outcome (written, review, no_value, failed, duplicate) and its values (the value, the quote that states it, its support, the conversion, and the review item it went to); run keeps one run (with run_counts, every input by outcome), outcome keeps some outcomes, iri keeps one input; data, has_more and next_cursor page them. A run records its results when it ends; they are kept 30 days. revisions (name) shows the history of a workflow's settings, newest change first: each item is a revision (settings, the request that makes it, and an id wrev_… that is the hash of the settings) with who changed it, when, how (create, change, activate, existing) and bound (the one in use); a row whose revision was deleted has available false and no settings; has_more and next_cursor page it with cursor and limit (1 to 100, default 20). last_tested on a revision of a workflow that has tests (values.extract) says what the workflow's tests read with those exact settings: an object (test, finished, counts, and experiment when the test is an arm of an experiment) names the newest test that read inputs with them, null means no test is recorded for those settings, and no key means the workflow has no tests or the server does not say; it shows what happened and gives no verdict. revision (name, revision) reads one revision; compare two by their settings to say what changed. Each run summary names the revision it ran on. Message workflows of the workflow engine are not listed here. tests lists the graph's workflow tests, newest first, without texts and results (name: one workflow's tests), one page with next_cursor; tests_get reads one test (id) with its inputs' texts and, per input, each value read with its quote, its support and what the live workflow does with it (writes it, gives it to review, or drops it). A test goes queued, running, then done, failed or cancelled. Create, refresh, pause or resume with lbb_workflows_manage, which also starts, answers and cancels tests and goes back to an earlier revision with its action activate; delete with lbb_workflows_delete.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | tests_get: the test's id. | |
| iri | No | run_results: only the results of this input. | |
| run | No | run_results: one run's results (a run id), in input order. | |
| iris | No | preview: the instances to show instead of a sample. | |
| name | No | get: the triggered workflow's name. preview: the name a new workflow would get. workflows: one workflow's name (omit for all). queue, run_results, revisions and revision: required. tests: one workflow's tests (omit for all). | |
| owns | No | preview/use, developer workflow only: what your code writes. classes it creates instances of, relations it writes as out-edges of the watched instances, properties it writes on them. Owned outputs never trigger the workflow itself. | |
| batch | No | preview/use and define, developer workflow only: instances per message, 1 to 64 (default 16); for a stream, events per message, 1 to 500 (default 100). The server checks each kind's bound. | |
| class | No | preview/use: the class whose instances the workflow watches (an IRI, or a name the ontology knows). Required unless the starter workflow's watch is fixed. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| limit | No | queue: items per page, 1 to 100 (default 50). run_results: inputs per page, at most 5, 20 or 100 by detail (compact, standard, full), and by default that many. workflows: workflows per page, 1 to 100 (the server's default 100). tests: tests per page, at most 5, 20 or 50 by detail (compact, standard, full) and by default that many, so the page comes back whole. revisions: revisions per page, 1 to 100 (default 20). | |
| action | Yes | ||
| cursor | No | queue, tests, workflows, run_results and revisions: the next_cursor of the page before. | |
| detail | No | Response detail level. Defaults to compact. | |
| fields | No | preview/use: the fields whose change triggers the workflow, as embedding paths (transcript, label, about/label, <https://…>). Omit for the starter workflow's own choice. | |
| params | No | preview/use: the starter workflow's own settings, as listed in its catalog entry: search.embed takes model, dim and title; ontology.fit takes context (one sentence about the text, e.g. {"context": "interviews with employees"}); workflow takes none. | |
| sample | No | preview: how many sample instances to show. | |
| exclude | No | preview/use: fields to drop from the automatic choice. | |
| outcome | No | run_results: only the inputs of these outcomes. | |
| starter | No | The starter workflow's catalog id from action=starters, e.g. search.embed (embeddings on a class), ontology.fit (fit from text) or workflow (a developer workflow: your worker's workflow gets the instances). get/preview/use/refresh: required. pause/resume: omit to name a workflow with triggers. | |
| trigger | No | define: the trigger's id (default watch, content, schedule or stream). queue: the trigger whose queue to read. | |
| revision | No | revision: the revision's id (wrev_ and 32 hex characters). | |
| workflow | No | preview/use, developer workflow (starter=workflow) only, required there: the workflow of your worker that receives the messages. Creating it creates the instance starter.<name>. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Read-only claim is consistent with readOnlyHint=true. Beyond the annotation it discloses real behavioral facts: run results are kept 30 days, preview calls no model and stores nothing, last_tested 'shows what happened and gives no verdict,' and message workflows of the engine are excluded. Good added context for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single enormous run-on paragraph, several hundred words long, mixing purpose, per-starter explanations, per-action listing behavior and parameter notes. Little front-loading or structure; an agent must parse the whole block to find the action it needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For 11 actions and 22 parameters with no output schema, the description manages to describe what each action returns (list fields, queue items and origins, run outcomes and values, revision fields, test states). Cursor/has_more pacing is mentioned repeatedly. It is verbose but substantively complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 95%, so per-parameter descriptions already carry the load. The description adds some semantics the schema lacks (e.g. last_tested semantics on revisions, 'compare two by their settings'), but most parameter meaning is duplicated rather than extended, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with 'Starter workflows and triggered workflows, read only,' naming both the resource and the read-only scope, and closes by routing writes to lbb_workflows_manage / lbb_workflows_delete. The core purpose is unambiguous, but the middle of the description buries it under per-starter detail, so an agent must read far past the first sentence to confirm scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternatives: 'Create, refresh, pause or resume with lbb_workflows_manage... delete with lbb_workflows_delete,' and distinguishes preview ('calls no model and stores nothing') from actual use. Each action gets a short usage note. What's missing is any 'when to choose action=A vs action=B' beyond the terse per-action clauses.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_workflows_deleteADestructiveIdempotent
Delete a triggered workflow: it stops following its class, and what it wrote stays. Deleting search.embed deletes the embedding and its vectors, so its class stops being searchable; the suggestions an ontology.fit filed stay; a developer workflow leaves its workflow instance and the facts its code wrote. Without starter it deletes a workflow with triggers by its name, and its shards stay. The server asks the person to approve it through the client (MCP form elicitation) and sends nothing when they decline (approval_declined). A client that cannot show the question gets approval_required and nothing is sent, unless the MCP server's environment sets LBB_MCP_DESTRUCTIVE=allow.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The triggered workflow's name. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| detail | No | Response detail level. Defaults to compact. | |
| starter | No | The starter workflow's catalog id, e.g. search.embed. Omit for a workflow with triggers. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description specifies exactly what is deleted and what remains, including vectors, suggestions, workflow instances, and facts written by code. It also discloses the approval flow, approval_declined and approval_required outcomes, and the LBB_MCP_DESTRUCTIVE override, which is unusually rich behavioral context for a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and deletion effects, then proceeds to approval and error behavior. It is dense and occasionally run-on, but nearly every clause conveys operational detail that an agent needs before invoking a destructive tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex destructive operation with no output schema, the description covers deletion scope, data retention, starter-vs-trigger behavior, approval requirements, error outcomes, and environment override. This is complete enough for an agent to understand the consequences and failure modes before calling the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description adds real meaning for the starter parameter by explaining omission behavior and trigger-based deletion. It also clarifies that name refers to a triggered workflow's name, though graph and detail semantics are left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: deleting a triggered workflow, with clear effects on its class and written data. It is distinguishable from siblings by the delete operation, but it does not explicitly name or contrast with lbb_workflows_manage or other alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the starter-vs-trigger distinction and gives concrete examples such as search.embed and ontology.fit, which clarifies when each deletion mode applies. It does not explicitly state when not to use this tool or name an alternative tool for other workflow operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lbb_workflows_manageA
Create a workflow from a starter workflow, or refresh, pause or resume a triggered workflow. Run lbb_workflows action=preview first and show the user the watch and the instance count. use creates a workflow from a starter workflow of action=starters, under a name (default: the class's local name), with its watch (class, fields) and params; the workflow then reads every instance of the class and follows each published commit. A developer workflow (starter=workflow) also takes workflow (workflow_type and version of the developer's worker), owns and batch; it needs a server with the workflow engine. use again with the same starter and name changes only what you name, and the same request again changes nothing. A workflow that calls models (ontology.fit, documents.link, documents.map, values.extract) spends model budget as it reads. refresh asks the workflow to run now and returns at once with queued; poll lbb_workflows action=get for progress. pause stops a workflow (a developer workflow, documents.parse, documents.link, documents.map or values.extract) from reading and sending, and stops the claims of a developer workflow's shards; resume lets it catch up. Without starter, pause and resume name a workflow with triggers. search.embed and ontology.fit cannot be paused. define creates or changes a workflow with triggers of the developer's worker (/v1/workflows/named): name, workflow, one trigger (class and fields for a watch, media_types for a content trigger on uploads, schedule for one run per slot of a timer, or stream for the events a client sends, in batches), owns, batch, and shards (engine identities, 1 to 16), route_by (a field that keeps work in order) and window (messages queued per shard, default 4), and optionally budget_usd_per_month (the workflow's own monthly model budget), on_exhausted (block or skip) and fan_in (the id of a fan-in identity the shards send to); it needs a server with the workflow engine, and a change of shards waits for empty inboxes. run (name) runs a workflow with triggers now: its watch sends every instance again, a content trigger reads its log again, a schedule sends one run outside its slots, a stream sends its partial batches. activate (name, revision) makes an earlier revision of a workflow's settings (from lbb_workflows action=revisions) the one in use: it goes through the same checks as a change, and answers the workflow with its active_revision. Show the user what changes first (compare the settings of the two revisions), and when the revision's last_tested is null say that no test is recorded for those settings and ask before you activate (activation stays allowed), and pass expected_revision, the revision you read as bound, so a change by someone else since fails with workflow_revision_conflict. A revision whose settings the graph now reads differently fails with workflow_revision_stale; then change the workflow instead. Activating changes what the workflow does from then on and deletes no data, so it is not a destructive write; a change of the watch, the parameters or the gate makes the workflow read its class again, and work that waits or runs keeps the revision it started with. tests_create tests a values.extract workflow on chosen inputs before it writes: name (a workflow of the graph; starter defaults to values.extract) or install (a workflow not created yet, as use takes it: starter, name, watch, params, gate), and iris (at most 20) or sample (1 to 20, default 6), and models to try other models before choosing one. A test reads each input as the workflow would and calls its models (the calls count in the monthly workflow budget); it writes nothing to the graph. Poll lbb_workflows action=tests_get. tests_answer records the person's answer to one value of a read input (id, iri, property, answer: accept, reject, correct with value, or cant_tell; null removes it); it writes nothing to the graph. Answer only what the user decided. tests_cancel stops a queued or running test (id). Save a test's answers as a dataset with lbb_evals action=datasets_create.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | tests_answer, tests_cancel: the test's id. | |
| iri | No | tests_answer: the input, by its instance IRI. | |
| gate | No | use: outputs below this confidence go to review instead of the graph, for a workflow with a review gate. | |
| iris | No | tests_create: the instances to test, at most 20. | |
| name | No | The triggered workflow's name, [a-z0-9][a-z0-9-]{0,62} (refresh, pause, resume: required; use: omit for the class's local name; tests_create: the workflow of the graph to test). | |
| owns | No | preview/use, developer workflow only: what your code writes. classes it creates instances of, relations it writes as out-edges of the watched instances, properties it writes on them. Owned outputs never trigger the workflow itself. | |
| batch | No | preview/use and define, developer workflow only: instances per message, 1 to 64 (default 16); for a stream, events per message, 1 to 500 (default 100). The server checks each kind's bound. | |
| class | No | preview/use: the class whose instances the workflow watches (an IRI, or a name the ontology knows). Required unless the starter workflow's watch is fixed. | |
| graph | No | Graph to target; defaults to the connection's graph | |
| action | Yes | ||
| answer | No | tests_answer: { decision: accept | reject | correct | cant_tell, value (with correct), note }; null removes the answer. For a property without a value, accept says the text states none, and correct gives the value it states. | |
| detail | No | Response detail level. Defaults to compact. | |
| fan_in | No | define: the id of the workflow's fan-in identity (starter.<name>.<fan_in>) that the shards' turns send to, for example a catalogue. Default: none. | |
| fields | No | preview/use: the fields whose change triggers the workflow, as embedding paths (transcript, label, about/label, <https://…>). Omit for the starter workflow's own choice. | |
| models | No | tests_create: other models to run the test on, per use (extract, decide), each one of the use's options in lbb_model_choice action=choices. The test's models name the ones it ran. | |
| params | No | preview/use: the starter workflow's own settings, as listed in its catalog entry: search.embed takes model, dim and title; ontology.fit takes context (one sentence about the text, e.g. {"context": "interviews with employees"}); workflow takes none. | |
| sample | No | tests_create: the first instances of the watched class instead, 1 to 20 (default 6). | |
| shards | No | define: engine identities that receive the messages, 1 to 16 (default 1). A change needs every shard's inbox empty. | |
| stream | No | define, in place of class: a stream of the events a client sends (POST /v1/workflows/named/events), in batches of batch events (1 to 500, default 100) or after max_wait; each event's key routes it to a shard, and shards stay as made. | |
| window | No | define: messages the watch keeps queued per shard, 1 to 128 (default 4). | |
| exclude | No | preview/use: fields to drop from the automatic choice. | |
| install | No | tests_create: a workflow not created yet, as use takes it: starter (values.extract), name, watch ({class, fields, exclude}), params and gate ({below}). | |
| starter | No | The starter workflow's catalog id from action=starters, e.g. search.embed (embeddings on a class), ontology.fit (fit from text) or workflow (a developer workflow: your worker's workflow gets the instances). get/preview/use/refresh: required. pause/resume: omit to name a workflow with triggers. | |
| trigger | No | define: the trigger's id (default watch, content, schedule or stream). queue: the trigger whose queue to read. | |
| property | No | tests_answer: the property of the value. | |
| revision | No | activate: the revision to use (wrev_ and 32 hex characters). | |
| route_by | No | define: a field of the class whose value keeps work in order: the changes of one value go to one shard. Default: the instance. | |
| schedule | No | define, in place of class: a schedule. One message per slot, at least 5 minutes apart, to one shard; a slot runs even when nothing changed (the message's changed is false). | |
| workflow | No | preview/use, developer workflow (starter=workflow) only, required there: the workflow of your worker that receives the messages. Creating it creates the instance starter.<name>. | |
| experiment | No | activate: an experiment (exp_…) whose B this activation applies; revision is B's revision. The workflow must still run the experiment's A, else experiment_outdated; when B's revision is active already, nothing changes. | |
| media_types | No | define, in place of class: a content trigger on the uploads of these media types (application/pdf, image/*, */*), one content per message, without a wait for a publication. | |
| on_exhausted | No | define: what a turn that failed for good does to its shard: block (the default) holds the inbox until a person retries or skips it; skip keeps the failed turn in the history and goes on. | |
| expected_revision | No | activate: the revision the workflow had bound when you read it; another one fails with workflow_revision_conflict. | |
| budget_usd_per_month | No | use and define: a monthly model budget in USD for this workflow, below the stack's own. For define, its turns' activity calls stop at it (429 workflow_budget_exceeded) and the turn waits until the next month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite terse annotations, the description adds substantial behavior: idempotency ("the same request again changes nothing", "changes only what you name"), the explicit non-destructive rationale for activate ("changes what the workflow does from then on and deletes no data, so it is not a destructive write"), prerequisites (needs a server with the workflow engine), async behavior (refresh returns queued; poll action=get), and named failure modes (workflow_revision_conflict, workflow_revision_stale, experiment_outdated, 429 workflow_budget_exceeded). It also warns that model-calling workflows consume budget.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single unstructured paragraph of roughly 600 words covering ten actions and 34 parameters, with no headings, bullets or line breaks to let an agent locate the segment relevant to its chosen action. Nearly every clause is content-bearing, so the problem is organization rather than padding, but key constraints (preview-first, ask-before-activate) are buried mid-paragraph rather than front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-action, 34-parameter mutation tool with no output schema, the description covers prerequisites, ordering, conflict handling and follow-up calls (poll lbb_workflows action=get or tests_get; save answers via lbb_evals action=datasets_create) for nearly every action. Return values are only partly sketched (queued, active_revision), and the tests_* sub-flows are covered unevenly, but an agent could invoke all ten actions correctly from this text.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 97%, so nearly every one of the 34 parameters is already self-documented, including the nested workflow, schedule, stream, install and owns objects. The description mostly restates the same parameter semantics in prose (name defaults to the class's local name, shards 1-16, window default 4) rather than adding meaning the schema lacks. Some added value appears around expected_revision and gate behavior, but it is marginal relative to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives concrete verbs and a resource (create a workflow from a starter, refresh/pause/resume a triggered workflow), and later sentences explicitly cover define, run, activate and the three tests_* actions. It also distinguishes itself from the sibling lbb_workflows, which handles preview/get/starters/revisions. The gaps are that the headline verb list doesn't mention define/activate/tests, so an agent skimming the first line does not learn the tool's full scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit sequencing ("Run lbb_workflows action=preview first and show the user the watch and the instance count"), per-action applicability (starter is required for get/preview/use/refresh but omitted for pause/resume), exclusion rules ("search.embed and ontology.fit cannot be paused"), and human-in-the-loop instructions ("Show the user what changes first", "ask before you activate", "Answer only what the user decided"). Alternatives and when-not conditions are named rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.17.0- Changed
lbb_commit3 fields changed- added
Input schema / properties / expected_graph_epochAdded value: +{ + "description": "mode=records only: exact decimal graph incarnation guard. Protocol support does not activate this graph.", + "type": "string" +} - changed
Input schema / properties / mode / enumPrevious value: -[ - "facts", - "retract", - "search_feedback" -]New value: +[ + "facts", + "retract", + "search_feedback", + "records" +] - added
Input schema / properties / recordsAdded value: +{ + "additionalProperties": {}, + "description": "Explicit mode=records only: the unchanged RecordCommitRequest object with version=records/1. Unknown fields are preserved for strict server validation; no native IRI normalization or scalar coercion. Cannot mix legacy write arguments.", + "propertyNames": { + "type": "string" + }, + "type": "object" +}
- Changed
lbb_evals11 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "summary", - "traces", - "trace", - "label", - "judge", - "goldens", - "golden", - "accept", - "delete", - "run", - "run_answers", - "results", - "settings", - "checks_summary", - "checks", - "review_check", - "datasets", - "datasets_get", - "datasets_export", - "datasets_create", - "datasets_items" -]New value: +[ + "summary", + "traces", + "trace", + "label", + "judge", + "goldens", + "golden", + "accept", + "delete", + "run", + "run_answers", + "results", + "settings", + "checks_summary", + "checks", + "review_check", + "datasets", + "datasets_get", + "datasets_export", + "datasets_create", + "datasets_items", + "experiments", + "experiment", + "experiments_estimate", + "experiments_create", + "experiments_cancel" +] - added
Input schema / properties / bAdded value: +{ + "additionalProperties": false, + "description": "experiments_estimate, experiments_create: what B changes in A: {model: {use, model: {provider, model, effort}}} or {revision}, not both.", + "properties": { + "model": { + "additionalProperties": false, + "properties": { + "model": { + "additionalProperties": false, + "properties": { + "effort": { + "description": "The effort of a Claude model", + "type": "string" + }, + "model": { + "description": "A model of the use's options", + "type": "string" + }, + "provider": { + "description": "anthropic, typesafe or mock", + "type": "string" + } + }, + "required": [ + "provider", + "model" + ], + "type": "object" + }, + "use": { + "description": "The use whose model B changes", + "enum": [ + "extract", + "decide" + ], + "type": "string" + } + }, + "required": [ + "use", + "model" + ], + "type": "object" + }, + "revision": { + "description": "A kept settings revision of the workflow (wrev_…)", + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / cursor / descriptionPrevious value: -"datasets: the next_cursor of the page before."New value: +"datasets, experiments: the next_cursor of the page before." - added
Input schema / properties / datasetAdded value: +{ + "description": "experiments_estimate, experiments_create: the dataset (ds_…) whose items both arms run. experiments: only the experiments on this dataset.", + "type": "string" +} - changed
Input schema / properties / id / descriptionPrevious value: -"datasets_get, datasets_export, datasets_items: the dataset's id (ds_…)."New value: +"datasets_get, datasets_export, datasets_items: the dataset's id (ds_…). experiment, experiments_cancel: the experiment's id (exp_…)." - changed
Input schema / properties / items / descriptionPrevious value: -"label: several results at once, each {id, valid, note}. datasets_create, datasets_items: the examples, at most 500, each {name, text, values, leave_out, iri, case}; values and leave_out hold {property, value, accept, stated, quote, reason}."New value: +"label: several results at once, each {id, valid, note}. datasets_create, datasets_items: the examples, at most 500, each {name, text, values, leave_out, iri, case}; values and leave_out hold {property, value, accept, stated, quote, reason, source}; source says which person's answer gave a label (kind test or review, id, at): send it back as read, or leave it out." - changed
Input schema / properties / items / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "id": { - "type": "string" - }, - "note": { - "type": "string" - }, - "valid": { - "type": "boolean" - } - }, - "required": [ - "id", - "valid" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "case": { - "description": "What the example shows, in one sentence", - "type": "string" - }, - "iri": { - "description": "The instance the input came from", - "type": "string" - }, - "leave_out": { - "items": { - "additionalProperties": false, - "properties": { - "accept": { - "description": "Other spellings a text value may take, lower case", - "items": { - "type": "string" - }, - "type": "array" - }, - "property": { - "type": "string" - }, - "quote": { - "description": "Words of the text that state the value", - "type": "string" - }, - "reason": { - "description": "Why a value is left out", - "type": "string" - }, - "stated": { - "description": "The number and unit as the text states them, e.g. 450 mm", - "type": "string" - }, - "value": { - "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", - "type": [ - "number", - "string", - "boolean", - "null" - ] - } - }, - "required": [ - "property", - "value" - ], - "type": "object" - }, - "type": "array" - }, - "name": { - "description": "The input's name, unique in the dataset; the same name replaces", - "type": "string" - }, - "source": { - "additionalProperties": false, - "properties": { - "id": { - "type": "string" - }, - "kind": { - "enum": [ - "test", - "review", - "answer_key" - ], - "type": "string" - } - }, - "required": [ - "kind" - ], - "type": "object" - }, - "text": { - "description": "The input text, at most 40,000 characters", - "maxLength": 40000, - "type": "string" - }, - "values": { - "items": { - "additionalProperties": false, - "properties": { - "accept": { - "description": "Other spellings a text value may take, lower case", - "items": { - "type": "string" - }, - "type": "array" - }, - "property": { - "type": "string" - }, - "quote": { - "description": "Words of the text that state the value", - "type": "string" - }, - "reason": { - "description": "Why a value is left out", - "type": "string" - }, - "stated": { - "description": "The number and unit as the text states them, e.g. 450 mm", - "type": "string" - }, - "value": { - "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", - "type": [ - "number", - "string", - "boolean", - "null" - ] - } - }, - "required": [ - "property", - "value" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "note": { + "type": "string" + }, + "valid": { + "type": "boolean" + } + }, + "required": [ + "id", + "valid" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "case": { + "description": "What the example shows, in one sentence", + "type": "string" + }, + "iri": { + "description": "The instance the input came from", + "type": "string" + }, + "leave_out": { + "items": { + "additionalProperties": false, + "properties": { + "accept": { + "description": "Other spellings a text value may take, lower case", + "items": { + "type": "string" + }, + "type": "array" + }, + "property": { + "type": "string" + }, + "quote": { + "description": "Words of the text that state the value", + "type": "string" + }, + "reason": { + "description": "Why a value is left out", + "type": "string" + }, + "source": { + "additionalProperties": false, + "description": "Who gave the label and when: a person's answer on a test (wtest_…) or a review item (rev_…). Send it back as read, or leave it out", + "properties": { + "at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "test", + "review" + ], + "type": "string" + } + }, + "required": [ + "kind", + "id", + "at" + ], + "type": "object" + }, + "stated": { + "description": "The number and unit as the text states them, e.g. 450 mm", + "type": "string" + }, + "value": { + "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", + "type": [ + "number", + "string", + "boolean", + "null" + ] + } + }, + "required": [ + "property", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "name": { + "description": "The input's name, unique in the dataset; the same name replaces", + "type": "string" + }, + "source": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "test", + "review", + "answer_key" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "text": { + "description": "The input text, at most 40,000 characters", + "maxLength": 40000, + "type": "string" + }, + "values": { + "items": { + "additionalProperties": false, + "properties": { + "accept": { + "description": "Other spellings a text value may take, lower case", + "items": { + "type": "string" + }, + "type": "array" + }, + "property": { + "type": "string" + }, + "quote": { + "description": "Words of the text that state the value", + "type": "string" + }, + "reason": { + "description": "Why a value is left out", + "type": "string" + }, + "source": { + "additionalProperties": false, + "description": "Who gave the label and when: a person's answer on a test (wtest_…) or a review item (rev_…). Send it back as read, or leave it out", + "properties": { + "at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "test", + "review" + ], + "type": "string" + } + }, + "required": [ + "kind", + "id", + "at" + ], + "type": "object" + }, + "stated": { + "description": "The number and unit as the text states them, e.g. 450 mm", + "type": "string" + }, + "value": { + "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", + "type": [ + "number", + "string", + "boolean", + "null" + ] + } + }, + "required": [ + "property", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" + } +] - added
Input schema / properties / max_cost_usdAdded value: +{ + "description": "experiments_estimate, experiments_create: the cost limit of both arms in US dollars (default 5).", + "exclusiveMinimum": 0, + "maximum": 100, + "type": "number" +} - added
Input schema / properties / max_itemsAdded value: +{ + "description": "experiments_estimate, experiments_create: run the dataset's first items only (default 200).", + "maximum": 200, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / statusAdded value: +{ + "description": "experiments: only the experiments with this status.", + "enum": [ + "queued", + "running", + "done", + "failed", + "cancelled" + ], + "type": "string" +} - added
Input schema / properties / workflowAdded value: +{ + "description": "experiments_estimate, experiments_create: the workflow to compare. experiments: only the experiments of this workflow.", + "type": "string" +}
- Changed
lbb_model_choice_manage1 field changed- added
Input schema / properties / experimentAdded value: +{ + "description": "put_choice: an experiment (exp_…) whose B this choice applies, with workflow; use and the model are B's change. The workflow must still run the experiment's A, else experiment_outdated; when it runs B already, nothing changes.", + "type": "string" +}
- Changed
lbb_reviews1 field changed- changed
Input schema / properties / eval_id / descriptionPrevious value: -"list, patterns: the items Evals filed for one record (eval.id): a calibration session, a model call's check, a golden."New value: +"list, patterns: the items Evals filed for one record (eval.id): a calibration session, a model call's check, a golden, a dataset."
- Changed
lbb_workflows_manage1 field changed- added
Input schema / properties / experimentAdded value: +{ + "description": "activate: an experiment (exp_…) whose B this activation applies; revision is B's revision. The workflow must still run the experiment's A, else experiment_outdated; when B's revision is active already, nothing changes.", + "type": "string" +}
22 tool updates
v0.16.0- Changed
lbb_commit21 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / entity_embeddings / items / propertiesAdded value: +{ + "entity_id": { + "type": [ + "string", + "null" + ] + }, + "key": { + "type": [ + "string", + "null" + ] + }, + "metric": { + "anyOf": [ + { + "enum": [ + "cosine", + "dot", + "l2" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "model_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "vector": { + "items": { + "type": "number" + }, + "type": "array" + } +} - added
Input schema / properties / entity_embeddings / items / requiredAdded value: +[ + "type", + "name", + "model_id", + "vector" +] - added
Input schema / properties / entity_properties / items / propertyNamesAdded value: +{ + "type": "string" +} - removed
Input schema / properties / retract_edges / items / additionalPropertiesRemoved value: -false - removed
Input schema / properties / retract_edges / items / properties / source / additionalPropertiesRemoved value: -false - removed
Input schema / properties / retract_edges / items / properties / target / additionalPropertiesRemoved value: -false - removed
Input schema / properties / retract_entities / items / additionalPropertiesRemoved value: -false - changed
Input schema / properties / search_feedback / additionalPropertiesPrevious value: -trueNew value: +{} - changed
Input schema / properties / search_feedback / properties / labels / items / additionalPropertiesPrevious value: -trueNew value: +{} - added
Input schema / properties / search_feedback / properties / labels / items / properties / rank / maximumAdded value: +9007199254740991 - removed
Input schema / properties / search_feedback / properties / labels / items / properties / target / anyOfRemoved value: -[ - { - "additionalProperties": true, - "properties": { - "entity": { - "additionalProperties": true, - "properties": { - "entity_id": { - "description": "Entity id (hex), as an alternative to type+name", - "type": "string" - }, - "entity_type": { - "description": "Entity type name (with `name`, names a fixed entity)", - "type": "string" - }, - "name": { - "description": "Entity name (paired with `entity_type`)", - "type": "string" - } - }, - "type": "object" - }, - "kind": { - "const": "entity", - "type": "string" - } - }, - "required": [ - "kind", - "entity" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "edge_event_id": { - "type": "string" - }, - "kind": { - "const": "assertion", - "type": "string" - } - }, - "required": [ - "kind", - "edge_event_id" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "kind": { - "const": "observation", - "type": "string" - }, - "observation_id": { - "type": "string" - } - }, - "required": [ - "kind", - "observation_id" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "concept_id": { - "type": "string" - }, - "kind": { - "const": "concept", - "type": "string" - }, - "name": { - "type": "string" - } - }, - "required": [ - "kind" - ], - "type": "object" - } -] - added
Input schema / properties / search_feedback / properties / labels / items / properties / target / oneOfAdded value: +[ + { + "additionalProperties": {}, + "properties": { + "entity": { + "additionalProperties": {}, + "properties": { + "entity_id": { + "description": "Entity id (hex), as an alternative to type+name", + "type": "string" + }, + "entity_type": { + "description": "Entity type name (with `name`, names a fixed entity)", + "type": "string" + }, + "name": { + "description": "Entity name (paired with `entity_type`)", + "type": "string" + } + }, + "type": "object" + }, + "kind": { + "const": "entity", + "type": "string" + } + }, + "required": [ + "kind", + "entity" + ], + "type": "object" + }, + { + "additionalProperties": {}, + "properties": { + "edge_event_id": { + "type": "string" + }, + "kind": { + "const": "assertion", + "type": "string" + } + }, + "required": [ + "kind", + "edge_event_id" + ], + "type": "object" + }, + { + "additionalProperties": {}, + "properties": { + "kind": { + "const": "observation", + "type": "string" + }, + "observation_id": { + "type": "string" + } + }, + "required": [ + "kind", + "observation_id" + ], + "type": "object" + }, + { + "additionalProperties": {}, + "properties": { + "concept_id": { + "type": "string" + }, + "kind": { + "const": "concept", + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "kind" + ], + "type": "object" + } +] - added
Input schema / properties / search_feedback / properties / profile / anyOfAdded value: +[ + { + "enum": [ + "baseline", + "scored_atom_v1", + "graph_aware_v1", + "ndcg_v1" + ], + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / search_feedback / properties / profile / typeRemoved value: -"string" - added
Input schema / properties / search_feedback / properties / snapshot / propertyNamesAdded value: +{ + "type": "string" +} - removed
Input schema / properties / triplets / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / triplets / items / properties / evidence / anyOfAdded value: +[ + { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": {}, + "properties": { + "observation_id": { + "type": [ + "string", + "null" + ] + }, + "region": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "confidence": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "page": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "x0": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "x1": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "y0": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "y1": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "page", + "x0", + "y0", + "x1", + "y1", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "source_id": { + "type": [ + "string", + "null" + ] + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + } + ] + }, + { + "type": "null" + } +] - removed
Input schema / properties / triplets / items / properties / source / additionalPropertiesRemoved value: -false - removed
Input schema / properties / triplets / items / properties / target / additionalPropertiesRemoved value: -false - removed
Input schema / properties / triplets / items / properties / valid_time / additionalPropertiesRemoved value: -false
- Changed
lbb_configure40 fields changed- changed
Input schema / additionalPropertiesPrevious value: -trueNew value: +{} - removed
Input schema / properties / change / items / $refRemoved value: -"#/properties/ops/items" - added
Input schema / properties / change / items / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "entity_type": { + "type": "string" + }, + "op": { + "const": "add_super_types", + "type": "string" + }, + "super_types": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "op", + "entity_type", + "super_types" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_domain": { + "description": "Entity-type names to add to the relation's domain (source types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "add_range": { + "description": "Entity-type names to add to the relation's range (target types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "op": { + "const": "widen_relation", + "type": "string" + }, + "relation": { + "description": "Relation to widen, by name (case-insensitive)", + "type": "string" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Display name of the new entity type (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "description": "Defaults to many_to_many", + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "domain": { + "description": "Entity-type names allowed as the source (domain); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "inverse_name": { + "description": "Optional inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "name": { + "description": "Display name of the new relation, e.g. HAS_PHASE", + "type": "string" + }, + "op": { + "const": "add_relation", + "type": "string" + }, + "range": { + "description": "Entity-type names allowed as the target (range); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "reducer": { + "description": "State-reducer token, e.g. append_only (default), latest_wins", + "type": "string" + }, + "symmetric": { + "type": "boolean" + }, + "temporal_semantics": { + "description": "Defaults to bitemporal", + "enum": [ + "atemporal", + "valid_time", + "commit_time", + "bitemporal" + ], + "type": "string" + }, + "transitive": { + "type": "boolean" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_values": { + "description": "Enforced allowed values (sh:in): a commit with another value for the field is refused. For keyword, text, i64 and bool fields only", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "description": "Display name of the new scalar property field, e.g. status (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_property", + "type": "string" + }, + "required": { + "description": "Advisory required flag (not enforced on commit)", + "type": "boolean" + }, + "unit": { + "description": "Unit of an i64 or f64 field, e.g. mm, cm, kg, m2 or h. Writers that read text, such as values.extract, convert numbers to it", + "type": "string" + }, + "value_type": { + "description": "Scalar type; defaults to text. Lets a later lbb_commit set entity_properties[].field", + "enum": [ + "bool", + "i64", + "f64", + "date_time", + "keyword", + "text", + "bytes" + ], + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "op": { + "const": "set_property_unit", + "type": "string" + }, + "property": { + "description": "An existing i64 or f64 field, by name", + "type": "string" + }, + "unit": { + "description": "The unit's symbol, as add_property takes it; omit it to clear the unit. Stored values are not converted", + "type": "string" + } + }, + "required": [ + "op", + "property" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_values": { + "description": "The allowed values that later commits are checked against; empty or absent clears the constraint. Stored values are not checked again", + "items": { + "type": "string" + }, + "type": "array" + }, + "op": { + "const": "set_property_constraint", + "type": "string" + }, + "property": { + "description": "An existing field, by name", + "type": "string" + } + }, + "required": [ + "op", + "property" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current entity-type name", + "type": "string" + }, + "op": { + "const": "rename_entity_type", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; records keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current relation name", + "type": "string" + }, + "op": { + "const": "rename_relation", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; edges keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inverse_name": { + "description": "Inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "op": { + "const": "set_relation_inverse", + "type": "string" + }, + "relation": { + "description": "Relation to set the inverse on, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "inverse_name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "op": { + "const": "set_relation_cardinality", + "type": "string" + }, + "relation": { + "description": "Relation to change, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "cardinality" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "op": { + "const": "narrow_relation", + "type": "string" + }, + "relation": { + "description": "Relation to narrow, by name", + "type": "string" + }, + "remove_domain": { + "description": "Entity-type names to remove from the relation's domain (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + }, + "remove_range": { + "description": "Entity-type names to remove from the relation's range (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Entity type to tombstone — kept readable for old records, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Relation to tombstone — old edges stay readable, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_relation", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + } +] - changed
Input schema / properties / entity_types / items / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "additionalProperties": {}, - "type": "object" - } -]New value: +[ + { + "type": "string" + }, + { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } +] - added
Input schema / properties / evidence / properties / records / maximumAdded value: +9007199254740991 - removed
Input schema / properties / evidence / properties / samples / items / $refRemoved value: -"#/properties/entity_types/items/anyOf/1" - added
Input schema / properties / evidence / properties / samples / items / additionalPropertiesAdded value: +{} - added
Input schema / properties / evidence / properties / samples / items / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / evidence / properties / samples / items / typeAdded value: +"object" - added
Input schema / properties / expected_ontology_version / maximumAdded value: +9007199254740991 - added
Input schema / properties / expected_version / maximumAdded value: +9007199254740991 - removed
Input schema / properties / facts / properties / entity_properties / items / $refRemoved value: -"#/properties/entity_types/items/anyOf/1" - added
Input schema / properties / facts / properties / entity_properties / items / additionalPropertiesAdded value: +{} - added
Input schema / properties / facts / properties / entity_properties / items / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / facts / properties / entity_properties / items / typeAdded value: +"object" - removed
Input schema / properties / facts / properties / replace_owned / properties / retract_entities / items / $refRemoved value: -"#/properties/facts/properties/triplets/items/properties/source" - added
Input schema / properties / facts / properties / replace_owned / properties / retract_entities / items / additionalPropertiesAdded value: +{} - added
Input schema / properties / facts / properties / replace_owned / properties / retract_entities / items / propertiesAdded value: +{ + "key": { + "description": "The record's external key, when it has one", + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } +} - added
Input schema / properties / facts / properties / replace_owned / properties / retract_entities / items / requiredAdded value: +[ + "type", + "name" +] - added
Input schema / properties / facts / properties / replace_owned / properties / retract_entities / items / typeAdded value: +"object" - removed
Input schema / properties / facts / properties / replace_owned / properties / subjects / items / $refRemoved value: -"#/properties/facts/properties/triplets/items/properties/source" - added
Input schema / properties / facts / properties / replace_owned / properties / subjects / items / additionalPropertiesAdded value: +{} - added
Input schema / properties / facts / properties / replace_owned / properties / subjects / items / propertiesAdded value: +{ + "key": { + "description": "The record's external key, when it has one", + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } +} - added
Input schema / properties / facts / properties / replace_owned / properties / subjects / items / requiredAdded value: +[ + "type", + "name" +] - added
Input schema / properties / facts / properties / replace_owned / properties / subjects / items / typeAdded value: +"object" - changed
Input schema / properties / facts / properties / triplets / items / additionalPropertiesPrevious value: -trueNew value: +{} - added
Input schema / properties / facts / properties / triplets / items / properties / evidence / anyOfAdded value: +[ + { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": {}, + "properties": { + "observation_id": { + "type": [ + "string", + "null" + ] + }, + "region": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "confidence": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "page": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "x0": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "x1": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "y0": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "y1": { + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "page", + "x0", + "y0", + "x1", + "y1", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "source_id": { + "type": [ + "string", + "null" + ] + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + } + ] + }, + { + "type": "null" + } +] - changed
Input schema / properties / facts / properties / triplets / items / properties / source / additionalPropertiesPrevious value: -falseNew value: +{} - changed
Input schema / properties / facts / properties / triplets / items / properties / source / properties / key / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Input schema / properties / facts / properties / triplets / items / properties / target / $refRemoved value: -"#/properties/facts/properties/triplets/items/properties/source" - added
Input schema / properties / facts / properties / triplets / items / properties / target / additionalPropertiesAdded value: +{} - added
Input schema / properties / facts / properties / triplets / items / properties / target / propertiesAdded value: +{ + "key": { + "description": "The record's external key, when it has one", + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } +} - added
Input schema / properties / facts / properties / triplets / items / properties / target / requiredAdded value: +[ + "type", + "name" +] - added
Input schema / properties / facts / properties / triplets / items / properties / target / typeAdded value: +"object" - removed
Input schema / properties / ontology / properties / format / $refRemoved value: -"#/properties/format" - added
Input schema / properties / ontology / properties / format / enumAdded value: +[ + "auto", + "turtle", + "json_ld", + "rdf_xml", + "csv", + "tsv", + "lbb_json", + "spec" +] - added
Input schema / properties / ontology / properties / format / typeAdded value: +"string" - removed
Input schema / properties / ops / items / anyOfRemoved value: -[ - { - "additionalProperties": false, - "properties": { - "entity_type": { - "type": "string" - }, - "op": { - "const": "add_super_types", - "type": "string" - }, - "super_types": { - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "op", - "entity_type", - "super_types" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "add_domain": { - "description": "Entity-type names to add to the relation's domain (source types)", - "items": { - "type": "string" - }, - "type": "array" - }, - "add_range": { - "description": "Entity-type names to add to the relation's range (target types)", - "items": { - "type": "string" - }, - "type": "array" - }, - "op": { - "const": "widen_relation", - "type": "string" - }, - "relation": { - "description": "Relation to widen, by name (case-insensitive)", - "type": "string" - } - }, - "required": [ - "op", - "relation" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Display name of the new entity type (idempotent if it exists)", - "type": "string" - }, - "op": { - "const": "add_entity_type", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "cardinality": { - "description": "Defaults to many_to_many", - "enum": [ - "one_to_one", - "one_to_many", - "many_to_one", - "many_to_many" - ], - "type": "string" - }, - "domain": { - "description": "Entity-type names allowed as the source (domain); must already exist", - "items": { - "type": "string" - }, - "type": "array" - }, - "inverse_name": { - "description": "Optional inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", - "type": "string" - }, - "name": { - "description": "Display name of the new relation, e.g. HAS_PHASE", - "type": "string" - }, - "op": { - "const": "add_relation", - "type": "string" - }, - "range": { - "description": "Entity-type names allowed as the target (range); must already exist", - "items": { - "type": "string" - }, - "type": "array" - }, - "reducer": { - "description": "State-reducer token, e.g. append_only (default), latest_wins", - "type": "string" - }, - "symmetric": { - "type": "boolean" - }, - "temporal_semantics": { - "description": "Defaults to bitemporal", - "enum": [ - "atemporal", - "valid_time", - "commit_time", - "bitemporal" - ], - "type": "string" - }, - "transitive": { - "type": "boolean" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Display name of the new scalar property field, e.g. status (idempotent if it exists)", - "type": "string" - }, - "op": { - "const": "add_property", - "type": "string" - }, - "required": { - "description": "Advisory required flag (not enforced on commit)", - "type": "boolean" - }, - "value_type": { - "description": "Scalar type; defaults to text. Lets a later lbb_commit set entity_properties[].field", - "enum": [ - "bool", - "i64", - "f64", - "date_time", - "keyword", - "text", - "bytes" - ], - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "from": { - "description": "Current entity-type name", - "type": "string" - }, - "op": { - "const": "rename_entity_type", - "type": "string" - }, - "to": { - "description": "New display name (stable id stays frozen; records keep resolving)", - "type": "string" - } - }, - "required": [ - "op", - "from", - "to" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "from": { - "description": "Current relation name", - "type": "string" - }, - "op": { - "const": "rename_relation", - "type": "string" - }, - "to": { - "description": "New display name (stable id stays frozen; edges keep resolving)", - "type": "string" - } - }, - "required": [ - "op", - "from", - "to" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "inverse_name": { - "description": "Inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", - "type": "string" - }, - "op": { - "const": "set_relation_inverse", - "type": "string" - }, - "relation": { - "description": "Relation to set the inverse on, by name", - "type": "string" - } - }, - "required": [ - "op", - "relation", - "inverse_name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "cardinality": { - "enum": [ - "one_to_one", - "one_to_many", - "many_to_one", - "many_to_many" - ], - "type": "string" - }, - "op": { - "const": "set_relation_cardinality", - "type": "string" - }, - "relation": { - "description": "Relation to change, by name", - "type": "string" - } - }, - "required": [ - "op", - "relation", - "cardinality" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "op": { - "const": "narrow_relation", - "type": "string" - }, - "relation": { - "description": "Relation to narrow, by name", - "type": "string" - }, - "remove_domain": { - "description": "Entity-type names to remove from the relation's domain (subtractive)", - "items": { - "type": "string" - }, - "type": "array" - }, - "remove_range": { - "description": "Entity-type names to remove from the relation's range (subtractive)", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "op", - "relation" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Entity type to tombstone — kept readable for old records, rejected for new commits", - "type": "string" - }, - "op": { - "const": "remove_entity_type", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Relation to tombstone — old edges stay readable, rejected for new commits", - "type": "string" - }, - "op": { - "const": "remove_relation", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - } -] - added
Input schema / properties / ops / items / oneOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "entity_type": { + "type": "string" + }, + "op": { + "const": "add_super_types", + "type": "string" + }, + "super_types": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "op", + "entity_type", + "super_types" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_domain": { + "description": "Entity-type names to add to the relation's domain (source types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "add_range": { + "description": "Entity-type names to add to the relation's range (target types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "op": { + "const": "widen_relation", + "type": "string" + }, + "relation": { + "description": "Relation to widen, by name (case-insensitive)", + "type": "string" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Display name of the new entity type (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "description": "Defaults to many_to_many", + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "domain": { + "description": "Entity-type names allowed as the source (domain); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "inverse_name": { + "description": "Optional inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "name": { + "description": "Display name of the new relation, e.g. HAS_PHASE", + "type": "string" + }, + "op": { + "const": "add_relation", + "type": "string" + }, + "range": { + "description": "Entity-type names allowed as the target (range); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "reducer": { + "description": "State-reducer token, e.g. append_only (default), latest_wins", + "type": "string" + }, + "symmetric": { + "type": "boolean" + }, + "temporal_semantics": { + "description": "Defaults to bitemporal", + "enum": [ + "atemporal", + "valid_time", + "commit_time", + "bitemporal" + ], + "type": "string" + }, + "transitive": { + "type": "boolean" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_values": { + "description": "Enforced allowed values (sh:in): a commit with another value for the field is refused. For keyword, text, i64 and bool fields only", + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "description": "Display name of the new scalar property field, e.g. status (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_property", + "type": "string" + }, + "required": { + "description": "Advisory required flag (not enforced on commit)", + "type": "boolean" + }, + "unit": { + "description": "Unit of an i64 or f64 field, e.g. mm, cm, kg, m2 or h. Writers that read text, such as values.extract, convert numbers to it", + "type": "string" + }, + "value_type": { + "description": "Scalar type; defaults to text. Lets a later lbb_commit set entity_properties[].field", + "enum": [ + "bool", + "i64", + "f64", + "date_time", + "keyword", + "text", + "bytes" + ], + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "op": { + "const": "set_property_unit", + "type": "string" + }, + "property": { + "description": "An existing i64 or f64 field, by name", + "type": "string" + }, + "unit": { + "description": "The unit's symbol, as add_property takes it; omit it to clear the unit. Stored values are not converted", + "type": "string" + } + }, + "required": [ + "op", + "property" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_values": { + "description": "The allowed values that later commits are checked against; empty or absent clears the constraint. Stored values are not checked again", + "items": { + "type": "string" + }, + "type": "array" + }, + "op": { + "const": "set_property_constraint", + "type": "string" + }, + "property": { + "description": "An existing field, by name", + "type": "string" + } + }, + "required": [ + "op", + "property" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current entity-type name", + "type": "string" + }, + "op": { + "const": "rename_entity_type", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; records keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current relation name", + "type": "string" + }, + "op": { + "const": "rename_relation", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; edges keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inverse_name": { + "description": "Inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "op": { + "const": "set_relation_inverse", + "type": "string" + }, + "relation": { + "description": "Relation to set the inverse on, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "inverse_name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "op": { + "const": "set_relation_cardinality", + "type": "string" + }, + "relation": { + "description": "Relation to change, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "cardinality" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "op": { + "const": "narrow_relation", + "type": "string" + }, + "relation": { + "description": "Relation to narrow, by name", + "type": "string" + }, + "remove_domain": { + "description": "Entity-type names to remove from the relation's domain (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + }, + "remove_range": { + "description": "Entity-type names to remove from the relation's range (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Entity type to tombstone — kept readable for old records, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Relation to tombstone — old edges stay readable, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_relation", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + } +] - changed
Input schema / properties / relations / items / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "$ref": "#/properties/entity_types/items/anyOf/1" - } -]New value: +[ + { + "type": "string" + }, + { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } +]
- Changed
lbb_embeddings2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dim / maximumAdded value: +9007199254740991
- Changed
lbb_embeddings_delete3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / confirmRemoved value: -{ - "description": "The same name again, to confirm.", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "name", - "confirm" -]New value: +[ + "name" +]
- Changed
lbb_embeddings_manage2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dim / maximumAdded value: +9007199254740991
- Changed
lbb_evals21 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / aboutAdded value: +{ + "description": "datasets_create: what the dataset is, in sentences.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / action / enumPrevious value: -[ - "summary", - "traces", - "trace", - "label", - "judge", - "goldens", - "golden", - "accept", - "delete", - "run", - "run_answers", - "results", - "settings", - "checks_summary", - "checks", - "review_check" -]New value: +[ + "summary", + "traces", + "trace", + "label", + "judge", + "goldens", + "golden", + "accept", + "delete", + "run", + "run_answers", + "results", + "settings", + "checks_summary", + "checks", + "review_check", + "datasets", + "datasets_get", + "datasets_export", + "datasets_create", + "datasets_items" +] - added
Input schema / properties / answers / items / properties / as_of_commit_seq / maximumAdded value: +9007199254740991 - added
Input schema / properties / answers / items / properties / cost_micro_usd / maximumAdded value: +9007199254740991 - removed
Input schema / properties / answers / items / properties / reply / additionalPropertiesRemoved value: -false - added
Input schema / properties / answers / items / properties / route / properties / probabilities / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / cursorAdded value: +{ + "description": "datasets: the next_cursor of the page before.", + "type": "string" +} - added
Input schema / properties / idAdded value: +{ + "description": "datasets_get, datasets_export, datasets_items: the dataset's id (ds_…).", + "type": "string" +} - added
Input schema / properties / installAdded value: +{ + "additionalProperties": false, + "description": "datasets_create: the settings it is graded with.", + "properties": { + "context": { + "type": "string" + }, + "properties": { + "additionalProperties": { + "type": "string" + }, + "description": "Each property's value type: text, keyword, i64, f64 or bool", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "units": { + "additionalProperties": { + "type": "string" + }, + "description": "The unit of each number property", + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" +} - changed
Input schema / properties / items / descriptionPrevious value: -"label: several results at once."New value: +"label: several results at once, each {id, valid, note}. datasets_create, datasets_items: the examples, at most 500, each {name, text, values, leave_out, iri, case}; values and leave_out hold {property, value, accept, stated, quote, reason}." - removed
Input schema / properties / items / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / items / items / anyOfAdded value: +[ + { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "note": { + "type": "string" + }, + "valid": { + "type": "boolean" + } + }, + "required": [ + "id", + "valid" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "case": { + "description": "What the example shows, in one sentence", + "type": "string" + }, + "iri": { + "description": "The instance the input came from", + "type": "string" + }, + "leave_out": { + "items": { + "additionalProperties": false, + "properties": { + "accept": { + "description": "Other spellings a text value may take, lower case", + "items": { + "type": "string" + }, + "type": "array" + }, + "property": { + "type": "string" + }, + "quote": { + "description": "Words of the text that state the value", + "type": "string" + }, + "reason": { + "description": "Why a value is left out", + "type": "string" + }, + "stated": { + "description": "The number and unit as the text states them, e.g. 450 mm", + "type": "string" + }, + "value": { + "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", + "type": [ + "number", + "string", + "boolean", + "null" + ] + } + }, + "required": [ + "property", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "name": { + "description": "The input's name, unique in the dataset; the same name replaces", + "type": "string" + }, + "source": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + }, + "kind": { + "enum": [ + "test", + "review", + "answer_key" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "type": "object" + }, + "text": { + "description": "The input text, at most 40,000 characters", + "maxLength": 40000, + "type": "string" + }, + "values": { + "items": { + "additionalProperties": false, + "properties": { + "accept": { + "description": "Other spellings a text value may take, lower case", + "items": { + "type": "string" + }, + "type": "array" + }, + "property": { + "type": "string" + }, + "quote": { + "description": "Words of the text that state the value", + "type": "string" + }, + "reason": { + "description": "Why a value is left out", + "type": "string" + }, + "stated": { + "description": "The number and unit as the text states them, e.g. 450 mm", + "type": "string" + }, + "value": { + "description": "Numbers compare as numbers, text in lower case. In leave_out, null means no value at all", + "type": [ + "number", + "string", + "boolean", + "null" + ] + } + }, + "required": [ + "property", + "value" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" + } +] - removed
Input schema / properties / items / items / propertiesRemoved value: -{ - "id": { - "type": "string" - }, - "note": { - "type": "string" - }, - "valid": { - "type": "boolean" - } -} - removed
Input schema / properties / items / items / requiredRemoved value: -[ - "id", - "valid" -] - removed
Input schema / properties / items / items / typeRemoved value: -"object" - added
Input schema / properties / kindAdded value: +{ + "description": "datasets_create: what the items hold: values (the default).", + "enum": [ + "values" + ], + "type": "string" +} - added
Input schema / properties / limit / maximumAdded value: +9007199254740991 - added
Input schema / properties / nameAdded value: +{ + "description": "datasets_create: the dataset's name.", + "type": "string" +} - added
Input schema / properties / reference / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / sourceAdded value: +{ + "additionalProperties": false, + "description": "datasets_create: {\"kind\": \"test\", \"id\": <test id>}: the answers of a workflow test become the items, and its settings the install.", + "properties": { + "id": { + "type": "string" + }, + "kind": { + "const": "test", + "type": "string" + } + }, + "required": [ + "kind", + "id" + ], + "type": "object" +}
- Added
lbb_evals_delete - Changed
lbb_files4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / from / maximumAdded value: +9007199254740991 - added
Input schema / properties / line_offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / to / maximumAdded value: +9007199254740991
- Changed
lbb_fit_sources1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
lbb_fit_sources_delete3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / confirmRemoved value: -{ - "description": "The same name again, to confirm.", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "name", - "confirm" -]New value: +[ + "name" +]
- Changed
lbb_fit_sources_manage1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
lbb_inspect9 fields changed- changed
Input schema / additionalPropertiesPrevious value: -trueNew value: +{} - added
Input schema / properties / as_of_commit_seq / maximumAdded value: +9007199254740991 - added
Input schema / properties / consistencyAdded value: +{ + "enum": [ + "strong", + "eventual" + ], + "type": "string" +} - added
Input schema / properties / iriAdded value: +{ + "description": "Authoritative full RDF IRI; selects the lossless records/1 read.", + "type": "string" +} - added
Input schema / properties / keyAdded value: +{ + "description": "Stable key with entity_type, resolved from the activated schema at the read snapshot.", + "type": "string" +} - added
Input schema / properties / limitsAdded value: +{ + "additionalProperties": false, + "description": "Lossless records/1 section bounds. Exceeding a bound refuses the read instead of truncating it.", + "properties": { + "assertion_statements": { + "exclusiveMinimum": 0, + "maximum": 10000, + "type": "integer" + }, + "assertions": { + "exclusiveMinimum": 0, + "maximum": 100, + "type": "integer" + }, + "incoming": { + "exclusiveMinimum": 0, + "maximum": 10000, + "type": "integer" + }, + "outgoing": { + "exclusiveMinimum": 0, + "maximum": 10000, + "type": "integer" + }, + "properties": { + "exclusiveMinimum": 0, + "maximum": 10000, + "type": "integer" + } + }, + "type": "object" +} - added
Input schema / properties / schema_revisionAdded value: +{ + "description": "Expected opaque schema revision for a records/1 read.", + "type": "string" +} - added
Input schema / properties / top_k / maximumAdded value: +9007199254740991 - added
Input schema / properties / versionAdded value: +{ + "const": "records/1", + "type": "string" +}
- Changed
lbb_model_choice6 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / action / enumPrevious value: -[ - "options", - "trials", - "trial", - "trial_call", - "switches" -]New value: +[ + "options", + "trials", + "trial", + "trial_call", + "switches", + "choices" +] - added
Input schema / properties / cursorAdded value: +{ + "description": "choices: the next_cursor of the page before.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"trials: at most this many, newest first (default 20)."New value: +"trials: at most this many, newest first (default 20); choices: rows per page (default 50)." - added
Input schema / properties / useAdded value: +{ + "description": "choices: one use.", + "enum": [ + "extract", + "decide", + "embed" + ], + "type": "string" +} - added
Input schema / properties / workflowAdded value: +{ + "description": "choices: a named workflow: the rows in force for it.", + "type": "string" +}
- Changed
lbb_model_choice_manage11 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / action / enumPrevious value: -[ - "start", - "stop", - "switch", - "revert" -]New value: +[ + "start", + "stop", + "switch", + "revert", + "put_choice", + "delete_choice" +] - changed
Input schema / properties / effort / descriptionPrevious value: -"start: the effort of a Claude candidate."New value: +"start / put_choice: the effort of a Claude model." - removed
Input schema / properties / job / $refRemoved value: -"#/properties/jobs/items" - added
Input schema / properties / job / enumAdded value: +[ + "ask", + "route", + "rerank", + "fit", + "label" +] - added
Input schema / properties / job / typeAdded value: +"string" - changed
Input schema / properties / model / descriptionPrevious value: -"start: the candidate model id, e.g. claude-haiku-5-5 or jev-latest."New value: +"start / put_choice: the model id, e.g. claude-haiku-5-5 or jev-latest." - changed
Input schema / properties / provider / descriptionPrevious value: -"start: the candidate's provider."New value: +"start: the candidate's provider; put_choice: the model's provider (mock only on a local server)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "anthropic", - "typesafe" -]New value: +[ + "anthropic", + "typesafe", + "mock" +] - added
Input schema / properties / useAdded value: +{ + "description": "put_choice / delete_choice: the workflow use.", + "enum": [ + "extract", + "decide", + "embed" + ], + "type": "string" +} - added
Input schema / properties / workflowAdded value: +{ + "description": "put_choice / delete_choice: a named workflow of the graph; absent for the environment.", + "type": "string" +}
- Changed
lbb_models4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / body / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / limit / maximumAdded value: +9007199254740991 - added
Input schema / properties / split_seq / maximumAdded value: +9007199254740991
- Changed
lbb_query21 fields changed- changed
Input schema / additionalPropertiesPrevious value: -trueNew value: +{} - removed
Input schema / properties / after / properties / as_of_commit_seq / $refRemoved value: -"#/properties/before/properties/as_of_commit_seq" - added
Input schema / properties / after / properties / as_of_commit_seq / maximumAdded value: +9007199254740991 - added
Input schema / properties / after / properties / as_of_commit_seq / minimumAdded value: +0 - added
Input schema / properties / after / properties / as_of_commit_seq / typeAdded value: +"integer" - removed
Input schema / properties / after / properties / date / $refRemoved value: -"#/properties/before/properties/date" - added
Input schema / properties / after / properties / date / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$" - added
Input schema / properties / after / properties / date / typeAdded value: +"string" - removed
Input schema / properties / after / properties / moment / $refRemoved value: -"#/properties/before/properties/moment" - added
Input schema / properties / after / properties / moment / typeAdded value: +"string" - added
Input schema / properties / as_of_commit_seq / maximumAdded value: +9007199254740991 - added
Input schema / properties / before / properties / as_of_commit_seq / maximumAdded value: +9007199254740991 - added
Input schema / properties / body / propertyNamesAdded value: +{ + "type": "string" +} - changed
Input schema / properties / min_indexed_seq / minimumPrevious value: --9007199254740991New value: +0 - added
Input schema / properties / probe / maximumAdded value: +9007199254740991 - changed
Input schema / properties / query / descriptionPrevious value: -"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo \"card payments\" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding \"name\" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks. compare: the SELECT to run at both points; leave out LIMIT."New value: +"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. Imported RDF retains its exact, case-sensitive IRIs. Use returned IRIs unchanged; lbb_inspect action=entity iri=<full IRI> reads any subject with records/1. The following convention applies only to native records: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo \"card payments\" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding \"name\" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks. compare: the SELECT to run at both points; leave out LIMIT." - removed
Input schema / properties / sparql / $refRemoved value: -"#/properties/body" - added
Input schema / properties / sparql / additionalPropertiesAdded value: +{} - added
Input schema / properties / sparql / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / sparql / typeAdded value: +"object" - added
Input schema / properties / timeline / items / properties / as_of_commit_seq / maximumAdded value: +9007199254740991
- Changed
lbb_rdf1 field changed- changed
Input schema / additionalPropertiesPrevious value: -trueNew value: +{}
- Added
lbb_reviews - Added
lbb_reviews_manage - Changed
lbb_workflows15 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / action / enumPrevious value: -[ - "starters", - "list", - "get", - "preview", - "workflows", - "queue" -]New value: +[ + "starters", + "list", + "get", + "preview", + "workflows", + "queue", + "revisions", + "revision", + "run_results", + "tests", + "tests_get" +] - removed
Input schema / properties / afterRemoved value: -{ - "description": "queue: the position to start from (next_after).", - "minimum": 0, - "type": "integer" -} - changed
Input schema / properties / batch / descriptionPrevious value: -"preview/use, developer workflow only: instances per message, 1 to 64 (default 16)."New value: +"preview/use and define, developer workflow only: instances per message, 1 to 64 (default 16); for a stream, events per message, 1 to 500 (default 100). The server checks each kind's bound." - changed
Input schema / properties / batch / maximumPrevious value: -64New value: +500 - added
Input schema / properties / cursorAdded value: +{ + "description": "queue, tests, workflows, run_results and revisions: the next_cursor of the page before.", + "type": "string" +} - added
Input schema / properties / idAdded value: +{ + "description": "tests_get: the test's id.", + "type": "string" +} - added
Input schema / properties / iriAdded value: +{ + "description": "run_results: only the results of this input.", + "type": "string" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"queue: items per page, 1 to 100 (default 50)."New value: +"queue: items per page, 1 to 100 (default 50). run_results: inputs per page, at most 5, 20 or 100 by detail (compact, standard, full), and by default that many. workflows: workflows per page, 1 to 100 (the server's default 100). tests: tests per page, at most 5, 20 or 50 by detail (compact, standard, full) and by default that many, so the page comes back whole. revisions: revisions per page, 1 to 100 (default 20)." - changed
Input schema / properties / name / descriptionPrevious value: -"get: the triggered workflow's name. preview: the name a new workflow would get. workflows: one workflow's name (omit for all). queue: required."New value: +"get: the triggered workflow's name. preview: the name a new workflow would get. workflows: one workflow's name (omit for all). queue, run_results, revisions and revision: required. tests: one workflow's tests (omit for all)." - added
Input schema / properties / outcomeAdded value: +{ + "description": "run_results: only the inputs of these outcomes.", + "items": { + "enum": [ + "written", + "review", + "no_value", + "failed", + "duplicate" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / params / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / revisionAdded value: +{ + "description": "revision: the revision's id (wrev_ and 32 hex characters).", + "type": "string" +} - added
Input schema / properties / runAdded value: +{ + "description": "run_results: one run's results (a run id), in input order.", + "type": "string" +} - changed
Input schema / properties / trigger / descriptionPrevious value: -"define: the watch trigger's id (default watch). queue: the trigger whose queue to read."New value: +"define: the trigger's id (default watch, content, schedule or stream). queue: the trigger whose queue to read."
- Changed
lbb_workflows_delete3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - removed
Input schema / properties / confirmRemoved value: -{ - "description": "The same name again, to confirm.", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "name", - "confirm" -]New value: +[ + "name" +]
- Changed
lbb_workflows_manage23 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / action / enumPrevious value: -[ - "use", - "refresh", - "pause", - "resume", - "define", - "run" -]New value: +[ + "use", + "refresh", + "pause", + "resume", + "define", + "run", + "activate", + "tests_create", + "tests_answer", + "tests_cancel" +] - added
Input schema / properties / answerAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "decision": { + "description": "accept, reject, correct (with value), choose (with option) or cant_tell", + "enum": [ + "accept", + "reject", + "correct", + "choose", + "cant_tell" + ], + "type": "string" + }, + "note": { + "description": "Why, in a few words; for an answer item, the answer text. At most 1,000 characters", + "maxLength": 1000, + "type": "string" + }, + "option": { + "description": "choose: the id of the chosen option or grade", + "type": "string" + }, + "value": { + "description": "correct: the right value, in the property's type. A number may name its unit, e.g. 450 mm", + "type": [ + "number", + "string", + "boolean" + ] + } + }, + "required": [ + "decision" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "tests_answer: { decision: accept | reject | correct | cant_tell, value (with correct), note }; null removes the answer. For a property without a value, accept says the text states none, and correct gives the value it states." +} - changed
Input schema / properties / batch / descriptionPrevious value: -"preview/use, developer workflow only: instances per message, 1 to 64 (default 16)."New value: +"preview/use and define, developer workflow only: instances per message, 1 to 64 (default 16); for a stream, events per message, 1 to 500 (default 100). The server checks each kind's bound." - changed
Input schema / properties / batch / maximumPrevious value: -64New value: +500 - changed
Input schema / properties / budget_usd_per_month / descriptionPrevious value: -"use: a monthly model budget in USD for this workflow, below the stack's own."New value: +"use and define: a monthly model budget in USD for this workflow, below the stack's own. For define, its turns' activity calls stop at it (429 workflow_budget_exceeded) and the turn waits until the next month." - added
Input schema / properties / expected_revisionAdded value: +{ + "description": "activate: the revision the workflow had bound when you read it; another one fails with workflow_revision_conflict.", + "type": "string" +} - added
Input schema / properties / fan_inAdded value: +{ + "description": "define: the id of the workflow's fan-in identity (starter.<name>.<fan_in>) that the shards' turns send to, for example a catalogue. Default: none.", + "type": "string" +} - added
Input schema / properties / idAdded value: +{ + "description": "tests_answer, tests_cancel: the test's id.", + "type": "string" +} - added
Input schema / properties / installAdded value: +{ + "additionalProperties": false, + "description": "tests_create: a workflow not created yet, as use takes it: starter (values.extract), name, watch ({class, fields, exclude}), params and gate ({below}).", + "properties": { + "gate": { + "additionalProperties": false, + "properties": { + "below": { + "description": "Values below this support go to review", + "maximum": 1, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "below" + ], + "type": "object" + }, + "name": { + "description": "The name the workflow would get; default the class's local name", + "type": "string" + }, + "params": { + "additionalProperties": {}, + "description": "The starter workflow's settings, as its catalog entry lists them (the properties to fill, the context)", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "starter": { + "description": "The starter workflow, values.extract", + "type": "string" + }, + "watch": { + "additionalProperties": false, + "properties": { + "class": { + "description": "The class whose instances it reads", + "type": "string" + }, + "exclude": { + "items": { + "type": "string" + }, + "type": "array" + }, + "fields": { + "description": "The fields that hold the text, as embedding paths", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "class" + ], + "type": "object" + } + }, + "required": [ + "starter" + ], + "type": "object" +} - added
Input schema / properties / iriAdded value: +{ + "description": "tests_answer: the input, by its instance IRI.", + "type": "string" +} - added
Input schema / properties / irisAdded value: +{ + "description": "tests_create: the instances to test, at most 20.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / media_typesAdded value: +{ + "description": "define, in place of class: a content trigger on the uploads of these media types (application/pdf, image/*, */*), one content per message, without a wait for a publication.", + "items": { + "type": "string" + }, + "maxItems": 32, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / modelsAdded value: +{ + "description": "tests_create: other models to run the test on, per use (extract, decide), each one of the use's options in lbb_model_choice action=choices. The test's models name the ones it ran.", + "properties": { + "decide": { + "properties": { + "effort": { + "enum": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "type": "string" + }, + "model": { + "type": "string" + }, + "provider": { + "enum": [ + "anthropic", + "typesafe", + "mock" + ], + "type": "string" + } + }, + "required": [ + "provider", + "model" + ], + "type": "object" + }, + "extract": { + "properties": { + "effort": { + "enum": [ + "low", + "medium", + "high", + "xhigh", + "max" + ], + "type": "string" + }, + "model": { + "type": "string" + }, + "provider": { + "enum": [ + "anthropic", + "typesafe", + "mock" + ], + "type": "string" + } + }, + "required": [ + "provider", + "model" + ], + "type": "object" + } + }, + "type": "object" +} - changed
Input schema / properties / name / descriptionPrevious value: -"The triggered workflow's name, [a-z0-9][a-z0-9-]{0,62} (refresh, pause, resume: required; use: omit for the class's local name)."New value: +"The triggered workflow's name, [a-z0-9][a-z0-9-]{0,62} (refresh, pause, resume: required; use: omit for the class's local name; tests_create: the workflow of the graph to test)." - added
Input schema / properties / on_exhaustedAdded value: +{ + "description": "define: what a turn that failed for good does to its shard: block (the default) holds the inbox until a person retries or skips it; skip keeps the failed turn in the history and goes on.", + "enum": [ + "block", + "skip" + ], + "type": "string" +} - added
Input schema / properties / params / propertyNamesAdded value: +{ + "type": "string" +} - added
Input schema / properties / propertyAdded value: +{ + "description": "tests_answer: the property of the value.", + "type": "string" +} - added
Input schema / properties / revisionAdded value: +{ + "description": "activate: the revision to use (wrev_ and 32 hex characters).", + "type": "string" +} - added
Input schema / properties / sampleAdded value: +{ + "description": "tests_create: the first instances of the watched class instead, 1 to 20 (default 6).", + "maximum": 20, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / scheduleAdded value: +{ + "description": "define, in place of class: a schedule. One message per slot, at least 5 minutes apart, to one shard; a slot runs even when nothing changed (the message's changed is false).", + "properties": { + "cron": { + "description": "Five fields: minute, hour, day of month, month, day of week (0 3 * * 1-5), or @daily and the other macros.", + "type": "string" + }, + "every": { + "description": "In place of cron: a period in UTC, 5m to 366d (15m, 6h, 1d).", + "type": "string" + }, + "jitter": { + "description": "Each slot runs up to this much later, the same delay each time; at most 1h.", + "type": "string" + }, + "offset": { + "description": "With every: moves each slot (every 1d, offset 3h runs at 03:00 UTC).", + "type": "string" + }, + "timezone": { + "description": "With cron: an IANA time zone (Europe/Berlin). Default UTC.", + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / streamAdded value: +{ + "description": "define, in place of class: a stream of the events a client sends (POST /v1/workflows/named/events), in batches of batch events (1 to 500, default 100) or after max_wait; each event's key routes it to a shard, and shards stay as made.", + "properties": { + "max_wait": { + "description": "How long the first event of a partial batch waits, 1s to 15m (default 10s).", + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / trigger / descriptionPrevious value: -"define: the watch trigger's id (default watch). queue: the trigger whose queue to read."New value: +"define: the trigger's id (default watch, content, schedule or stream). queue: the trigger whose queue to read."
1 tool update
v0.15.1- Changed
lbb_files3 fields changed- added
Input schema / properties / afterAdded value: +{ + "description": "list: the next 50 files, from a previous call's next (pass the same parse_status and name).", + "type": "string" +} - changed
Input schema / properties / name / descriptionPrevious value: -"pages: the file's exact name, when you do not have its sha256."New value: +"list: only the files whose name holds this text, in any case. pages: the file's exact name, when you do not have its sha256." - added
Input schema / properties / parse_statusAdded value: +{ + "description": "list: only the files of this parse status; waiting is a file not parsed yet.", + "enum": [ + "parsed", + "waiting", + "unsupported", + "failed" + ], + "type": "string" +}
12 tool updates
v0.14.0- Changed
lbb_configure3 fields changed- changed
Input schema / properties / change / descriptionPrevious value: -"The ontology operations a person applies by accepting, in order (same shapes as evolve_ontology ops)"New value: +"The ontology operations a person applies by accepting, in order (same shapes as evolve_ontology ops). Up to 128; may be empty or absent when facts is set" - removed
Input schema / properties / change / minItemsRemoved value: -1 - added
Input schema / properties / factsAdded value: +{ + "additionalProperties": false, + "description": "Graph facts a person confirms: accepting commits them after the change (at most 200 triplets and property rows together). Records graphs only", + "properties": { + "entity_properties": { + "description": "Fields to commit, each { type, name, properties: { field: value } } as lbb_commit takes them", + "items": { + "$ref": "#/properties/entity_types/items/anyOf/1" + }, + "maxItems": 200, + "type": "array" + }, + "replace_owned": { + "additionalProperties": false, + "description": "Replace the producer's owned edges and fields on its subjects in the same commit", + "properties": { + "properties": { + "description": "Owned fields: the ones the facts do not set on a subject are removed", + "items": { + "type": "string" + }, + "maxItems": 64, + "type": "array" + }, + "relations": { + "description": "Owned relations: their current out-edges of the subjects that the facts do not write again are removed", + "items": { + "type": "string" + }, + "maxItems": 64, + "type": "array" + }, + "retract_entities": { + "description": "Records the producer made and no longer makes", + "items": { + "$ref": "#/properties/facts/properties/triplets/items/properties/source" + }, + "maxItems": 1000, + "type": "array" + }, + "subjects": { + "description": "The records this write is for", + "items": { + "$ref": "#/properties/facts/properties/triplets/items/properties/source" + }, + "maxItems": 1000, + "type": "array" + } + }, + "required": [ + "subjects" + ], + "type": "object" + }, + "summary": { + "description": "One line about the facts for the reviewer", + "maxLength": 500, + "type": "string" + }, + "triplets": { + "description": "Links to commit, as lbb_commit takes triplets", + "items": { + "additionalProperties": true, + "properties": { + "confidence": { + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "evidence": { + "description": "Why the link holds: a string, or { text, source_id } as lbb_commit takes it" + }, + "relation": { + "type": "string" + }, + "source": { + "additionalProperties": false, + "properties": { + "key": { + "description": "The record's external key, when it has one", + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type", + "name" + ], + "type": "object" + }, + "target": { + "$ref": "#/properties/facts/properties/triplets/items/properties/source" + } + }, + "required": [ + "source", + "relation", + "target" + ], + "type": "object" + }, + "maxItems": 200, + "type": "array" + } + }, + "type": "object" +}
- Changed
lbb_evals8 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "summary", - "traces", - "trace", - "label", - "judge", - "goldens", - "golden", - "accept", - "delete", - "run", - "results", - "settings", - "checks_summary", - "checks", - "review_check" -]New value: +[ + "summary", + "traces", + "trace", + "label", + "judge", + "goldens", + "golden", + "accept", + "delete", + "run", + "run_answers", + "results", + "settings", + "checks_summary", + "checks", + "review_check" +] - added
Input schema / properties / answersAdded value: +{ + "description": "run_answers: one answer per question golden your app asked: golden (its id), sparql (the query whose rows hold the answer; leave it out when the question is unanswerable), entailment, as_of_commit_seq, route (as the router returned it), reply, error (your app failed), cost_micro_usd.", + "items": { + "additionalProperties": false, + "properties": { + "as_of_commit_seq": { + "minimum": 0, + "type": "integer" + }, + "cost_micro_usd": { + "minimum": 0, + "type": "integer" + }, + "entailment": { + "enum": [ + "none", + "subclass", + "rdfs", + "owl" + ], + "type": "string" + }, + "error": { + "type": "string" + }, + "golden": { + "minLength": 1, + "type": "string" + }, + "reply": { + "additionalProperties": false, + "properties": { + "citations": { + "items": { + "type": "string" + }, + "type": "array" + }, + "text": { + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "route": { + "additionalProperties": false, + "properties": { + "by": { + "enum": [ + "caller", + "router", + "rewriter" + ], + "type": "string" + }, + "confidence": { + "type": "number" + }, + "kind": { + "enum": [ + "lookup", + "aggregate", + "search", + "history", + "schema", + "unanswerable" + ], + "type": "string" + }, + "probabilities": { + "additionalProperties": { + "type": "number" + }, + "type": "object" + } + }, + "required": [ + "kind", + "confidence", + "by" + ], + "type": "object" + }, + "sparql": { + "type": "string" + } + }, + "required": [ + "golden" + ], + "type": "object" + }, + "type": "array" +} - changed
Input schema / properties / consistency / descriptionPrevious value: -"run / accept: strong reads the head, eventual the last published commit."New value: +"run / run_answers / accept: strong reads the head, eventual the last published commit." - changed
Input schema / properties / job / enumPrevious value: -[ - "rerank", - "route", - "rewrite", - "fit", - "propose", - "label" -]New value: +[ + "rerank", + "route", + "ask", + "rewrite", + "fit", + "propose", + "label" +] - added
Input schema / properties / routeAdded value: +{ + "description": "label: with valid=true, or valid=false with sparql, the route the question expects.", + "enum": [ + "lookup", + "aggregate", + "search", + "history", + "schema", + "unanswerable" + ], + "type": "string" +} - added
Input schema / properties / runnerAdded value: +{ + "description": "run_answers / results: your app's name, lower-case letters, digits and -, at most 40 characters (default app). results without runner reads the server's runs.", + "type": "string" +} - changed
Input schema / properties / sparql / descriptionPrevious value: -"golden: the query to freeze (the search text for surface=search)."New value: +"golden: the query to freeze (the search text for surface=search). label: with valid=false and no item, the right query for the question; the server checks and runs it once." - changed
Input schema / properties / valid / descriptionPrevious value: -"label: true = the result answers the request (thumbs up), false = it does not."New value: +"label: true = the result answers the request (thumbs up), false = it does not. Without item or items, on a question's trace: the whole answer is right (true) or wrong (false)."
- Added
lbb_files - Added
lbb_fit_sources - Added
lbb_fit_sources_delete - Added
lbb_fit_sources_manage - Added
lbb_model_choice - Added
lbb_model_choice_manage - Changed
lbb_query18 fields changed- added
Input schema / properties / afterAdded value: +{ + "additionalProperties": false, + "description": "compare: the later point; defaults to the latest commit.", + "properties": { + "as_of_commit_seq": { + "$ref": "#/properties/before/properties/as_of_commit_seq" + }, + "date": { + "$ref": "#/properties/before/properties/date" + }, + "moment": { + "$ref": "#/properties/before/properties/moment" + } + }, + "type": "object" +} - changed
Input schema / properties / anchor / descriptionPrevious value: -"question: entity IRIs the question is about, at most 10 (for example the record the user has open). The server reads each one, and the query uses these IRIs directly instead of matching their names."New value: +"question: entity IRIs the question is about, at most 10 (for example the record the user has open). The server reads each one, and its queries use these IRIs directly instead of matching their names." - added
Input schema / properties / beforeAdded value: +{ + "additionalProperties": false, + "description": "compare: the earlier point (required): {\"as_of_commit_seq\": n}, {\"date\": \"YYYY-MM-DD\"} or {\"moment\": \"RFC 3339\"}.", + "properties": { + "as_of_commit_seq": { + "minimum": 0, + "type": "integer" + }, + "date": { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "moment": { + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / classesAdded value: +{ + "description": "describe: class IRIs to describe, at most 20.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / compare_cursorAdded value: +{ + "description": "compare: the cursor of the page before, from next; pass it with the same arguments.", + "type": "string" +} - added
Input schema / properties / dateAdded value: +{ + "description": "commit_at: YYYY-MM-DD; the last commit written by the end of that day (UTC).", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" +} - added
Input schema / properties / keyAdded value: +{ + "description": "compare: the variables that identify a row's entity, e.g. [\"contact\"]. With a key the rows are paired: added and removed hold the entities at one point only, changed the entities whose values differ. Without one whole rows are compared.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 8, + "type": "array" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"question: rows the run returns, 1 to 1,000. Defaults by detail: compact=20, standard=100, full=1000."New value: +"question: rows each query of the server's loop returns, 1 to 1,000. Defaults by detail: compact=20, standard=100, full=1000. names: candidates per name, 1 to 10 (default 5). compare: entries of each list per page, 1 to 1,000 (defaults by detail: 20, 100, 500)." - added
Input schema / properties / max_rowsAdded value: +{ + "description": "compare: rows to read per point, 1 to 50,000 (default 20,000). Past it the result says truncated.", + "maximum": 50000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"Selects the variant (one of: structured, sparql, question, search, analyze)."New value: +"Selects the variant (one of: structured, sparql, question, search, analyze, names, describe, commit_at, compare)." - changed
Input schema / properties / mode / enumPrevious value: -[ - "structured", - "sparql", - "question", - "search", - "analyze" -]New value: +[ + "structured", + "sparql", + "question", + "search", + "analyze", + "names", + "describe", + "commit_at", + "compare" +] - added
Input schema / properties / momentAdded value: +{ + "description": "commit_at: RFC 3339, e.g. 2026-06-18T12:00:00Z; the last commit written at or before it.", + "type": "string" +} - added
Input schema / properties / propertiesAdded value: +{ + "description": "describe: property IRIs to describe, at most 50.", + "items": { + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "type": "array" +} - changed
Input schema / properties / query / descriptionPrevious value: -"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo \"card payments\" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding \"name\" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks."New value: +"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo \"card payments\" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding \"name\" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks. compare: the SELECT to run at both points; leave out LIMIT." - changed
Input schema / properties / question / descriptionPrevious value: -"question: the question in plain words (required), 1 to 4,000 characters. The server writes the SPARQL query from a description of this graph, checks it, and runs it."New value: +"question: the question in plain words (required), 1 to 4,000 characters. The server's model runs queries on this graph, reads their rows, and answers. describe: the question whose classes and properties to describe." - changed
Input schema / properties / route / descriptionPrevious value: -"question: the kind of query, when you know it. Omit it and the router model selects it."New value: +"question: the kind of question, when you know it. Omit it and the router model picks it." - removed
Input schema / properties / runRemoved value: -{ - "description": "question: run the query and return its rows. Defaults to true; false returns the query only.", - "type": "boolean" -} - changed
Input schema / properties / text / descriptionPrevious value: -"The query text (required); embedded with the graph's model."New value: +"search: the query text (required); embedded with the graph's model. names: the question, or the names, to find (required)."
- Added
lbb_workflows - Added
lbb_workflows_delete - Added
lbb_workflows_manage
5 tool updates
v0.9.0- Changed
lbb_configure5 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: define_ontology, publish_schema, evolve_ontology, list_starters, apply_starter, suggest_ontology_change)."New value: +"Selects the variant (one of: define_ontology, publish_schema, evolve_ontology, list_starters, apply_starter, suggest_ontology_change, get_rewrite_profile, set_rewrite_profile)." - changed
Input schema / properties / action / enumPrevious value: -[ - "define_ontology", - "publish_schema", - "evolve_ontology", - "list_starters", - "apply_starter", - "suggest_ontology_change" -]New value: +[ + "define_ontology", + "publish_schema", + "evolve_ontology", + "list_starters", + "apply_starter", + "suggest_ontology_change", + "get_rewrite_profile", + "set_rewrite_profile" +] - added
Input schema / properties / examplesAdded value: +{ + "description": "Up to 20 worked examples: a question and the query that answers it on this graph", + "items": { + "additionalProperties": false, + "properties": { + "note": { + "maxLength": 1000, + "type": "string" + }, + "question": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + "sparql": { + "description": "A SELECT or ASK query with its PREFIX lines; the server parses it", + "maxLength": 4000, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "question", + "sparql" + ], + "type": "object" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / expected_versionAdded value: +{ + "description": "The version get_rewrite_profile returned (0 for none): another stored version answers 409 conflict and stores nothing", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / notesAdded value: +{ + "description": "What the data means for questions: which property holds the current state, what 'me' or 'my' means, which records to leave out. At most 8,000 characters", + "maxLength": 8000, + "type": "string" +}
- Changed
lbb_evals11 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "summary", - "traces", - "trace", - "label", - "judge", - "goldens", - "golden", - "accept", - "delete", - "run", - "results", - "settings" -]New value: +[ + "summary", + "traces", + "trace", + "label", + "judge", + "goldens", + "golden", + "accept", + "delete", + "run", + "results", + "settings", + "checks_summary", + "checks", + "review_check" +] - added
Input schema / properties / afterAdded value: +{ + "description": "checks: the next_after of the previous page.", + "type": "string" +} - added
Input schema / properties / agreeAdded value: +{ + "description": "review_check: true = the judge is right, false = correct it with verdict.", + "type": "boolean" +} - added
Input schema / properties / call_idAdded value: +{ + "description": "review_check: the check's `call` id, from checks.", + "type": "string" +} - added
Input schema / properties / jobAdded value: +{ + "description": "checks: only the checks of one job.", + "enum": [ + "rerank", + "route", + "rewrite", + "fit", + "propose", + "label" + ], + "type": "string" +} - added
Input schema / properties / monthAdded value: +{ + "description": "checks_summary / checks: the month, yyyy-mm (UTC). Defaults to the current month.", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])$", + "type": "string" +} - added
Input schema / properties / note / descriptionAdded value: +"label / review_check: why. review_check: at most 2,000 characters." - added
Input schema / properties / referenceAdded value: +{ + "additionalProperties": {}, + "description": "review_check with agree=false: the right answer. A rerank or label check: {\"grades\": {\"<hit id>\": 0..3}}; a route or fit check: {\"picks\": {\"<question id>\": \"<option>\"}}.", + "type": "object" +} - added
Input schema / properties / reviewedAdded value: +{ + "description": "checks: true = only the checks a person reviewed, false = only the others.", + "type": "boolean" +} - added
Input schema / properties / scoreAdded value: +{ + "description": "review_check with agree=false: the right score, 0 to 1. Omit for the judge's score of that verdict.", + "maximum": 1, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / verdictAdded value: +{ + "description": "checks: only the checks whose ground truth has this verdict. review_check with agree=false: the right verdict.", + "enum": [ + "right", + "partly", + "wrong" + ], + "type": "string" +}
- Changed
lbb_inspect1 field changed- changed
Input schema / properties / as_of / descriptionPrevious value: -"Valid-time snapshot pin (RFC3339): reproduce the node as of this instant."New value: +"Unsupported for entity; use as_of_commit_seq for a retained commit snapshot."
- Changed
lbb_models2 fields changed- changed
Input schema / properties / action / enumPrevious value: -[ - "shadow_eval", - "suggest_dataset", - "extractor_dataset" -]New value: +[ + "shadow_eval", + "suggest_dataset", + "extractor_dataset", + "activity" +] - added
Input schema / properties / monthAdded value: +{ + "description": "activity: the month, yyyy-mm (UTC). Defaults to the current month.", + "pattern": "^\\d{4}-(0[1-9]|1[0-2])$", + "type": "string" +}
- Changed
lbb_query11 fields changed- added
Input schema / properties / anchorAdded value: +{ + "description": "question: entity IRIs the question is about, at most 10 (for example the record the user has open). The server reads each one, and the query uses these IRIs directly instead of matching their names.", + "items": { + "maxLength": 2000, + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "type": "array" +} - added
Input schema / properties / contextAdded value: +{ + "description": "question: notes for the model, at most 8,000 characters: what the data means, units, names to prefer.", + "type": "string" +} - added
Input schema / properties / limitAdded value: +{ + "description": "question: rows the run returns, 1 to 1,000. Defaults by detail: compact=20, standard=100, full=1000.", + "maximum": 1000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"Selects the variant (one of: structured, sparql, search, analyze)."New value: +"Selects the variant (one of: structured, sparql, question, search, analyze)." - changed
Input schema / properties / mode / enumPrevious value: -[ - "structured", - "sparql", - "search", - "analyze" -]New value: +[ + "structured", + "sparql", + "question", + "search", + "analyze" +] - changed
Input schema / properties / query / descriptionPrevious value: -"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10"New value: +"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10. Search by meaning inside the query (the graph needs an embedding; see lbb_embeddings action=list): PREFIX search: <https://littlebigbrain.com/search#> SELECT ?x ?score WHERE { ?x search:similarTo \"card payments\" ; search:score ?score . ?x <https://littlebigbrain.com/r/calls> ?y } ORDER BY DESC(?score) LIMIT 5. The other patterns filter and join the hits. One search:similarTo per query, with a variable subject, in the main group (not inside OPTIONAL, UNION, MINUS or a subquery). The object is text, an entity IRI (records like that one) or a vector literal. search:top N sets the hits (1 to 1000; default the query LIMIT, then 10) and search:embedding \"name\" searches one embedding. FILTER(?score > 0.8) keeps close hits. The result's search field reports the plan (nearest, filter_first or search_first), the hits and complete. For a question in words, add search:rerank true ; search:relevance ?r and ORDER BY DESC(?r): the rerank model (Jev) reads the best hits with the text, keeps the top that answer it and binds its answer (0 to 1); search.rerank reports the status. Only a text query reranks." - added
Input schema / properties / questionAdded value: +{ + "description": "question: the question in plain words (required), 1 to 4,000 characters. The server writes the SPARQL query from a description of this graph, checks it, and runs it.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / rerankAdded value: +{ + "description": "true: the managed rerank model (Jev) orders the best hits by how well each answers the text, and each hit gets its relevance (0 to 1); adds about 0.3 s. false: the similarity order. Omit it to follow the graph's search setting.", + "type": "boolean" +} - added
Input schema / properties / routeAdded value: +{ + "description": "question: the kind of query, when you know it. Omit it and the router model selects it.", + "enum": [ + "lookup", + "aggregate", + "search", + "history", + "schema", + "unanswerable" + ], + "type": "string" +} - added
Input schema / properties / runAdded value: +{ + "description": "question: run the query and return its rows. Defaults to true; false returns the query only.", + "type": "boolean" +} - added
Input schema / properties / timelineAdded value: +{ + "description": "question: dated points that stand for the graph's commits, at most 200. A question about a date reads the commit of the latest point on or before it. Use it when the commits stand for other dates than the days they were written (a demo's milestones, an import of old records); without it the server reads the last commit written by the end of that day.", + "items": { + "additionalProperties": false, + "properties": { + "as_of_commit_seq": { + "description": "The commit that holds the graph as it was on that date.", + "minimum": 0, + "type": "integer" + }, + "date": { + "description": "YYYY-MM-DD.", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + }, + "label": { + "description": "A name for the point, such as a milestone.", + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "date", + "as_of_commit_seq" + ], + "type": "object" + }, + "maxItems": 200, + "type": "array" +}
2 tool updates
v0.8.1- Changed
lbb_configure11 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: define_ontology, publish_schema, evolve_ontology)."New value: +"Selects the variant (one of: define_ontology, publish_schema, evolve_ontology, list_starters, apply_starter, suggest_ontology_change)." - changed
Input schema / properties / action / enumPrevious value: -[ - "define_ontology", - "publish_schema", - "evolve_ontology" -]New value: +[ + "define_ontology", + "publish_schema", + "evolve_ontology", + "list_starters", + "apply_starter", + "suggest_ontology_change" +] - added
Input schema / properties / agentAdded value: +{ + "description": "Your name as the producer, shown to reviewers", + "maxLength": 200, + "type": "string" +} - added
Input schema / properties / anchorAdded value: +{ + "additionalProperties": false, + "description": "The class, property or relation the change is about", + "properties": { + "kind": { + "enum": [ + "ontology", + "class", + "property", + "relation" + ], + "type": "string" + }, + "name": { + "maxLength": 200, + "type": "string" + } + }, + "required": [ + "kind" + ], + "type": "object" +} - added
Input schema / properties / changeAdded value: +{ + "description": "The ontology operations a person applies by accepting, in order (same shapes as evolve_ontology ops)", + "items": { + "$ref": "#/properties/ops/items" + }, + "maxItems": 128, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / evidenceAdded value: +{ + "additionalProperties": false, + "description": "What you saw: record count, fields, up to 20 sample records", + "properties": { + "records": { + "minimum": 0, + "type": "integer" + }, + "samples": { + "items": { + "$ref": "#/properties/entity_types/items/anyOf/1" + }, + "maxItems": 20, + "type": "array" + }, + "source_fields": { + "items": { + "type": "string" + }, + "maxItems": 200, + "type": "array" + } + }, + "type": "object" +} - added
Input schema / properties / expected_ontology_versionAdded value: +{ + "description": "Refuse when the graph's ontology version differs", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / keyAdded value: +{ + "description": "Idempotency key ([A-Za-z0-9-_.:/]); filing again with the same key revises the suggestion", + "maxLength": 255, + "type": "string" +} - added
Input schema / properties / rationaleAdded value: +{ + "description": "Why the ontology needs the change; cite what you saw", + "maxLength": 4000, + "type": "string" +} - added
Input schema / properties / starterAdded value: +{ + "description": "Starter id: crm, documents or work (list_starters names them)", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / titleAdded value: +{ + "description": "Short imperative text, e.g. 'Add class Contractor'", + "maxLength": 200, + "minLength": 1, + "type": "string" +}
- Changed
lbb_inspect4 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, entity)."New value: +"Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, ontology_suggestions, entity)." - changed
Input schema / properties / action / enumPrevious value: -[ - "guide", - "ontology", - "ontology_conformance", - "schema", - "graphs", - "publication", - "ontology_search", - "metadata", - "entity" -]New value: +[ + "guide", + "ontology", + "ontology_conformance", + "schema", + "graphs", + "publication", + "ontology_search", + "metadata", + "ontology_suggestions", + "entity" +] - added
Input schema / properties / limitAdded value: +{ + "maximum": 500, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / statusAdded value: +{ + "description": "Only suggestions in this state; default all", + "enum": [ + "open", + "accepted", + "dismissed", + "superseded" + ], + "type": "string" +}
2 tool updates
v0.6.0- Changed
lbb_inspect8 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, entity, state, history, why, transitions)."New value: +"Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, entity)." - changed
Input schema / properties / action / enumPrevious value: -[ - "guide", - "ontology", - "ontology_conformance", - "schema", - "graphs", - "publication", - "ontology_search", - "metadata", - "entity", - "state", - "history", - "why", - "transitions" -]New value: +[ + "guide", + "ontology", + "ontology_conformance", + "schema", + "graphs", + "publication", + "ontology_search", + "metadata", + "entity" +] - changed
Input schema / properties / as_of_commit_seq / descriptionPrevious value: -"Snapshot pin: reproduce the node (state, edges, history) as of this commit_seq."New value: +"Snapshot pin: reproduce the node's attributes and relationships as of this commit_seq." - removed
Input schema / properties / relationRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / source_nameRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / source_typeRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / target_nameRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / target_typeRemoved value: -{ - "type": "string" -}
- Changed
lbb_models1 field changed- changed
Input schema / properties / action / enumPrevious value: -[ - "shadow_eval", - "planner_dataset", - "planner_preference_dataset", - "suggest_dataset", - "extractor_dataset" -]New value: +[ + "shadow_eval", + "suggest_dataset", + "extractor_dataset" +]
12 tool updates
v0.5.2- Removed
lbb_branch - Changed
lbb_commit1 field changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -}
- Changed
lbb_configure1 field changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -}
- Added
lbb_embeddings - Added
lbb_embeddings_delete - Added
lbb_embeddings_manage - Added
lbb_evals - Changed
lbb_inspect1 field changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -}
- Changed
lbb_models1 field changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -}
- Removed
lbb_observe - Changed
lbb_query11 fields changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -} - added
Input schema / properties / embeddingAdded value: +{ + "description": "One embedding by name (see lbb_embeddings action=list). Omit it to search every searchable class of the graph; each hit names its class.", + "type": "string" +} - added
Input schema / properties / explainAdded value: +{ + "description": "Plan without running: the scope, the resolved filter, and the allowed count. No model call.", + "type": "boolean" +} - added
Input schema / properties / filterAdded value: +{ + "description": "Conditions every hit must meet: {\"class\": …} or {\"via\": …, \"to\": …}. The response's filter shows how each condition resolved; an unknown relationship or name answers with the options.", + "items": { + "additionalProperties": false, + "properties": { + "class": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "A class condition: one class IRI or a list (any of); subclasses too. One class condition per search." + }, + "direction": { + "description": "With via: out (default), the hit links to the entity; in, the entity links to the hit.", + "enum": [ + "out", + "in" + ], + "type": "string" + }, + "to": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "With via: the entity, an IRI or a name (its label; a spelling slip resolves when one entity is clearly closest), or a list (any of)." + }, + "via": { + "description": "A relationship condition: the relationship, a local name (calls), prefix:name, or <iri>.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} - added
Input schema / properties / includeAdded value: +{ + "description": "text: return the embedded text of each hit.", + "items": { + "enum": [ + "text" + ], + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"Selects the variant (one of: structured, sparql, analyze)."New value: +"Selects the variant (one of: structured, sparql, search, analyze)." - changed
Input schema / properties / mode / enumPrevious value: -[ - "structured", - "sparql", - "analyze" -]New value: +[ + "structured", + "sparql", + "search", + "analyze" +] - added
Input schema / properties / probeAdded value: +{ + "description": "Clusters to read (default 4·√clusters, at least 8). More reads cost latency and find more.", + "exclusiveMinimum": 0, + "type": "integer" +} - added
Input schema / properties / requestAdded value: +{ + "description": "The user's own words behind this query (managed evals). When present the server records an eval trace and the result carries its trace_id; label the rows valid or not with lbb_evals action=label. Omit on continuation pages.", + "type": "string" +} - added
Input schema / properties / textAdded value: +{ + "description": "The query text (required); embedded with the graph's model.", + "type": "string" +} - added
Input schema / properties / top_k / maximumAdded value: +200
- Changed
lbb_rdf1 field changed- removed
Input schema / properties / branchRemoved value: -{ - "description": "Branch to target; defaults to the connection's branch", - "type": "string" -}
5 tool updates
v0.5.1- Changed
lbb_commit1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Validate a facts commit and return its structured SHACL report without writing. Only supported for mode=facts.", + "type": "boolean" +}
- Changed
lbb_configure9 fields changed- changed
Input schema / properties / allow_data_conflicts / descriptionPrevious value: -"Apply subtractive ops (narrow/remove) even when current data conflicts; affected records are kept and begin to warn. Default false rejects a conflicting subtractive request and reports the conflicts."New value: +"Deprecated compatibility flag; does not bypass conflicts. Preview subtractive changes with dry_run=true, repair the reported conflicts, then apply." - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview the exact definition without creating a graph or writing metadata.", + "type": "boolean" +} - removed
Input schema / properties / entity_types / items / additionalPropertiesRemoved value: -{} - added
Input schema / properties / entity_types / items / anyOfAdded value: +[ + { + "type": "string" + }, + { + "additionalProperties": {}, + "type": "object" + } +] - removed
Input schema / properties / entity_types / items / typeRemoved value: -"object" - changed
Input schema / properties / ops / items / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "add_domain": { - "description": "Entity-type names to add to the relation's domain (source types)", - "items": { - "type": "string" - }, - "type": "array" - }, - "add_range": { - "description": "Entity-type names to add to the relation's range (target types)", - "items": { - "type": "string" - }, - "type": "array" - }, - "op": { - "const": "widen_relation", - "type": "string" - }, - "relation": { - "description": "Relation to widen, by name (case-insensitive)", - "type": "string" - } - }, - "required": [ - "op", - "relation" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Display name of the new entity type (idempotent if it exists)", - "type": "string" - }, - "op": { - "const": "add_entity_type", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "cardinality": { - "description": "Defaults to many_to_many", - "enum": [ - "one_to_one", - "one_to_many", - "many_to_one", - "many_to_many" - ], - "type": "string" - }, - "domain": { - "description": "Entity-type names allowed as the source (domain); must already exist", - "items": { - "type": "string" - }, - "type": "array" - }, - "inverse_name": { - "description": "Optional inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", - "type": "string" - }, - "name": { - "description": "Display name of the new relation, e.g. HAS_PHASE", - "type": "string" - }, - "op": { - "const": "add_relation", - "type": "string" - }, - "range": { - "description": "Entity-type names allowed as the target (range); must already exist", - "items": { - "type": "string" - }, - "type": "array" - }, - "reducer": { - "description": "State-reducer token, e.g. append_only (default), latest_wins", - "type": "string" - }, - "symmetric": { - "type": "boolean" - }, - "temporal_semantics": { - "description": "Defaults to bitemporal", - "enum": [ - "atemporal", - "valid_time", - "commit_time", - "bitemporal" - ], - "type": "string" - }, - "transitive": { - "type": "boolean" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Display name of the new scalar property field, e.g. status (idempotent if it exists)", - "type": "string" - }, - "op": { - "const": "add_property", - "type": "string" - }, - "required": { - "description": "Advisory required flag (not enforced on commit)", - "type": "boolean" - }, - "value_type": { - "description": "Scalar type; defaults to text. Lets a later lbb_commit set entity_properties[].field", - "enum": [ - "bool", - "i64", - "f64", - "date_time", - "keyword", - "text", - "bytes" - ], - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "from": { - "description": "Current entity-type name", - "type": "string" - }, - "op": { - "const": "rename_entity_type", - "type": "string" - }, - "to": { - "description": "New display name (stable id stays frozen; records keep resolving)", - "type": "string" - } - }, - "required": [ - "op", - "from", - "to" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "from": { - "description": "Current relation name", - "type": "string" - }, - "op": { - "const": "rename_relation", - "type": "string" - }, - "to": { - "description": "New display name (stable id stays frozen; edges keep resolving)", - "type": "string" - } - }, - "required": [ - "op", - "from", - "to" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "inverse_name": { - "description": "Inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", - "type": "string" - }, - "op": { - "const": "set_relation_inverse", - "type": "string" - }, - "relation": { - "description": "Relation to set the inverse on, by name", - "type": "string" - } - }, - "required": [ - "op", - "relation", - "inverse_name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "cardinality": { - "enum": [ - "one_to_one", - "one_to_many", - "many_to_one", - "many_to_many" - ], - "type": "string" - }, - "op": { - "const": "set_relation_cardinality", - "type": "string" - }, - "relation": { - "description": "Relation to change, by name", - "type": "string" - } - }, - "required": [ - "op", - "relation", - "cardinality" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "op": { - "const": "narrow_relation", - "type": "string" - }, - "relation": { - "description": "Relation to narrow, by name", - "type": "string" - }, - "remove_domain": { - "description": "Entity-type names to remove from the relation's domain (subtractive)", - "items": { - "type": "string" - }, - "type": "array" - }, - "remove_range": { - "description": "Entity-type names to remove from the relation's range (subtractive)", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "op", - "relation" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Entity type to tombstone — kept readable for old records, rejected for new commits", - "type": "string" - }, - "op": { - "const": "remove_entity_type", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "name": { - "description": "Relation to tombstone — old edges stay readable, rejected for new commits", - "type": "string" - }, - "op": { - "const": "remove_relation", - "type": "string" - } - }, - "required": [ - "op", - "name" - ], - "type": "object" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "entity_type": { + "type": "string" + }, + "op": { + "const": "add_super_types", + "type": "string" + }, + "super_types": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "op", + "entity_type", + "super_types" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_domain": { + "description": "Entity-type names to add to the relation's domain (source types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "add_range": { + "description": "Entity-type names to add to the relation's range (target types)", + "items": { + "type": "string" + }, + "type": "array" + }, + "op": { + "const": "widen_relation", + "type": "string" + }, + "relation": { + "description": "Relation to widen, by name (case-insensitive)", + "type": "string" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Display name of the new entity type (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "description": "Defaults to many_to_many", + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "domain": { + "description": "Entity-type names allowed as the source (domain); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "inverse_name": { + "description": "Optional inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "name": { + "description": "Display name of the new relation, e.g. HAS_PHASE", + "type": "string" + }, + "op": { + "const": "add_relation", + "type": "string" + }, + "range": { + "description": "Entity-type names allowed as the target (range); must already exist", + "items": { + "type": "string" + }, + "type": "array" + }, + "reducer": { + "description": "State-reducer token, e.g. append_only (default), latest_wins", + "type": "string" + }, + "symmetric": { + "type": "boolean" + }, + "temporal_semantics": { + "description": "Defaults to bitemporal", + "enum": [ + "atemporal", + "valid_time", + "commit_time", + "bitemporal" + ], + "type": "string" + }, + "transitive": { + "type": "boolean" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Display name of the new scalar property field, e.g. status (idempotent if it exists)", + "type": "string" + }, + "op": { + "const": "add_property", + "type": "string" + }, + "required": { + "description": "Advisory required flag (not enforced on commit)", + "type": "boolean" + }, + "value_type": { + "description": "Scalar type; defaults to text. Lets a later lbb_commit set entity_properties[].field", + "enum": [ + "bool", + "i64", + "f64", + "date_time", + "keyword", + "text", + "bytes" + ], + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current entity-type name", + "type": "string" + }, + "op": { + "const": "rename_entity_type", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; records keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "description": "Current relation name", + "type": "string" + }, + "op": { + "const": "rename_relation", + "type": "string" + }, + "to": { + "description": "New display name (stable id stays frozen; edges keep resolving)", + "type": "string" + } + }, + "required": [ + "op", + "from", + "to" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "inverse_name": { + "description": "Inverse-relation display name, e.g. PHASE_OF (enables one-hop reverse traversal)", + "type": "string" + }, + "op": { + "const": "set_relation_inverse", + "type": "string" + }, + "relation": { + "description": "Relation to set the inverse on, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "inverse_name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "cardinality": { + "enum": [ + "one_to_one", + "one_to_many", + "many_to_one", + "many_to_many" + ], + "type": "string" + }, + "op": { + "const": "set_relation_cardinality", + "type": "string" + }, + "relation": { + "description": "Relation to change, by name", + "type": "string" + } + }, + "required": [ + "op", + "relation", + "cardinality" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "op": { + "const": "narrow_relation", + "type": "string" + }, + "relation": { + "description": "Relation to narrow, by name", + "type": "string" + }, + "remove_domain": { + "description": "Entity-type names to remove from the relation's domain (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + }, + "remove_range": { + "description": "Entity-type names to remove from the relation's range (subtractive)", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "op", + "relation" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Entity type to tombstone — kept readable for old records, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_entity_type", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "description": "Relation to tombstone — old edges stay readable, rejected for new commits", + "type": "string" + }, + "op": { + "const": "remove_relation", + "type": "string" + } + }, + "required": [ + "op", + "name" + ], + "type": "object" + } +] - removed
Input schema / properties / relations / $refRemoved value: -"#/properties/entity_types" - added
Input schema / properties / relations / itemsAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/properties/entity_types/items/anyOf/1" + } + ] +} - added
Input schema / properties / relations / typeAdded value: +"array"
- Changed
lbb_inspect5 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: guide, ontology, ontology_conformance, schema, ontology_search, metadata, entity, state, history, why, transitions)."New value: +"Selects the variant (one of: guide, ontology, ontology_conformance, schema, graphs, publication, ontology_search, metadata, entity, state, history, why, transitions)." - changed
Input schema / properties / action / enumPrevious value: -[ - "guide", - "ontology", - "ontology_conformance", - "schema", - "ontology_search", - "metadata", - "entity", - "state", - "history", - "why", - "transitions" -]New value: +[ + "guide", + "ontology", + "ontology_conformance", + "schema", + "graphs", + "publication", + "ontology_search", + "metadata", + "entity", + "state", + "history", + "why", + "transitions" +] - added
Input schema / properties / cursorAdded value: +{ + "description": "Opaque lbb_inspect continuation. Repeat action and pass the returned next arguments; rejects changed metadata.", + "type": "string" +} - added
Input schema / properties / page_sizeAdded value: +{ + "description": "Maximum complete metadata entries per page; defaults to 50. Nested fields are never truncated; an oversized single entry returns serialized_json fragments to concatenate and parse.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / sectionAdded value: +{ + "description": "Optional top-level array to inspect, e.g. entity_type_defs, relation_defs, property_defs, classes, or relations. Omit to page through all sections.", + "type": "string" +}
- Changed
lbb_query6 fields changed- changed
Input schema / properties / as_of / descriptionPrevious value: -"Snapshot pin (valid-time, RFC3339): evaluate the body as of this instant. Folded into the request's `as_of_valid_time`. Top-level here is the supported spelling — a bare `as_of` inside the body is rejected, since the server silently ignores it."New value: +"Unsupported in structured and SPARQL text modes; use as_of_commit_seq for a retained commit snapshot." - changed
Input schema / properties / body / descriptionPrevious value: -"Structured SPARQL-subset request body. Shape: { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having?, order_by?, select?, limit?, distinct? }. Each pattern term is { var: \"x\" } or a fixed { entity: { entity_type, name } }; `predicate` is a relation name and is case-insensitive here (FOR_CLIENT and for_client both resolve — unlike SPARQL text, which needs the lowercased IRI local name). FILTER — `filters` is a list of conditions, each of exact shape { \"compare\": { \"op\": <op>, \"left\": <term>, \"right\": <term> } } (or { \"and\": [<filter>…] }, { \"or\": [<filter>…] }, { \"not\": <filter> }). `op` is one of eq | ne | lt | le | gt | ge (NOT the symbols =,<,>). Each <term> is exactly one of { \"var\": \"x\" }, { \"property\": { \"var\": \"x\", \"field\": \"amount\" } } (a typed scalar attribute), or { \"value\": <typed> } — and <typed> is exactly one wrapper: { \"str\": \"…\" }, { \"i64\": 5 }, { \"f64\": 0.9 }, { \"bool\": true }, { \"date_time\": \"2026-01-01\" } (RFC3339), or { \"entity\": { \"entity_type\": \"T\", \"name\": \"N\" } }. Complete runnable example — deals whose amount ≥ 1000000: { \"patterns\": [{ \"subject\": { \"var\": \"d\" }, \"predicate\": \"for_client\", \"object\": { \"var\": \"c\" } }], \"filters\": [{ \"compare\": { \"op\": \"ge\", \"left\": { \"property\": { \"var\": \"d\", \"field\": \"amount\" } }, \"right\": { \"value\": { \"f64\": 1000000 } } } }] }. Comparisons use the field's real declared type (numbers as numbers, datetimes as instants), so they run server-side. GROUP BY supports both entity-identity keys (group_by: [\"s\"]) and typed scalar keys via group_keys: a property value ({ property: { var, field, as } }) or a calendar bucket of a datetime property ({ date_bucket: { var, field, granularity: year|month|week|day|hour, as } }). Scalar keys come back per group under value_keys[as] — so a per-area breakdown or a commits-per-month time series is one server-side query, no client-side bucketing. Worked example -- commits per area per month in one query: { \"patterns\": [{ \"subject\": { \"var\": \"c\" }, \"predicate\": \"committed_to\", \"object\": { \"var\": \"repo\" } }], \"group_keys\": [{ \"date_bucket\": { \"var\": \"c\", \"field\": \"committed_at\", \"granularity\": \"month\", \"as\": \"m\" } }, { \"property\": { \"var\": \"c\", \"field\": \"area\", \"as\": \"area\" } }], \"aggregates\": [{ \"func\": \"count\", \"as\": \"n\" }], \"order_by\": [{ \"var\": \"m\" }] } -- area and committed_at are typed entity attributes (set via entity_properties; readable flat under attributes, never a nested metadata blob), and each group returns value_keys.m + value_keys.area + aggregates.n. `having: [...]` takes the same filter shape over the aggregated groups (e.g. { \"compare\": { \"op\": \"gt\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 10 } } } }). A `combinators` key (UNION/OPTIONAL/MINUS/EXISTS) is rejected here; express those with SPARQL text under mode=sparql. Cheap aggregate count: pair an equality having (e.g. { \"compare\": { \"op\": \"eq\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 4 } } } }) with row_limit: 1 -- the response row_page.total reports how many groups match without materializing them all, so you read the count off row_page.total instead of paging every matching row. For snapshot pinning prefer the top-level `as_of` / `as_of_commit_seq` arguments below; a bare `as_of` key inside the body is rejected (the body's valid-time field is `as_of_valid_time`)."New value: +"Structured SPARQL-subset request body. Shape: { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having?, order_by?, select?, limit?, distinct? }. Each pattern term is { var: \"x\" } or a fixed { entity: { entity_type, name } }; `predicate` is a relation name and is case-insensitive here (FOR_CLIENT and for_client both resolve — unlike SPARQL text, which needs the lowercased IRI local name). FILTER — `filters` is a list of conditions, each of exact shape { \"compare\": { \"op\": <op>, \"left\": <term>, \"right\": <term> } } (or { \"and\": [<filter>…] }, { \"or\": [<filter>…] }, { \"not\": <filter> }). `op` is one of eq | ne | lt | le | gt | ge (NOT the symbols =,<,>). Each <term> is exactly one of { \"var\": \"x\" }, { \"property\": { \"var\": \"x\", \"field\": \"amount\" } } (a typed scalar attribute), or { \"value\": <typed> } — and <typed> is exactly one wrapper: { \"str\": \"…\" }, { \"i64\": 5 }, { \"f64\": 0.9 }, { \"bool\": true }, { \"date_time\": \"2026-01-01\" } (RFC3339), or { \"entity\": { \"entity_type\": \"T\", \"name\": \"N\" } }. Complete runnable example — deals whose amount ≥ 1000000: { \"patterns\": [{ \"subject\": { \"var\": \"d\" }, \"predicate\": \"for_client\", \"object\": { \"var\": \"c\" } }], \"filters\": [{ \"compare\": { \"op\": \"ge\", \"left\": { \"property\": { \"var\": \"d\", \"field\": \"amount\" } }, \"right\": { \"value\": { \"f64\": 1000000 } } } }] }. Comparisons use the field's real declared type (numbers as numbers, datetimes as instants), so they run server-side. GROUP BY supports both entity-identity keys (group_by: [\"s\"]) and typed scalar keys via group_keys: a property value ({ property: { var, field, as } }) or a calendar bucket of a datetime property ({ date_bucket: { var, field, granularity: year|month|week|day|hour, as } }). Scalar keys come back per group under value_keys[as] — so a per-area breakdown or a commits-per-month time series is one server-side query, no client-side bucketing. Worked example -- commits per area per month in one query: { \"patterns\": [{ \"subject\": { \"var\": \"c\" }, \"predicate\": \"committed_to\", \"object\": { \"var\": \"repo\" } }], \"group_keys\": [{ \"date_bucket\": { \"var\": \"c\", \"field\": \"committed_at\", \"granularity\": \"month\", \"as\": \"m\" } }, { \"property\": { \"var\": \"c\", \"field\": \"area\", \"as\": \"area\" } }], \"aggregates\": [{ \"func\": \"count\", \"as\": \"n\" }], \"order_by\": [{ \"var\": \"m\" }] } -- area and committed_at are typed entity attributes (set via entity_properties; readable flat under attributes, never a nested metadata blob), and each group returns value_keys.m + value_keys.area + aggregates.n. `having: [...]` takes the same filter shape over the aggregated groups (e.g. { \"compare\": { \"op\": \"gt\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 10 } } } }). A `combinators` key (UNION/OPTIONAL/MINUS/EXISTS) is rejected here; express those with SPARQL text under mode=sparql. Cheap aggregate count: pair an equality having (e.g. { \"compare\": { \"op\": \"eq\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 4 } } } }) with row_limit: 1 -- the response row_page.total reports how many groups match without materializing them all, so you read the count off row_page.total instead of paging every matching row. For snapshot pinning use the top-level `as_of_commit_seq` argument or the same body field. Valid-time `as_of` and `as_of_valid_time` selectors are unsupported and rejected before HTTP." - added
Input schema / properties / consistencyAdded value: +{ + "description": "Read consistency. strong requires publication through head; a pending response is retryable.", + "enum": [ + "eventual", + "strong" + ], + "type": "string" +} - added
Input schema / properties / entailmentAdded value: +{ + "description": "Reasoning over the pinned RDF generation. Defaults to none. owl includes RDFS, inverse relationships and the supported OWL profile.", + "enum": [ + "none", + "subclass", + "rdfs", + "owl" + ], + "type": "string" +} - added
Input schema / properties / min_indexed_seqAdded value: +{ + "description": "Read-after-write publication floor. Preserved across cursor pages.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - changed
Input schema / properties / query / descriptionPrevious value: -"SPARQL 1.1 query text (SELECT or ASK). IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with rdfs:subClassOf closure on by default. Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10"New value: +"SPARQL 1.1 query text (SELECT or ASK). Valid-time as_of is unsupported; use as_of_commit_seq for a retained commit snapshot. IRI scheme: relations are <https://littlebigbrain.com/r/NAME> (NAME lowercased, e.g. writes_to; reverse a relation with the ^ path operator, no stored inverse triple). Types are <https://littlebigbrain.com/class/NAME> (lowercased), matched as `?x a <…/class/NAME>` with explicit entailment=subclass, rdfs, or owl for inference (default none). Property fields are <https://littlebigbrain.com/p/NAME> (lowercased). The local name is ALWAYS lowercase — an uppercase one (e.g. <…/r/FOR_CLIENT>) is a different, non-existent IRI that silently matches nothing; this tool auto-lowercases the local name of /r/, /class/, and /p/ IRIs for you and adds a `notes` entry when it does, so a stray uppercase still resolves. (Structured mode's `predicate` is case-insensitive on its own.) Entities are content-addressed <https://littlebigbrain.com/e/HASH> — never build an entity IRI from a name; anchor a named entity by its label instead: `?e <http://www.w3.org/2000/01/rdf-schema#label> \"Acme\"`. Discover the exact relation and type names with lbb_inspect action=ontology. SELECT and ASK only (CONSTRUCT/DESCRIBE are rejected). Example: SELECT ?service ?db WHERE { ?service <https://littlebigbrain.com/r/writes_to> ?db } LIMIT 10"
- Added
lbb_rdf
5 tool updates
v0.4.2- Removed
lbb_decode - Removed
lbb_ground - Changed
lbb_inspect5 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: guide, ontology, ontology_conformance, schema, ontology_search, metadata, entity, state, history, why, traverse, transitions)."New value: +"Selects the variant (one of: guide, ontology, ontology_conformance, schema, ontology_search, metadata, entity, state, history, why, transitions)." - changed
Input schema / properties / action / enumPrevious value: -[ - "guide", - "ontology", - "ontology_conformance", - "schema", - "ontology_search", - "metadata", - "entity", - "state", - "history", - "why", - "traverse", - "transitions" -]New value: +[ + "guide", + "ontology", + "ontology_conformance", + "schema", + "ontology_search", + "metadata", + "entity", + "state", + "history", + "why", + "transitions" +] - removed
Input schema / properties / directionRemoved value: -{ - "enum": [ - "out", - "in", - "both" - ], - "type": "string" -} - removed
Input schema / properties / max_hopsRemoved value: -{ - "exclusiveMinimum": 0, - "maximum": 6, - "type": "integer" -} - removed
Input schema / properties / relationsRemoved value: -{ - "items": { - "type": "string" - }, - "type": "array" -}
- Changed
lbb_query2 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"Structured SPARQL-subset or analytics request body. Shape: { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having?, order_by?, select?, limit?, distinct? }. Each pattern term is { var: \"x\" } or a fixed { entity: { entity_type, name } }; `predicate` is a relation name and is case-insensitive here (FOR_CLIENT and for_client both resolve — unlike SPARQL text, which needs the lowercased IRI local name). FILTER — `filters` is a list of conditions, each of exact shape { \"compare\": { \"op\": <op>, \"left\": <term>, \"right\": <term> } } (or { \"and\": [<filter>…] }, { \"or\": [<filter>…] }, { \"not\": <filter> }). `op` is one of eq | ne | lt | le | gt | ge (NOT the symbols =,<,>). Each <term> is exactly one of { \"var\": \"x\" }, { \"property\": { \"var\": \"x\", \"field\": \"amount\" } } (a typed scalar attribute), or { \"value\": <typed> } — and <typed> is exactly one wrapper: { \"str\": \"…\" }, { \"i64\": 5 }, { \"f64\": 0.9 }, { \"bool\": true }, { \"date_time\": \"2026-01-01\" } (RFC3339), or { \"entity\": { \"entity_type\": \"T\", \"name\": \"N\" } }. Complete runnable example — deals whose amount ≥ 1000000: { \"patterns\": [{ \"subject\": { \"var\": \"d\" }, \"predicate\": \"for_client\", \"object\": { \"var\": \"c\" } }], \"filters\": [{ \"compare\": { \"op\": \"ge\", \"left\": { \"property\": { \"var\": \"d\", \"field\": \"amount\" } }, \"right\": { \"value\": { \"f64\": 1000000 } } } }] }. Comparisons use the field's real declared type (numbers as numbers, datetimes as instants), so they run server-side. GROUP BY supports both entity-identity keys (group_by: [\"s\"]) and typed scalar keys via group_keys: a property value ({ property: { var, field, as } }) or a calendar bucket of a datetime property ({ date_bucket: { var, field, granularity: year|month|week|day|hour, as } }). Scalar keys come back per group under value_keys[as] — so a per-area breakdown or a commits-per-month time series is one server-side query, no client-side bucketing. Worked example -- commits per area per month in one query: { \"patterns\": [{ \"subject\": { \"var\": \"c\" }, \"predicate\": \"committed_to\", \"object\": { \"var\": \"repo\" } }], \"group_keys\": [{ \"date_bucket\": { \"var\": \"c\", \"field\": \"committed_at\", \"granularity\": \"month\", \"as\": \"m\" } }, { \"property\": { \"var\": \"c\", \"field\": \"area\", \"as\": \"area\" } }], \"aggregates\": [{ \"func\": \"count\", \"as\": \"n\" }], \"order_by\": [{ \"var\": \"m\" }] } -- area and committed_at are typed entity attributes (set via entity_properties; readable flat under attributes, never a nested metadata blob), and each group returns value_keys.m + value_keys.area + aggregates.n. `having: [...]` takes the same filter shape over the aggregated groups (e.g. { \"compare\": { \"op\": \"gt\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 10 } } } }); it is evaluated only on this grouped path, NOT alongside `combinators` (UNION/OPTIONAL/MINUS), which route to the analytics engine. Cheap aggregate count: pair an equality having (e.g. { \"compare\": { \"op\": \"eq\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 4 } } } }) with row_limit: 1 -- the response row_page.total reports how many groups match without materializing them all, so you read the count off row_page.total instead of paging every matching row. For snapshot pinning prefer the top-level `as_of` / `as_of_commit_seq` arguments below; a bare `as_of` key inside the body is rejected (the body's valid-time field is `as_of_valid_time`)."New value: +"Structured SPARQL-subset request body. Shape: { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having?, order_by?, select?, limit?, distinct? }. Each pattern term is { var: \"x\" } or a fixed { entity: { entity_type, name } }; `predicate` is a relation name and is case-insensitive here (FOR_CLIENT and for_client both resolve — unlike SPARQL text, which needs the lowercased IRI local name). FILTER — `filters` is a list of conditions, each of exact shape { \"compare\": { \"op\": <op>, \"left\": <term>, \"right\": <term> } } (or { \"and\": [<filter>…] }, { \"or\": [<filter>…] }, { \"not\": <filter> }). `op` is one of eq | ne | lt | le | gt | ge (NOT the symbols =,<,>). Each <term> is exactly one of { \"var\": \"x\" }, { \"property\": { \"var\": \"x\", \"field\": \"amount\" } } (a typed scalar attribute), or { \"value\": <typed> } — and <typed> is exactly one wrapper: { \"str\": \"…\" }, { \"i64\": 5 }, { \"f64\": 0.9 }, { \"bool\": true }, { \"date_time\": \"2026-01-01\" } (RFC3339), or { \"entity\": { \"entity_type\": \"T\", \"name\": \"N\" } }. Complete runnable example — deals whose amount ≥ 1000000: { \"patterns\": [{ \"subject\": { \"var\": \"d\" }, \"predicate\": \"for_client\", \"object\": { \"var\": \"c\" } }], \"filters\": [{ \"compare\": { \"op\": \"ge\", \"left\": { \"property\": { \"var\": \"d\", \"field\": \"amount\" } }, \"right\": { \"value\": { \"f64\": 1000000 } } } }] }. Comparisons use the field's real declared type (numbers as numbers, datetimes as instants), so they run server-side. GROUP BY supports both entity-identity keys (group_by: [\"s\"]) and typed scalar keys via group_keys: a property value ({ property: { var, field, as } }) or a calendar bucket of a datetime property ({ date_bucket: { var, field, granularity: year|month|week|day|hour, as } }). Scalar keys come back per group under value_keys[as] — so a per-area breakdown or a commits-per-month time series is one server-side query, no client-side bucketing. Worked example -- commits per area per month in one query: { \"patterns\": [{ \"subject\": { \"var\": \"c\" }, \"predicate\": \"committed_to\", \"object\": { \"var\": \"repo\" } }], \"group_keys\": [{ \"date_bucket\": { \"var\": \"c\", \"field\": \"committed_at\", \"granularity\": \"month\", \"as\": \"m\" } }, { \"property\": { \"var\": \"c\", \"field\": \"area\", \"as\": \"area\" } }], \"aggregates\": [{ \"func\": \"count\", \"as\": \"n\" }], \"order_by\": [{ \"var\": \"m\" }] } -- area and committed_at are typed entity attributes (set via entity_properties; readable flat under attributes, never a nested metadata blob), and each group returns value_keys.m + value_keys.area + aggregates.n. `having: [...]` takes the same filter shape over the aggregated groups (e.g. { \"compare\": { \"op\": \"gt\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 10 } } } }). A `combinators` key (UNION/OPTIONAL/MINUS/EXISTS) is rejected here; express those with SPARQL text under mode=sparql. Cheap aggregate count: pair an equality having (e.g. { \"compare\": { \"op\": \"eq\", \"left\": { \"var\": \"n\" }, \"right\": { \"value\": { \"i64\": 4 } } } }) with row_limit: 1 -- the response row_page.total reports how many groups match without materializing them all, so you read the count off row_page.total instead of paging every matching row. For snapshot pinning prefer the top-level `as_of` / `as_of_commit_seq` arguments below; a bare `as_of` key inside the body is rejected (the body's valid-time field is `as_of_valid_time`)." - changed
Input schema / properties / metric / enumPrevious value: -[ - "entity_types", - "relations", - "overview", - "facets", - "sparql" -]New value: +[ + "entity_types", + "relations", + "overview", + "sparql" +]
- Removed
lbb_search
8 tool updates
v0.2.7- Removed
lbb_ask - Changed
lbb_configure6 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: define_ontology, define_rules, publish_schema, evolve_ontology)."New value: +"Selects the variant (one of: define_ontology, publish_schema, evolve_ontology)." - changed
Input schema / properties / action / enumPrevious value: -[ - "define_ontology", - "define_rules", - "publish_schema", - "evolve_ontology" -]New value: +[ + "define_ontology", + "publish_schema", + "evolve_ontology" +] - removed
Input schema / properties / confirm_emptyRemoved value: -{ - "type": "boolean" -} - changed
Input schema / properties / desired_mode / enumPrevious value: -[ - "warn", - "reject" -]New value: +[ + "off", + "warn", + "reject" +] - removed
Input schema / properties / preview_digestRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / rulesRemoved value: -{ - "items": { - "additionalProperties": true, - "properties": { - "body": { - "description": "The condition: a basic graph pattern over current edges (asserted + already-derived), joined on shared variables. Terms may be variables or fixed entities.", - "items": { - "additionalProperties": true, - "properties": { - "object": { - "$ref": "#/properties/rules/items/properties/body/items/properties/subject", - "description": "A rule term: { \"var\": \"x\" } (a variable) or { \"entity\": { \"entity_type\": \"DeliveryStatus\", \"name\": \"Complete\" } } (a fixed entity used as a constant in the body or head)" - }, - "predicate": { - "description": "Relation name. In a rule body, the reserved \"rdf:type\" makes a type-membership constraint: the object names a class ({ entity: { entity_type: \"Contact\" } }, no name) and matches every entity of that class and its subtypes (rdfs:subClassOf closure), so one rule keyed on a supertype fires for all subtypes. Not allowed in a head or an exists/not_exists filter.", - "type": "string" - }, - "subject": { - "anyOf": [ - { - "additionalProperties": true, - "properties": { - "var": { - "description": "A variable, joined across patterns by name", - "type": "string" - } - }, - "required": [ - "var" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "entity": { - "additionalProperties": true, - "properties": { - "entity_id": { - "description": "Entity id (hex), as an alternative to type+name", - "type": "string" - }, - "entity_type": { - "description": "Entity type name (with `name`, names a fixed entity)", - "type": "string" - }, - "name": { - "description": "Entity name (paired with `entity_type`)", - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "entity" - ], - "type": "object" - } - ], - "description": "A rule term: { \"var\": \"x\" } (a variable) or { \"entity\": { \"entity_type\": \"DeliveryStatus\", \"name\": \"Complete\" } } (a fixed entity used as a constant in the body or head)" - } - }, - "type": "object" - }, - "type": "array" - }, - "combinators": { - "description": "exists/not_exists filters folded over the body. not_exists is stratified negation — it lets a rule express a universal condition, e.g. derive \"phase complete\" only when not_exists an incomplete deliverable. A negation cycle is rejected.", - "items": { - "anyOf": [ - { - "additionalProperties": true, - "properties": { - "exists": { - "items": { - "$ref": "#/properties/rules/items/properties/body/items" - }, - "type": "array" - } - }, - "required": [ - "exists" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "not_exists": { - "items": { - "$ref": "#/properties/rules/items/properties/body/items" - }, - "type": "array" - } - }, - "required": [ - "not_exists" - ], - "type": "object" - } - ], - "description": "An existence filter over the body solutions: { exists: [...] } (semijoin — keep rows with a compatible match) or { not_exists: [...] } (negation/antijoin — keep rows with none)" - }, - "type": "array" - }, - "head": { - "$ref": "#/properties/rules/items/properties/body/items", - "description": "The triple derived once per body solution. Every head variable must be bound by the body; a fixed-entity object derives a constant (e.g. set the rolled-up status to the Complete entity)." - }, - "name": { - "type": "string" - }, - "order": { - "description": "Run order, low to high (a determinism hint)", - "type": "integer" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "type": "array" -}
- Changed
lbb_decode5 fields changed- removed
Input schema / properties / source_name / descriptionRemoved value: -"Source entity display name" - removed
Input schema / properties / source_type / descriptionRemoved value: -"Source entity type; omit to have the DB recover it from the name" - removed
Input schema / properties / target_name / descriptionRemoved value: -"Target entity display name" - removed
Input schema / properties / target_type / descriptionRemoved value: -"Target entity type; omit to have the DB recover it from the name" - removed
Input schema / properties / use_model_when_forced / descriptionRemoved value: -"Call the model even when the type pair forces one relation (default false — a forced pair is answered by the DB alone)"
- Changed
lbb_ground5 fields changed- removed
Input schema / properties / action / descriptionRemoved value: -"complete = narrowed vocabulary autocomplete; resolve = snap free text to the nearest real vocabulary; audit = groundability report" - changed
Input schema / properties / kinds / descriptionPrevious value: -"[complete/resolve] Restrict to these vocabulary kinds (default: all)"New value: +"Restrict to these vocabulary kinds (default: all)" - changed
Input schema / properties / sample / descriptionPrevious value: -"[audit] Entities to sample for narrowing-recall"New value: +"[audit] Entities sampled for narrowing recall" - changed
Input schema / properties / text / descriptionPrevious value: -"[resolve] Free text to snap to the nearest real vocabulary item"New value: +"[resolve] Free text to resolve" - changed
Input schema / properties / top_k / descriptionPrevious value: -"[complete/resolve] Max results (default 8)"New value: +"Max results (default 8)"
- Removed
lbb_index - Changed
lbb_inspect12 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Selects the variant (one of: guide, ontology, ontology_conformance, schema, schema_audit, rules, schema_preview, ontology_search, metadata, entity, edges, state, history, why, traverse, transitions)."New value: +"Selects the variant (one of: guide, ontology, ontology_conformance, schema, ontology_search, metadata, entity, state, history, why, traverse, transitions)." - changed
Input schema / properties / action / enumPrevious value: -[ - "guide", - "ontology", - "ontology_conformance", - "schema", - "schema_audit", - "rules", - "schema_preview", - "ontology_search", - "metadata", - "entity", - "edges", - "state", - "history", - "why", - "traverse", - "transitions" -]New value: +[ + "guide", + "ontology", + "ontology_conformance", + "schema", + "ontology_search", + "metadata", + "entity", + "state", + "history", + "why", + "traverse", + "transitions" +] - removed
Input schema / properties / base_ontology_versionRemoved value: -{ - "minimum": 0, - "type": "integer" -} - removed
Input schema / properties / base_shapes_versionRemoved value: -{ - "minimum": 0, - "type": "integer" -} - removed
Input schema / properties / cursorRemoved value: -{ - "description": "Opaque cursor from the previous page's `next_cursor`. The response is the unified list envelope { object:'list', data, has_more, next_cursor, total_count }; page a high-degree node (entity detail hard-caps its edge sample) by feeding next_cursor back here until has_more is false. Each row carries valid_time for a per-edge timeline.", - "type": "string" -} - removed
Input schema / properties / desired_modeRemoved value: -{ - "enum": [ - "warn", - "reject" - ], - "type": "string" -} - removed
Input schema / properties / direction / descriptionRemoved value: -"Edges out of / into / touching the entity (default both)." - removed
Input schema / properties / offsetRemoved value: -{ - "description": "Legacy alias for `cursor` (still accepted); prefer paging with `cursor`.", - "minimum": 0, - "type": "integer" -} - removed
Input schema / properties / ontologyRemoved value: -{ - "additionalProperties": false, - "properties": { - "format": { - "enum": [ - "auto", - "turtle", - "json_ld", - "rdf_xml", - "csv", - "tsv", - "lbb_json", - "spec" - ], - "type": "string" - }, - "source": { - "description": "Ontology source text", - "type": "string" - } - }, - "required": [ - "source" - ], - "type": "object" -} - removed
Input schema / properties / relation / descriptionRemoved value: -"Filter to a single relation name." - removed
Input schema / properties / row_limitRemoved value: -{ - "description": "Max edges returned this page (server caps at 1000; default 150).", - "exclusiveMinimum": 0, - "type": "integer" -} - removed
Input schema / properties / shapesRemoved value: -{ - "additionalProperties": false, - "properties": { - "format": { - "enum": [ - "auto", - "turtle", - "n_triples", - "n_quads", - "trig" - ], - "type": "string" - }, - "source": { - "description": "SHACL/RDF shape source text", - "type": "string" - } - }, - "required": [ - "source" - ], - "type": "object" -}
- Added
lbb_models - Changed
lbb_query16 fields changed- removed
Input schema / properties / anchor_nameRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / anchor_typeRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / explainRemoved value: -{ - "type": "boolean" -} - removed
Input schema / properties / include_derivedRemoved value: -{ - "type": "boolean" -} - removed
Input schema / properties / max_derivedRemoved value: -{ - "exclusiveMinimum": 0, - "type": "integer" -} - removed
Input schema / properties / max_premisesRemoved value: -{ - "exclusiveMinimum": 0, - "type": "integer" -} - removed
Input schema / properties / max_roundsRemoved value: -{ - "exclusiveMinimum": 0, - "type": "integer" -} - removed
Input schema / properties / max_solutionsRemoved value: -{ - "exclusiveMinimum": 0, - "type": "integer" -} - changed
Input schema / properties / mode / descriptionPrevious value: -"Selects the variant (one of: structured, sparql, shacl, infer, retrieval_premises, analyze)."New value: +"Selects the variant (one of: structured, sparql, analyze)." - changed
Input schema / properties / mode / enumPrevious value: -[ - "structured", - "sparql", - "shacl", - "infer", - "retrieval_premises", - "analyze" -]New value: +[ + "structured", + "sparql", + "analyze" +] - removed
Input schema / properties / query_top_kRemoved value: -{ - "exclusiveMinimum": 0, - "type": "integer" -} - removed
Input schema / properties / relationRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / rulesRemoved value: -{ - "items": { - "additionalProperties": true, - "properties": { - "body": { - "description": "The condition: a basic graph pattern over current edges (asserted + already-derived), joined on shared variables. Terms may be variables or fixed entities.", - "items": { - "additionalProperties": true, - "properties": { - "object": { - "$ref": "#/properties/rules/items/properties/body/items/properties/subject", - "description": "A rule term: { \"var\": \"x\" } (a variable) or { \"entity\": { \"entity_type\": \"DeliveryStatus\", \"name\": \"Complete\" } } (a fixed entity used as a constant in the body or head)" - }, - "predicate": { - "description": "Relation name. In a rule body, the reserved \"rdf:type\" makes a type-membership constraint: the object names a class ({ entity: { entity_type: \"Contact\" } }, no name) and matches every entity of that class and its subtypes (rdfs:subClassOf closure), so one rule keyed on a supertype fires for all subtypes. Not allowed in a head or an exists/not_exists filter.", - "type": "string" - }, - "subject": { - "anyOf": [ - { - "additionalProperties": true, - "properties": { - "var": { - "description": "A variable, joined across patterns by name", - "type": "string" - } - }, - "required": [ - "var" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "entity": { - "additionalProperties": true, - "properties": { - "entity_id": { - "description": "Entity id (hex), as an alternative to type+name", - "type": "string" - }, - "entity_type": { - "description": "Entity type name (with `name`, names a fixed entity)", - "type": "string" - }, - "name": { - "description": "Entity name (paired with `entity_type`)", - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "entity" - ], - "type": "object" - } - ], - "description": "A rule term: { \"var\": \"x\" } (a variable) or { \"entity\": { \"entity_type\": \"DeliveryStatus\", \"name\": \"Complete\" } } (a fixed entity used as a constant in the body or head)" - } - }, - "type": "object" - }, - "type": "array" - }, - "combinators": { - "description": "exists/not_exists filters folded over the body. not_exists is stratified negation — it lets a rule express a universal condition, e.g. derive \"phase complete\" only when not_exists an incomplete deliverable. A negation cycle is rejected.", - "items": { - "anyOf": [ - { - "additionalProperties": true, - "properties": { - "exists": { - "items": { - "$ref": "#/properties/rules/items/properties/body/items" - }, - "type": "array" - } - }, - "required": [ - "exists" - ], - "type": "object" - }, - { - "additionalProperties": true, - "properties": { - "not_exists": { - "items": { - "$ref": "#/properties/rules/items/properties/body/items" - }, - "type": "array" - } - }, - "required": [ - "not_exists" - ], - "type": "object" - } - ], - "description": "An existence filter over the body solutions: { exists: [...] } (semijoin — keep rows with a compatible match) or { not_exists: [...] } (negation/antijoin — keep rows with none)" - }, - "type": "array" - }, - "head": { - "$ref": "#/properties/rules/items/properties/body/items", - "description": "The triple derived once per body solution. Every head variable must be bound by the body; a fixed-entity object derives a constant (e.g. set the rolled-up status to the Complete entity)." - }, - "name": { - "type": "string" - }, - "order": { - "description": "Run order, low to high (a determinism hint)", - "type": "integer" - } - }, - "required": [ - "name" - ], - "type": "object" - }, - "type": "array" -} - removed
Input schema / properties / shacl_modeRemoved value: -{ - "description": "select returns focus nodes; validate returns a report", - "enum": [ - "select", - "validate" - ], - "type": "string" -} - removed
Input schema / properties / shapesRemoved value: -{ - "items": { - "$ref": "#/properties/body" - }, - "type": "array" -} - removed
Input schema / properties / thresholdRemoved value: -{ - "maximum": 1, - "minimum": 0, - "type": "number" -}
11 tool updates
v0.2.1- First observed
lbb_ask - First observed
lbb_branch - First observed
lbb_commit - First observed
lbb_configure - First observed
lbb_decode - First observed
lbb_ground - First observed
lbb_index - First observed
lbb_inspect - First observed
lbb_observe - First observed
lbb_query - First observed
lbb_search
TDQS
Scored across 22 tools
The set has a mostly clean read/manage/delete split by resource family, making most tools easy to tell apart. Some boundaries blur around lbb_evals versus lbb_models dataset actions, lbb_workflows tests, and lbb_commit versus lbb_rdf, but the descriptions generally resolve these.
Names consistently use lowercase snake_case with the lbb_ prefix and resource-based suffixes such as _manage and _delete. The convention is predictable throughout, even where a write-capable tool like lbb_evals lacks the _manage suffix.
At 22 tools the surface is somewhat heavy, but it reflects genuinely broad domains: graph reads/writes, schema, RDF, workflows, embeddings, fit sources, evals, reviews, files, and model choice. The read/manage/delete splits are purposeful rather than redundant.
Coverage is extensive across graph, ontology, workflows, evals/datasets/experiments, reviews, files, embeddings, and model management, with lifecycle operations for most resources. Minor gaps remain, such as files being read-only with no upload tool and limited dataset-item removal, but agents can largely work around them.
Maintenance
Related MCP Connectors
MCP server for querying BrainKB, a knowledge base for neuroscience knowledge graphs.
Repository knowledge graph MCP server for codebase understanding and debugging.
MCP server for searching Airweave collections with natural language queries.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that enables graph database interactions with Neo4j, allowing users to access and manipulate graph data through natural language commands.-
- AlicenseAqualityDmaintenanceAn MCP server that enables AI-powered exploration of RDF data and SPARQL querying via RDF4J. It provides tools for executing queries, searching knowledge graph resources, and retrieving schema summaries.131MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that builds a knowledge graph from code and text documents, enabling Q\&A and implementation planning via tools like graph_create, graph_plan, and graph_query.7MIT
- FlicenseNot gradedqualityDmaintenanceMCP server that connects AI assistants to the Data Graphs knowledge graph platform, enabling natural language search, exploration, and querying of graph data.12 npm-