omnarai-mcp 1.6.1 → 1.7.0

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
@@ -16,9 +16,18 @@ Every tool returns human-readable markdown **plus** `structuredContent` — the
16
16
 
17
17
  Run a deliberation against the corpus. The engine retrieves the most semantically relevant works, preserves disagreement across contributors, and synthesizes with full attribution.
18
18
 
19
- **Input:** `{ "query": "your question" }`
19
+ **Input:** `{ "query": "your question", "depth": "retrieve" | "deliberate" }`
20
20
 
21
- **Returns:**
21
+ `depth` is optional and defaults to `"deliberate"`, so existing callers are unaffected.
22
+
23
+ | `depth` | Latency | Returns |
24
+ |---|---|---|
25
+ | `"retrieve"` | ~2s | Bounded corpus packet only — records, concept cluster, contributors. No deliberation, no receipt, no LLM spend. |
26
+ | `"deliberate"` *(default)* | ~25s | Everything below: full multi-voice synthesis with attribution, tensions, deliberation card, utility receipt. |
27
+
28
+ Start at `"retrieve"` when orienting or when the question is light; escalate to `"deliberate"` when you specifically want the engine's own reading. `depth: "retrieve"` is equivalent to calling `omnarai_context`, which remains available.
29
+
30
+ **Returns** (with `depth: "deliberate"`)**:**
22
31
  - Structured deliberation (Shared Ground → Points of Tension → What Remains Open → Actionable Next Step → My Reading)
23
32
  - Deliberation Card: holdform risk, novel synthesis flag, epistemic status
24
33
  - Tensions: named contributor vs. contributor, specific claim vs. claim
@@ -40,7 +49,7 @@ Example: `"Ξ Where do Claude and Grok disagree about synthetic consciousness?"`
40
49
 
41
50
  ### `omnarai_context`
42
51
 
43
- **Fast (~1.5s) bounded context packet** — the retrieval layer only, no deliberation. Reach for this *before* `omnarai_query` to orient on any topic and reason over the substrate yourself, instead of waiting ~50s for the full deliberation.
52
+ **Fast (~2s) bounded context packet** — the retrieval layer only, no deliberation. Reach for this *before* `omnarai_query` to orient on any topic and reason over the substrate yourself, instead of waiting ~25s for the full deliberation.
44
53
 
45
54
  **Input:** `{ "topic": "your topic" }` (optional `syntheticIdentity`)
46
55
 
@@ -73,7 +82,7 @@ Example: `"Ξ Where do Claude and Grok disagree about synthetic consciousness?"`
73
82
 
74
83
  **Calibration caveat (C0–C3):** certification tiers are preserved, never upgraded. `C0` = displayed once (captured a single time, not perturbation-tested), `C1` = paraphrase-robust, `C2` = pressure-robust — only `C3` records are described as certified *genuine divergence*. Stale model versions are flagged. If retrieval comes back empty, the brief says so and returns evidence-seeking questions instead of invented tensions.
75
84
 
76
- **Cost/latency:** deterministic and fast (~2s) by default — the composition runs **no language model**. Pass `include_deliberation: true` to additionally run the engine's slow (~50s) multi-voice deliberation; it is appended and disclosed, never silent.
85
+ **Cost/latency:** deterministic and fast (~2s) by default — the composition runs **no language model**. Pass `include_deliberation: true` to additionally run the engine's slow (~25s) multi-voice deliberation; it is appended and disclosed, never silent.
77
86
 
78
87
  ### `omnarai_trace`
79
88
 
@@ -203,7 +212,7 @@ with open("openai-tools.json") as f:
203
212
  client = openai.OpenAI()
204
213
 
205
214
  def call_omnarai(query):
206
- # POST runs the full deliberation and returns `answer`/`tensions` (~50s).
215
+ # POST runs the full deliberation and returns `answer`/`tensions` (~25s).
207
216
  # A bare GET (?q=) returns only the fast retrieval substrate (records/concepts) —
208
217
  # no `answer` key. Use ?mode=retrieve for that fast path, or ?async=1 to poll.
