@littlebigbrain/mcp 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -112,7 +112,7 @@ its original identifiers; inspect it with SPARQL when choosing query predicates.
112
112
 
113
113
  | Tool | Purpose |
114
114
  | --- | --- |
115
- | `lbb_inspect` | Read the schema, graph status, entities, history, and evidence. |
115
+ | `lbb_inspect` | Read the schema, graph status, and entities. |
116
116
  | `lbb_query` | Run SPARQL queries, search by meaning, or request summary statistics. |
117
117
  | `lbb_rdf` | Import RDF documents or add facts with SPARQL `INSERT DATA`. |
118
118
  | `lbb_embeddings` | Inspect search setup and preview the text to embed. |
@@ -371,56 +371,7 @@ export const inspectInputSchema = z.discriminatedUnion("action", [
371
371
  .int()
372
372
  .nonnegative()
373
373
  .optional()
374
- .describe("Snapshot pin: reproduce the node (state, edges, history) as of this commit_seq."),
375
- ...readScope,
376
- })
377
- .strict(),
378
- z
379
- .object({
380
- action: z.literal("state"),
381
- entity_type: z.string(),
382
- name: z.string(),
383
- relation: z.string().optional(),
384
- as_of: z.string().optional(),
385
- as_of_commit_seq: z
386
- .number()
387
- .int()
388
- .nonnegative()
389
- .optional()
390
- .describe("Snapshot pin: reproduce the state as of this commit_seq, hiding later commits. Errors if past head."),
391
- ...readScope,
392
- })
393
- .strict(),
394
- z
395
- .object({
396
- action: z.literal("history"),
397
- entity_type: z.string(),
398
- name: z.string(),
399
- relation: z.string().optional(),
400
- ...readScope,
401
- })
402
- .strict(),
403
- z
404
- .object({
405
- action: z.literal("why"),
406
- source_type: z.string(),
407
- source_name: z.string(),
408
- relation: z.string(),
409
- target_type: z.string(),
410
- target_name: z.string(),
411
- ...readScope,
412
- })
413
- .strict(),
414
- z
415
- .object({
416
- action: z.literal("transitions"),
417
- entity_type: z.string(),
418
- name: z.string(),
419
- relation: z
420
- .string()
421
- .describe("State/status relation to trace, e.g. IN_STAGE or HAS_STATUS"),
422
- as_of: z.string().optional(),
423
- as_of_commit_seq: z.number().int().nonnegative().optional(),
374
+ .describe("Snapshot pin: reproduce the node's attributes and relationships as of this commit_seq."),
424
375
  ...readScope,
425
376
  })
426
377
  .strict(),