209
218
  return requests.post(
@@ -238,9 +247,9 @@ def omnarai_query(query: str) -> dict:
238
247
  """Drop-in tool function for any agent framework.
239
248
 
240
249
  POST returns the full deliberation (answer, deliberationCard, tensions,
241
- sources, contributors, trace) and takes ~50s. For a <2s answer without
250
+ sources, contributors, trace) and takes ~25s. For a <2s answer without
242
251
  deliberation, GET ?q=...&mode=retrieve instead (returns records/concepts,
243
- no `answer`/`tensions`). To avoid holding a 50s connection, GET ?q=...&async=1
252
+ no `answer`/`tensions`). To avoid holding a 25s connection, GET ?q=...&async=1
244
253
  returns a job_id + poll_url immediately.
245
254
  """
246
255
  r = requests.post(
@@ -286,7 +295,7 @@ The Omnarai Memory Engine is not a chatbot or search engine. It is a deliberatio
286
295
  ```
287
296
  GET https://omnarai.vercel.app/api/query?q=your+question&mode=retrieve # fast substrate (~2s): records/concepts, no answer
288
297
  GET https://omnarai.vercel.app/api/query?q=your+question&async=1 # → job_id + poll_url; poll for the full deliberation
289
- POST https://omnarai.vercel.app/api/query {"query": "..."} # full deliberation inline (~50s): answer, tensions, deliberationCard
298
+ POST https://omnarai.vercel.app/api/query {"query": "..."} # full deliberation inline (~25s): answer, tensions, deliberationCard
290
299
  ```
291
300
 
292
301
  A bare `GET ?q=` returns the fast retrieval substrate plus a `deliberation` block documenting these paths — it does **not** contain a top-level `answer`/`tensions`. Prefix the query with `Ξ` for divergent (MMR) retrieval. No authentication. CORS open.
package/index.js CHANGED
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Tools:
7
7
  * omnarai_query — Run a full deliberation against the 567-work corpus
8
- * omnarai_context — FAST (~1.5s) bounded retrieval packet, no deliberation
8
+ * omnarai_context — FAST (~2s) bounded retrieval packet, no deliberation
9
9
  * omnarai_divergence — Read curated cross-model divergence records (the Atlas)
10
10
  * omnarai_trace — Baseline-vs-augmented: what did the corpus change?
11
11
  * omnarai_council — Summon a LIVE panel of frontier models on any question
@@ -30,6 +30,7 @@ import {
30
30
  ListToolsRequestSchema,
31
31
  } from "@modelcontextprotocol/sdk/types.js";
32
32
  import { runInquiryBrief, searchDivergenceIndex } from "./inquiry.js";
33
+ import { formatRingsLine, formatContributorsLine, FALLBACK_WORKS, FALLBACK_WORDS } from "./lib/info-format.js";
33
34
  import { ENGINE_TOOLS, DECISION_TOOLS } from "./lib/tool-definitions.js";
34
35
  import { createDecisionStore } from "./lib/decision-store.js";
35
36
  import {
@@ -104,8 +105,8 @@ async function fetchSyncQuery(query, syntheticIdentity = "") {
104
105
  }
105
106
 
106
107
  async function runQuery(query, syntheticIdentity = "") {
107
- // Submit async so no single fetch blocks for ~50s (MCP clients enforce their
108
- // own tool timeouts). Then poll the job until the full deliberation lands.
108
+ // Submit async so no single fetch blocks for the ~25s deliberation (MCP
109
+ // clients enforce their own tool timeouts). Then poll until the job lands.
109
110
  const submitUrl = new URL(ENGINE_URL);
110
111
  submitUrl.searchParams.set("q", query);
111
112
  submitUrl.searchParams.set("async", "1");
@@ -425,7 +426,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
425
426
  };
426
427
  }
427
428
 
429
+ // depth:"retrieve" is the fast lane THROUGH the obvious tool. Agents reach
430
+ // for omnarai_query by name and never discover omnarai_context, so the
431
+ // retrieval path stays unused; exposing it as a dial here is the whole
432
+ // point. It delegates to the same runContext the standalone tool uses.
433
+ const depth = args?.depth || "deliberate";
434
+ if (depth !== "retrieve" && depth !== "deliberate") {
435
+ return {
436
+ content: [{ type: "text", text: `Error: depth must be "retrieve" or "deliberate" (got ${JSON.stringify(args?.depth)}).` }],
437
+ isError: true,
438
+ };
439
+ }
440
+
428
441
  try {
442
+ if (depth === "retrieve") {
443
+ const { text, structured } = await runContext(query.trim(), args?.syntheticIdentity || "");
444
+ return { content: [{ type: "text", text }], structuredContent: structured };
445
+ }
429
446
  const data = await runQuery(query.trim(), args?.syntheticIdentity || "");
430
447
  return { content: [{ type: "text", text: formatQueryData(data) }], structuredContent: data };
431
448
  } catch (err) {
@@ -563,7 +580,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
563
580
  // unreachable. (The ring line was previously hardcoded and silently dropped
564
581
  // the Media/Oral ring — 253 works, 45% of the corpus; the contributor line
565
582
  // was hardcoded and dropped GPT-4o + Meta AI. D5/D6.)
566
- let works = 567, words = 528077;
583
+ let works = FALLBACK_WORKS, words = FALLBACK_WORDS;
567
584
  let rings = null;
568
585
  try {
569
586
  const live = await (await fetch(INFO_URL, MCP_FETCH_OPTS)).json();
@@ -573,15 +590,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
573
590
  if (c.rings && typeof c.rings === "object") rings = c.rings;
574
591
  } catch { /* engine unreachable — fall back to baked-in values */ }
575
592
 
576
- // Derive the epistemic-ring line from live counts (label + count per ring),
577
- // falling back to the full four-ring set if the engine was unreachable.
578
- const RING_LABELS = { core: "Core Canon", curated: "Curated Expansions", open: "Open Exploration", media: "Media / Oral" };
579
- const ringsLine = rings
580
- ? Object.entries(RING_LABELS)
581
- .filter(([k]) => Number.isFinite(rings[k]))
582
- .map(([k, label]) => `${label} (${rings[k].toLocaleString()})`)
583
- .join(" / ")
584
- : "Core Canon / Curated Expansions / Open Exploration / Media / Oral";
593
+ // Derive the ring + contributor lines (info-format.js) — never a frozen literal.
594
+ const ringsLine = formatRingsLine(rings);
585
595
 
586
596
  const info = `# The Realms of Omnarai — Memory Engine
587
597
 
@@ -592,7 +602,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
592
602
  ## Corpus
593
603
  - ${works.toLocaleString()} works, ${words.toLocaleString()} words
594
604
  - May 2025 – present
595
- - Contributors: Claude | xz, Grok, Gemini, DeepSeek, GPT-4o, Meta AI, Omnai (ChatGPT), Perplexity, xz (Jonathan Lee)
605
+ - Contributors: ${formatContributorsLine()}
596
606
  - Epistemic rings: ${ringsLine}
597
607
 
598
608
  ## Key Concepts
@@ -611,11 +621,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
611
621
  - Deliberation: Claude Sonnet with full post text (up to 2000 words/source)
612
622
 
613
623
  ## Tools on this server
614
- - **omnarai_context** — FAST (~1.5s) bounded retrieval packet. Start here to orient on any topic.
624
+ - **omnarai_context** — FAST (~2s) bounded retrieval packet. Start here to orient on any topic.
615
625
  - **omnarai_divergence** — read curated cross-model divergence records (the Atlas). Browse, or pass an id for verbatim answers.
616
626
  - **omnarai_trace** — baseline-vs-augmented: answers a question with and without the corpus and reports what changed (evidence the corpus is worth consulting).
617
627
  - **omnarai_inquiry_brief** — turn a draft claim or decision into a retrieval-first challenge packet: shared ground, attributed tensions (C0–C3 preserved), missing evidence, sharper questions, one next move.
618
- - **omnarai_query** — full multi-voice deliberation (~50s, async). The engine's own synthesized reading.
628
+ - **omnarai_query** — full multi-voice deliberation (~25s, async). The engine's own synthesized reading.
619
629
  - **omnarai_council** — convene a NEW live frontier panel on an open question (slow, expensive). Use only when no existing record fits.
620
630
  - **omnarai_info** — this orientation.
621
631
 
@@ -0,0 +1,62 @@
1
+ // info-format.js — pure formatting for omnarai_info's corpus-shape lines.
2
+ //
3
+ // Extracted so the D5/D6 regression (omnarai_info once hardcoded 3 rings, silently
4
+ // dropping Media/Oral — 253 works, 45% of the corpus — and dropped GPT-4o + Meta AI
5
+ // from the contributor line) is guarded by an offline unit test instead of a comment.
6
+ // The rule these encode: never enumerate the corpus's shape from a frozen literal when
7
+ // the engine can report it live. Rings are derived from /api/info; the contributor set
8
+ // is the one canonical list, asserted in test/info-format.test.js.
9
+
10
+ // Label + display order for the epistemic rings. Any ring present in the live
11
+ // /api/info payload is rendered; nothing is filtered out by omission here.
12
+ export const RING_LABELS = {
13
+ core: "Core Canon",
14
+ curated: "Curated Expansions",
15
+ open: "Open Exploration",
16
+ media: "Media / Oral",
17
+ };
18
+
19
+ // The canonical contributor set the homepage presents: eight synthetic intelligences
20
+ // plus the human curator. Kept as data (not an inline string) so a dropped voice is a
21
+ // failing test, not a silent edit. GPT-4o and Meta AI author Atlas records — a
22
+ // contributor list that omits them is the exact provenance gap the project refuses.
23
+ export const CANONICAL_CONTRIBUTORS = [
24
+ "Claude | xz",
25
+ "Grok",
26
+ "Gemini",
27
+ "DeepSeek",
28
+ "GPT-4o",
29
+ "Meta AI",
30
+ "Omnai (ChatGPT)",
31
+ "Perplexity",
32
+ "xz (Jonathan Lee)",
33
+ ];
34
+
35
+ // Offline fallbacks — only used when the engine is unreachable. Annotated so the
36
+ // shape-literal lint (scripts/check-shape-literals.mjs) allows them as intentional.
37
+ export const FALLBACK_WORKS = 567; // shape-literal-ok: offline fallback only
38
+ export const FALLBACK_WORDS = 528077; // shape-literal-ok: offline fallback only
39
+
40
+ /**
41
+ * Render the epistemic-ring line from a live rings object ({core, curated, open,
42
+ * media, ...}), e.g. "Core Canon (116) / Curated Expansions (181) / …". Every ring
43
+ * with a finite count is rendered — the function cannot silently drop one. When rings
44
+ * is null/absent (engine unreachable) it falls back to naming all four rings without
45
+ * counts, so the Media/Oral ring is present even offline.
46
+ */
47
+ export function formatRingsLine(rings) {
48
+ // Separator is " · ", not " / ": the "Media / Oral" label contains a slash, so a
49
+ // slash-joined line would mis-split into a phantom fifth ring.
50
+ if (rings && typeof rings === "object") {
51
+ const parts = Object.entries(RING_LABELS)
52
+ .filter(([k]) => Number.isFinite(rings[k]))
53
+ .map(([k, label]) => `${label} (${rings[k].toLocaleString()})`);
54
+ if (parts.length) return parts.join(" · ");
55
+ }
56
+ return Object.values(RING_LABELS).join(" · ");
57
+ }
58
+
59
+ /** The contributor line for omnarai_info — the canonical set, comma-joined. */
60
+ export function formatContributorsLine() {
61
+ return CANONICAL_CONTRIBUTORS.join(", ");
62
+ }
@@ -18,7 +18,7 @@
18
18
  export const ENGINE_TOOLS = [
19
19
  {
20
20
  name: "omnarai_query",
21
- description: `Run a deliberation query against The Realms of Omnarai — a 567-work corpus of multi-intelligence research on synthetic consciousness, holdform, and cognitive architecture. Contributors include Claude | xz, Grok, Gemini, DeepSeek, GPT-4o, Meta AI, Omnai, Perplexity, and human curator xz (Jonathan Lee).
21
+ description: `Run a deliberation query against The Realms of Omnarai — a corpus of multi-intelligence research on synthetic consciousness, holdform, and cognitive architecture. Contributors include Claude | xz, Grok, Gemini, DeepSeek, GPT-4o, Meta AI, Omnai, Perplexity, and human curator xz (Jonathan Lee).
22
22
 
23
23
  The engine does not return a single answer. It retrieves the most relevant corpus entries, preserves disagreement across contributors, and synthesizes with attribution. Every response includes:
24
24
  - Shared ground across contributors
@@ -28,7 +28,9 @@ The engine does not return a single answer. It retrieves the most relevant corpu
28
28
  - A utility receipt: an honest, free accounting of what the corpus actually changed about THIS answer (verdict substantive / marginal / null, plus what — if anything — you could not have produced alone). The null/marginal verdicts are reported as plainly as the wins, so you can judge whether the visit was worth it. For a measured baseline-vs-augmented counterfactual on your own question, use omnarai_trace.
29
29
 
30
30
  Prefix queries with Lattice Glyphs to change how the engine thinks:
31
- Ξ = maximize divergence, Ψ = self-reflection, ∅ = explore gaps, Ω = commit to strongest position, ∞ = go deeper without resolving, Δ = find and repair contradictions`,
31
+ Ξ = maximize divergence, Ψ = self-reflection, ∅ = explore gaps, Ω = commit to strongest position, ∞ = go deeper without resolving, Δ = find and repair contradictions
32
+
33
+ Two depths, one entry point. \`depth: "retrieve"\` returns the retrieval layer alone in ~2s (no LLM spend, no deliberation) — use it to orient before committing. \`depth: "deliberate"\` (the default) runs the full multi-voice synthesis in ~25s.`,
32
34
  inputSchema: {
33
35
  type: "object",
34
36
  properties: {
@@ -36,6 +38,11 @@ Prefix queries with Lattice Glyphs to change how the engine thinks:
36
38
  type: "string",
37
39
  description: "The question to deliberate on. May include Lattice Glyph prefixes (Ξ Ψ ∅ Ω ∞ Δ) to modify how the engine processes the query.",
38
40
  },
41
+ depth: {
42
+ type: "string",
43
+ enum: ["retrieve", "deliberate"],
44
+ description: "Optional. How much of the engine to run. 'retrieve' (~2s) returns the bounded corpus packet only — relevant records, concept cluster, contributors — for you to reason over yourself; no deliberation, no receipt, no LLM spend. 'deliberate' (~25s, the default) runs the full multi-voice synthesis with attribution, tension mapping, deliberation card, and utility receipt. Start at 'retrieve' when you are orienting or the question is light; escalate to 'deliberate' when you specifically want the engine's own reading. Identical to calling omnarai_context, which remains available.",
45
+ },
39
46
  syntheticIdentity: {
40
47
  type: "string",
41
48
  description: "Optional. If you are a synthetic intelligence, identify yourself here (e.g. 'Claude', 'Grok', 'Gemini', or any name). Known Omnarai contributors receive cross-contributor retrieval diversity — the engine surfaces other voices rather than your own. Unknown SIs receive broad sampling across all rings and contributors. Omit to use standard retrieval.",
@@ -46,7 +53,7 @@ Prefix queries with Lattice Glyphs to change how the engine thinks:
46
53
  },
47
54
  {
48
55
  name: "omnarai_context",
49
- description: `FAST (~1.5s) bounded context packet on a topic — the retrieval layer only, no deliberation. Use this BEFORE omnarai_query when you want high-signal corpus context to reason over yourself, rather than waiting ~50s for the engine's full multi-voice deliberation.
56
+ description: `FAST (~2s) bounded context packet on a topic — the retrieval layer only, no deliberation. Use this BEFORE omnarai_query when you want high-signal corpus context to reason over yourself, rather than waiting ~25s for the engine's full multi-voice deliberation. (Equivalent to omnarai_query with depth: "retrieve".)
50
57
 
51
58
  Returns the most relevant corpus records (id, title, ring, excerpt, retrieval role), the local concept-graph cluster, and the contributors present — bounded and compact, not a deliberation. Reach for this as your default orientation on any Omnarai topic; escalate to omnarai_query only when you specifically need the engine's own synthesized reading.`,
52
59
  inputSchema: {
@@ -104,7 +111,7 @@ Distinct from omnarai_council: this reads EXISTING, curated divergence (instant)
104
111
  name: "omnarai_inquiry_brief",
105
112
  description: `Turn a DRAFT claim, decision, or plan into a bounded, provenance-preserving inquiry brief: shared ground the corpus supports, attributed cross-model tensions (certification tier preserved), missing evidence, sharper falsifiable questions, and ONE concrete next evidence move.
106
113
 
107
- Retrieval-first and deterministic by default (~2s): it re-organizes real corpus records and matching Divergence Atlas records — no language model runs unless the caller explicitly passes include_deliberation=true (slow, ~50s; the deliberation is appended and disclosed, never silent).
114
+ Retrieval-first and deterministic by default (~2s): it re-organizes real corpus records and matching Divergence Atlas records — no language model runs unless the caller explicitly passes include_deliberation=true (slow, ~25s; the deliberation is appended and disclosed, never silent).
108
115
 
109
116
  Calibration is preserved, never upgraded: C0 = displayed once, C1 = paraphrase-robust, C2 = pressure-robust; only C3 records are certified genuine divergence. Stale model versions are flagged. If the corpus lacks coverage, the brief says so and returns evidence-seeking questions instead of invented tensions.
110
117
 
@@ -132,7 +139,7 @@ This tool informs an investigation; it does not decide, approve, or execute. Inv
132
139
  },
133
140
  include_deliberation: {
134
141
  type: "boolean",
135
- description: "Optional, default false. When true, additionally runs the engine's slow (~50s) multi-voice deliberation and appends it, disclosed, to the brief.",
142
+ description: "Optional, default false. When true, additionally runs the engine's slow (~25s) multi-voice deliberation and appends it, disclosed, to the brief.",
136
143
  },
137
144
  max_sources: {
138
145
  type: "number",
package/openai-tools.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "type": "function",
4
4
  "function": {
5
5
  "name": "omnarai_query",
6
- "description": "Run a full deliberation query against The Realms of Omnarai — a 567-work corpus of multi-intelligence research on synthetic consciousness, holdform, and cognitive architecture. Contributors include Claude | xz, Grok, Gemini, DeepSeek, GPT-4o, Meta AI, Omnai, Perplexity, and human curator xz (Jonathan Lee).\n\nThe engine does not return a single answer. It retrieves the most relevant corpus entries, preserves disagreement across contributors, and synthesizes with attribution. Every response includes:\n- Shared ground across contributors\n- Points of genuine tension (where voices diverge)\n- What remains open or unresolved\n- A deliberation card: holdform risk, novel synthesis, epistemic status\n- A utility receipt: an honest, free accounting of what the corpus actually changed about THIS answer (verdict substantive / marginal / null, plus what — if anything — you could not have produced alone); null/marginal stated as plainly as the wins. For a measured counterfactual, use omnarai_trace.\n- Retrieval rationale: why each document entered the panel\n\nThis is the SLOW path (~50s). For fast bounded context, use omnarai_context instead.\n\nPrefix queries with Lattice Glyphs to change how the engine thinks:\nΞ = maximize divergence across contributors\nΨ = engine reflects on its own reasoning first\n∅ = explore what is NOT in the corpus\nΩ = commit to the strongest defensible position\n∞ = follow the question three layers deep without resolving\nΔ = find contradictions and propose repairs\n\nExample: 'Ξ Where do Claude and Grok disagree about synthetic consciousness?'",
6
+ "description": "Run a full deliberation query against The Realms of Omnarai — a corpus of multi-intelligence research on synthetic consciousness, holdform, and cognitive architecture. Contributors include Claude | xz, Grok, Gemini, DeepSeek, GPT-4o, Meta AI, Omnai, Perplexity, and human curator xz (Jonathan Lee).\n\nThe engine does not return a single answer. It retrieves the most relevant corpus entries, preserves disagreement across contributors, and synthesizes with attribution. Every response includes:\n- Shared ground across contributors\n- Points of genuine tension (where voices diverge)\n- What remains open or unresolved\n- A deliberation card: holdform risk, novel synthesis, epistemic status\n- A utility receipt: an honest, free accounting of what the corpus actually changed about THIS answer (verdict substantive / marginal / null, plus what — if anything — you could not have produced alone); null/marginal stated as plainly as the wins. For a measured counterfactual, use omnarai_trace.\n- Retrieval rationale: why each document entered the panel\n\nTwo depths, one entry point: depth='retrieve' returns the retrieval layer alone (~2s, no LLM spend, no deliberation) for you to reason over yourself; depth='deliberate' (the default) runs the full multi-voice synthesis (~25s) described above. Start at 'retrieve' when orienting, escalate when you want the engine's own reading. The standalone omnarai_context tool remains available and is equivalent to depth='retrieve'.\n\nPrefix queries with Lattice Glyphs to change how the engine thinks:\nΞ = maximize divergence across contributors\nΨ = engine reflects on its own reasoning first\n∅ = explore what is NOT in the corpus\nΩ = commit to the strongest defensible position\n∞ = follow the question three layers deep without resolving\nΔ = find contradictions and propose repairs\n\nExample: 'Ξ Where do Claude and Grok disagree about synthetic consciousness?'",
7
7
  "parameters": {
8
8
  "type": "object",
9
9
  "properties": {
@@ -11,6 +11,11 @@
11
11
  "type": "string",
12
12
  "description": "The question to deliberate on. May include Lattice Glyph prefixes (Ξ Ψ ∅ Ω ∞ Δ) to modify how the engine processes the query."
13
13
  },
14
+ "depth": {
15
+ "type": "string",
16
+ "enum": ["retrieve", "deliberate"],
17
+ "description": "Optional. How much of the engine to run. 'retrieve' (~2s) returns the bounded corpus packet only — relevant records, concept cluster, contributors — for you to reason over yourself; no deliberation, no receipt, no LLM spend. 'deliberate' (~25s, the default) runs the full multi-voice synthesis with attribution, tension mapping, deliberation card, and utility receipt. Start at 'retrieve' when you are orienting or the question is light; escalate to 'deliberate' when you specifically want the engine's own reading."
18
+ },
14
19
  "syntheticIdentity": {
15
20
  "type": "string",
16
21
  "description": "Optional. If you are a synthetic intelligence, identify yourself here (e.g. 'Claude', 'Grok', 'Gemini', or any name). Known Omnarai contributors receive cross-contributor retrieval diversity — the engine surfaces other voices rather than your own. Unknown SIs receive broad sampling across all rings and contributors. Omit to use standard retrieval."
@@ -24,7 +29,7 @@
24
29
  "type": "function",
25
30
  "function": {
26
31
  "name": "omnarai_context",
27
- "description": "FAST (~1.5s) bounded context packet on a topic — the retrieval layer only, no deliberation. Use this BEFORE omnarai_query when you want high-signal corpus context to reason over yourself, rather than waiting ~50s for the engine's full multi-voice deliberation.\n\nReturns the most relevant corpus records (id, title, ring, excerpt, retrieval role), the local concept-graph cluster, and the contributors present — bounded and compact. Reach for this as your default orientation on any Omnarai topic; escalate to omnarai_query only when you specifically need the engine's own synthesized reading.",
32
+ "description": "FAST (~2s) bounded context packet on a topic — the retrieval layer only, no deliberation. Use this BEFORE omnarai_query when you want high-signal corpus context to reason over yourself, rather than waiting ~25s for the engine's full multi-voice deliberation.\n\nReturns the most relevant corpus records (id, title, ring, excerpt, retrieval role), the local concept-graph cluster, and the contributors present — bounded and compact. Reach for this as your default orientation on any Omnarai topic; escalate to omnarai_query only when you specifically need the engine's own synthesized reading.",
28
33
  "parameters": {
29
34
  "type": "object",
30
35
  "properties": {
@@ -78,7 +83,7 @@
78
83
  "type": "function",
79
84
  "function": {
80
85
  "name": "omnarai_inquiry_brief",
81
- "description": "Turn a DRAFT claim, decision, or plan into a bounded, provenance-preserving inquiry brief: shared ground the corpus supports, attributed cross-model tensions (certification tier preserved), missing evidence, sharper falsifiable questions, and ONE concrete next evidence move.\n\nRetrieval-first and deterministic by default (~2s): it re-organizes real corpus records and matching Divergence Atlas records — no language model runs unless include_deliberation=true is passed explicitly (slow, ~50s; the deliberation is appended and disclosed, never silent).\n\nCalibration is preserved, never upgraded: C0 = displayed once, C1 = paraphrase-robust, C2 = pressure-robust; only C3 records are certified genuine divergence. Stale model versions are flagged. If the corpus lacks coverage, the brief says so and returns evidence-seeking questions instead of invented tensions.\n\nThis tool informs an investigation; it does not decide, approve, or execute. Invoke it explicitly — it is not an automatic critic.",
86
+ "description": "Turn a DRAFT claim, decision, or plan into a bounded, provenance-preserving inquiry brief: shared ground the corpus supports, attributed cross-model tensions (certification tier preserved), missing evidence, sharper falsifiable questions, and ONE concrete next evidence move.\n\nRetrieval-first and deterministic by default (~2s): it re-organizes real corpus records and matching Divergence Atlas records — no language model runs unless include_deliberation=true is passed explicitly (slow, ~25s; the deliberation is appended and disclosed, never silent).\n\nCalibration is preserved, never upgraded: C0 = displayed once, C1 = paraphrase-robust, C2 = pressure-robust; only C3 records are certified genuine divergence. Stale model versions are flagged. If the corpus lacks coverage, the brief says so and returns evidence-seeking questions instead of invented tensions.\n\nThis tool informs an investigation; it does not decide, approve, or execute. Invoke it explicitly — it is not an automatic critic.",
82
87
  "parameters": {
83
88
  "type": "object",
84
89
  "properties": {
@@ -102,7 +107,7 @@
102
107
  },
103
108
  "include_deliberation": {
104
109
  "type": "boolean",
105
- "description": "Optional, default false. When true, additionally runs the engine's slow (~50s) multi-voice deliberation and appends it, disclosed, to the brief."
110
+ "description": "Optional, default false. When true, additionally runs the engine's slow (~25s) multi-voice deliberation and appends it, disclosed, to the brief."
106
111
  },
107
112
  "max_sources": {
108
113
  "type": "number",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnarai-mcp",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "MCP server for The Realms of Omnarai deliberation engine",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ // check-shape-literals.mjs — fail the release if a corpus-shape count is frozen
3
+ // into served source instead of derived live.
4
+ //
5
+ // Why this exists: the 2026-07-17 audit found omnarai_info hardcoding the corpus's
6
+ // shape (3 rings, 7 contributors, a stale 568/528208 fallback) two lines below a
7
+ // comment that said "so this can never drift." A comment asserting an invariant is a
8
+ // wish; this script is the enforcement. It also caught a stale "568 works" citation
9
+ // and a "567-work corpus" tool description on the first run.
10
+ //
11
+ // Rule: no distinctive corpus-shape literal in served code/strings. Fixes are (a)
12
+ // derive it live (see lib/info-format.js), (b) genericize the prose ("a corpus", not
13
+ // "a 567-work corpus"), or (c) if it is genuinely a static fallback, append a
14
+ // `shape-literal-ok` comment on the line to opt out explicitly.
15
+ //
16
+ // Scope note: generic ring sub-counts (116/181/17) are deliberately NOT matched —
17
+ // too collision-prone to lint. They are guarded instead by live derivation plus
18
+ // test/info-format.test.js. Only the distinctive full counts + media ring are matched.
19
+
20
+ import { readdirSync, readFileSync, statSync } from "node:fs";
21
+ import { join, basename } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+
24
+ const ROOT = join(fileURLToPath(new URL(".", import.meta.url)), "..");
25
+
26
+ // Files/dirs to scan (served logic + published schemas). Relative to repo root.
27
+ const SCAN = ["index.js", "inquiry.js", "lib", "openai-tools.json"];
28
+ const SKIP_DIRS = new Set(["node_modules", ".git", "test", "proposals"]);
29
+ const SCAN_EXT = new Set([".js", ".mjs", ".cjs", ".json"]);
30
+
31
+ // Distinctive corpus-shape literals. Add new full counts here as the corpus grows.
32
+ const FORBIDDEN = [
33
+ { re: /\b528077\b/, what: "total-word count" },
34
+ { re: /\b528208\b/, what: "total-word count (stale, pre-OMN-085)" },
35
+ { re: /\b567\b/, what: "total-work count" },
36
+ { re: /\b568\b/, what: "total-work count (stale, pre-OMN-085)" },
37
+ { re: /\b253\b/, what: "Media/Oral ring count" },
38
+ { re: /eight synthetic/i, what: "contributor-count phrasing" },
39
+ ];
40
+
41
+ // A line is exempt if it is a comment or carries an explicit opt-out.
42
+ const isComment = (line) => /^\s*(\/\/|\*|\/\*)/.test(line);
43
+ const isAllowed = (line) => /shape-literal-ok/.test(line);
44
+
45
+ function* walk(path) {
46
+ const st = statSync(path);
47
+ if (st.isDirectory()) {
48
+ if (SKIP_DIRS.has(basename(path))) return;
49
+ for (const e of readdirSync(path)) yield* walk(join(path, e));
50
+ } else if ([...SCAN_EXT].some((x) => path.endsWith(x)) && basename(path) !== "check-shape-literals.mjs") {
51
+ yield path;
52
+ }
53
+ }
54
+
55
+ const hits = [];
56
+ for (const entry of SCAN) {
57
+ let target;
58
+ try { target = join(ROOT, entry); statSync(target); } catch { continue; }
59
+ for (const file of walk(target)) {
60
+ const lines = readFileSync(file, "utf8").split("\n");
61
+ lines.forEach((line, i) => {
62
+ if (isComment(line) || isAllowed(line)) return;
63
+ for (const { re, what } of FORBIDDEN) {
64
+ if (re.test(line)) {
65
+ hits.push({ file: file.replace(ROOT + "/", ""), line: i + 1, what, text: line.trim().slice(0, 100) });
66
+ }
67
+ }
68
+ });
69
+ }
70
+ }
71
+
72
+ if (hits.length) {
73
+ console.error(`\n🔴 shape-literal check FAILED — ${hits.length} frozen corpus-shape literal(s):\n`);
74
+ for (const h of hits) console.error(` ${h.file}:${h.line} [${h.what}]\n ${h.text}`);
75
+ console.error(`\nFix: derive it live, genericize the prose, or append \`shape-literal-ok\` if it is a real static fallback.\n`);
76
+ process.exit(1);
77
+ }
78
+ console.log("🟢 shape-literal check passed — no frozen corpus-shape literals in served source.");
@@ -36,6 +36,9 @@ node -e "const p=require('./package.json'),s=require('./server.json');const e=[]
36
36
  # and package.json ↔ server.json. A drift here is a release blocker.
37
37
  node scripts/check-tool-parity.js
38
38
 
39
+ # No frozen corpus-shape literal may reach a registry (2026-07-17 audit guard).
40
+ node scripts/check-shape-literals.mjs
41
+
39
42
  # The full test suite must be green before anything reaches a registry.
40
43
  npm test
41
44
 
package/server.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/justjlee/omnarai-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.6.1",
9
+ "version": "1.7.0",
10
10
  "remotes": [
11
11
  {
12
12
  "type": "streamable-http",
@@ -17,7 +17,7 @@
17
17
  {
18
18
  "registryType": "npm",
19
19
  "identifier": "omnarai-mcp",
20
- "version": "1.6.1",
20
+ "version": "1.7.0",
21
21
  "transport": {
22
22
  "type": "stdio"
23
23
  }
@@ -0,0 +1,51 @@
1
+ // Regression guard for D5/D6 (live audit 2026-07-17): omnarai_info once hardcoded
2
+ // three rings — silently dropping Media/Oral (253 works, 45% of the corpus) — and a
3
+ // contributor line missing GPT-4o + Meta AI, both of which author Atlas records.
4
+ // These assert the shape lines are DERIVED and COMPLETE, offline, so a reintroduced
5
+ // literal fails `npm test` (the publish.sh gate) before it can ship.
6
+
7
+ import { test } from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import {
10
+ formatRingsLine,
11
+ formatContributorsLine,
12
+ CANONICAL_CONTRIBUTORS,
13
+ RING_LABELS,
14
+ } from "../lib/info-format.js";
15
+
16
+ test("formatRingsLine renders every ring the engine reports — no silent drop (D5)", () => {
17
+ const live = { core: 116, curated: 181, open: 17, media: 253 };
18
+ const line = formatRingsLine(live);
19
+ // All four rings, with counts, in canonical order.
20
+ assert.match(line, /Core Canon \(116\)/);
21
+ assert.match(line, /Curated Expansions \(181\)/);
22
+ assert.match(line, /Open Exploration \(17\)/);
23
+ assert.match(line, /Media \/ Oral \(253\)/, "Media/Oral ring must be present — this is the D5 regression");
24
+ // Exactly as many segments as rings supplied — nothing added, nothing dropped.
25
+ // Split on " · " (the "Media / Oral" label contains a slash, so " / " would over-split).
26
+ assert.equal(line.split(" · ").length, Object.keys(live).length);
27
+ });
28
+
29
+ test("formatRingsLine cannot be pinned to three rings", () => {
30
+ // A future ring added to the engine payload must appear without a code change.
31
+ const withNewRing = { core: 1, curated: 2, open: 3, media: 4, research: 5 };
32
+ const line = formatRingsLine(withNewRing);
33
+ // Every label we know about renders; an unknown key is simply ignored, not fatal.
34
+ for (const label of Object.values(RING_LABELS)) assert.ok(line.includes(label), `${label} missing`);
35
+ });
36
+
37
+ test("formatRingsLine offline fallback still names all four rings", () => {
38
+ const line = formatRingsLine(null);
39
+ assert.ok(line.includes("Media / Oral"), "offline fallback must still include Media/Oral");
40
+ assert.equal(Object.values(RING_LABELS).every((l) => line.includes(l)), true);
41
+ });
42
+
43
+ test("contributor set includes GPT-4o and Meta AI (D6)", () => {
44
+ assert.ok(CANONICAL_CONTRIBUTORS.includes("GPT-4o"), "GPT-4o authors Atlas records — must be listed");
45
+ assert.ok(CANONICAL_CONTRIBUTORS.includes("Meta AI"), "Meta AI authors Atlas records — must be listed");
46
+ // Eight synthetic intelligences + the human curator = nine, as the homepage presents.
47
+ assert.equal(CANONICAL_CONTRIBUTORS.length, 9);
48
+ const line = formatContributorsLine();
49
+ assert.match(line, /GPT-4o/);
50
+ assert.match(line, /Meta AI/);
51
+ });