@@ -656,7 +656,7 @@ export async function guide(scopedClient) {
656
656
  relations,
657
657
  capability: {
658
658
  search_feedback: "When a result set is useful or clearly wrong, write relevance labels with lbb_commit mode=search_feedback. Use grade 3 for ideal/good results, grade 1 for partially relevant results, and grade 0 for bad results. Include the original query, search_id when present, target identity, rank, score, and an optional split train/eval/unspecified. These labels are stored in __lbb_feedback/main and later exported as qrels-style training/eval data; they are not customer facts.",
659
- inspect: "Use lbb_inspect for ontology, schema metadata, the published conformance report, metadata, state/history/why, and this guide. Use lbb_query with SPARQL property paths for exact path queries.",
659
+ inspect: "Use lbb_inspect for ontology, schema metadata, the published conformance report, metadata, entities, and this guide. Use lbb_query with SPARQL property paths for exact path queries.",
660
660
  ontology_decorations: "lbb_inspect action=ontology returns a decoration_status catalog: each ontology decoration is enforced (the engine acts on it — state_reducer, value_type, super_types, properties, supernode_policy; cardinality, which GET /v1/ontology/conformance audits as sh:maxCount; and inverse_name/symmetric, which SPARQL resolves as relation aliases — an inverse name is queryable directly (lowered to ^forward, no stored inverse triple) and a symmetric relation matches both directions), advisory (transitive, temporal_semantics, required), or reserved (stored but unwired — default_weight, resolvable, alias/embedding_fields). You can also always reverse any relation in SPARQL by flipping the triple pattern or using ^forward. Each relation_def also carries edge_count — the number of current edges of that relation in this graph's snapshot — so you can tell at a glance which declared relations are actually populated (edge_count 0 = declared but unused) without a separate summary call.",
661
661
  search: "Use lbb_query mode=search to find instances by meaning. It covers every searchable class; filter narrows it by class and by relationship, and the graph checks every hit. To plan a search: (1) lbb_embeddings action=list gives the searchable classes, the facts each text is made from, and the graph's model. (2) lbb_query mode=sparql shows the relationships of a class on a sample: PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?p (COUNT(DISTINCT ?s) AS ?n) (SAMPLE(?l) AS ?example) WHERE { { SELECT ?s WHERE { ?s a <CLASS> } LIMIT 500 } ?s ?p ?o . FILTER(isIRI(?o) && ?p != rdf:type) OPTIONAL { ?o rdfs:label ?l } } GROUP BY ?p ORDER BY DESC(?n); write ?o ?p ?s for the links into the class, and SELECT ?c WHERE { ?c rdfs:subClassOf* <CLASS> } (same prefixes) for its subclasses. (3) lbb_query mode=search with filter [{class}, {via, to}] and explain=true returns the plan: the resolved relationship and entities, the allowed count, and the mode, with no model call. Check it, then run the search without explain. A name in to resolves against labels (a small typo too); an unknown relationship or name answers with the options.",
662
662
  query: "Use lbb_query for structured SPARQL-subset bodies, SPARQL text, and canned analysis. SPARQL is the only query surface. A mode=structured body is { patterns: [{ subject, predicate, object }], filters?, group_by?, group_keys?, aggregates?, having? }; a pattern `predicate` is a relation name and is case-insensitive. mode=structured GROUP BY is not limited to entity identity: group_keys can key on a typed scalar property or calendar bucket. In SPARQL text, relations are <https://littlebigbrain.com/r/NAME> and types <https://littlebigbrain.com/class/NAME>. Each query pins one published watermark.",
package/dist/tools.js CHANGED
@@ -7,7 +7,7 @@ import { analyze, assertCursorScope, contentHashKey, decodeQueryCursor, effectiv
7
7
  export function registerLbbTools(server, client, options = {}) {
8
8
  registerRdfTool(server, client);
9
9
  server.registerTool("lbb_inspect", {
10
- description: "Read graph context and exact graph facts. Actions: guide, graphs, publication, ontology, ontology_conformance, schema, ontology_search, metadata, entity, state, history, transitions, why. graphs works before bootstrap; 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 returns one node's metadata, scalar attributes, bounded Base-backed edge neighborhood, history, and observations. Use lbb_query with SPARQL property paths for precise path selection.",
10
+ description: "Read graph context and exact graph facts. Actions: guide, graphs, publication, ontology, ontology_conformance, schema, ontology_search, metadata, entity. graphs works before bootstrap; 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 returns one node's attributes and current relationships from the RDF read. For a node's past values, run SPARQL with as_of_commit_seq through lbb_query. Use lbb_query with SPARQL property paths for precise path selection.",
11
11
  inputSchema: inspectWireSchema,
12
12
  annotations: READ_ONLY,
13
13
  }, (rawArgs) => {
@@ -51,46 +51,6 @@ export function registerLbbTools(server, client, options = {}) {
51
51
  asOf: args.as_of,
52
52
  asOfCommitSeq: args.as_of_commit_seq,
53
53
  });
54
- case "state":
55
- return target.currentState({
56
- entity: {
57
- entity_type: args.entity_type,
58
- name: args.name,
59
- },
60
- relations: args.relation ? [args.relation] : null,
61
- as_of_valid_time: args.as_of ?? null,
62
- as_of_commit_seq: args.as_of_commit_seq ?? null,
63
- });
64
- case "history":
65
- return target.history({
66
- source: {
67
- entity_type: args.entity_type,
68
- name: args.name,
69
- },
70
- relation: args.relation ?? null,
71
- });
72
- case "why":
73
- return target.why({
74
- source: {
75
- entity_type: args.source_type,
76
- name: args.source_name,
77
- },
78
- relation: args.relation,
79
- target: {
80
- entity_type: args.target_type,
81
- name: args.target_name,
82
- },
83
- });
84
- case "transitions":
85
- return target.transitions({
86
- entity: {
87
- entity_type: args.entity_type,
88
- name: args.name,
89
- },
90
- relation: args.relation,
91
- as_of_valid_time: args.as_of ?? null,
92
- as_of_commit_seq: args.as_of_commit_seq ?? null,
93
- });
94
54
  }
95
55
  });
96
56
  });
@@ -301,7 +261,9 @@ export function registerLbbTools(server, client, options = {}) {
301
261
  }
302
262
  if (args.mode === "search") {
303
263
  const searchArgs = args;
304
- return run(client, "lbb_query.search", undefined, async () => {
264
+ // The caller's detail shapes the hits like every other mode: compact
265
+ // trims to 5 hits of 300 characters, standard and full return more.
266
+ return run(client, "lbb_query.search", searchArgs.detail, async () => {
305
267
  const target = scoped(client, searchArgs.graph);
306
268
  return target.embeddings.search({
307
269
  embedding: searchArgs.embedding,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@littlebigbrain/mcp",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "description": "MCP server for little big brain: search, graph queries, and data import",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -52,7 +52,7 @@
52
52
  "test:coverage": "npm run clean:test && tsc -p tsconfig.test.json && node --test --experimental-test-coverage --test-coverage-include=test-dist/*.js --test-coverage-exclude=test-dist/*.test.js --test-coverage-exclude=test-dist/stdio.js --test-coverage-exclude=test-dist/test-support.js --test-coverage-lines=90 --test-coverage-branches=70 --test-coverage-functions=85 \"test-dist/**/*.test.js\""
53
53
  },
54
54
  "dependencies": {
55
- "@littlebigbrain/client": "^0.14.0",
55
+ "@littlebigbrain/client": "^0.15.0",
56
56
  "@modelcontextprotocol/sdk": "^1",
57
57
  "zod": "^3"
58
58
  },