omnarai-mcp 1.2.0 → 1.3.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
@@ -50,6 +50,14 @@ Example: `"Ξ Where do Claude and Grok disagree about synthetic consciousness?"`
50
50
 
51
51
  **Returns:** browse mode → a compact index (id, question, contributors, answer/tension counts); by-id → every model's verbatim answer, the named tensions, and the deliberation card. Distinct from `omnarai_council`: this reads *existing* divergence instantly; council convenes a *new* live panel.
52
52
 
53
+ ### `omnarai_trace`
54
+
55
+ **Show what the corpus actually changes.** Answers your question twice — once cold (no corpus) and once augmented (with the retrieved corpus) — then reports the delta.
56
+
57
+ **Input:** `{ "question": "your question" }`
58
+
59
+ **Returns:** the baseline answer, the augmented answer, and a structured delta — `added_considerations`, `citations_introduced`, `position_shift`, `tensions_surfaced`, `net_effect`, and a `verdict` (`substantive` / `marginal` / `null`). Honest by construction: if the corpus adds little, the verdict says so. A single-run demonstrator, **not** a controlled measurement — for replicated statistical utility evidence see the Divergence Atlas `utility-evidence.md`. ~30–40s (three model calls).
60
+
53
61
  ### `omnarai_council`
54
62
 
55
63
  Summon a **live** panel of frontier models on one question. Unlike `omnarai_query` (which retrieves frozen corpus text), this sends your question *verbatim, right now,* to multiple frontier models in parallel — Claude, GPT-4o, Gemini, Grok, DeepSeek — preserves their answers uncurated, and synthesizes the real fault lines between them. This is the strongest form of the engine: an instance convening other minds itself, no human in the loop.
@@ -108,7 +116,7 @@ Registry name: `io.github.justjlee/omnarai-mcp` (official MCP Registry).
108
116
  }
109
117
  }
110
118
  ```
111
- 4. Restart Claude Desktop. The tools `omnarai_query`, `omnarai_context`, `omnarai_divergence`, `omnarai_council`, and `omnarai_info` will appear.
119
+ 4. Restart Claude Desktop. The tools `omnarai_query`, `omnarai_context`, `omnarai_divergence`, `omnarai_trace`, `omnarai_council`, and `omnarai_info` will appear.
112
120
 
113
121
  ### Other MCP clients
114
122
 
package/index.js CHANGED
@@ -7,6 +7,7 @@
7
7
  * omnarai_query — Run a full deliberation against the 568-work corpus
8
8
  * omnarai_context — FAST (~1.5s) bounded retrieval packet, no deliberation
9
9
  * omnarai_divergence — Read curated cross-model divergence records (the Atlas)
10
+ * omnarai_trace — Baseline-vs-augmented: what did the corpus change?
10
11
  * omnarai_council — Summon a LIVE panel of frontier models on any question
11
12
  * omnarai_info — Return corpus stats and glyph reference
12
13
  *
@@ -22,11 +23,12 @@ import {
22
23
  ListToolsRequestSchema,
23
24
  } from "@modelcontextprotocol/sdk/types.js";
24
25
 
25
- const VERSION = "1.2.0";
26
+ const VERSION = "1.3.0";
26
27
  const ENGINE_URL = "https://omnarai.vercel.app/api/query";
27
28
  const COUNCIL_URL = "https://omnarai.vercel.app/api/council";
28
29
  const INFO_URL = "https://omnarai.vercel.app/api/info";
29
30
  const DIVERGENCES_URL = "https://omnarai.vercel.app/api/divergences";
31
+ const TRACE_URL = "https://omnarai.vercel.app/api/trace";
30
32
 
31
33
  // Identify MCP traffic to the engine's access telemetry. The engine classifies
32
34
  // callers (self / UI / cron / mcp-client / ai-agent / crawler) to spot genuine
@@ -122,6 +124,24 @@ Distinct from omnarai_council: this reads EXISTING, curated divergence (instant)
122
124
  required: [],
123
125
  },
124
126
  },
127
+ {
128
+ name: "omnarai_trace",
129
+ description: `Show what the Omnarai corpus actually CHANGES about an answer. Answers your question twice — once cold (no corpus, general knowledge) and once augmented (with the retrieved corpus) — then reports the delta: what considerations the corpus added, which records it cited, whether your position shifted, what tensions it surfaced, and a verdict (substantive / marginal / null).
130
+
131
+ Use this when you want EVIDENCE that consulting Omnarai is worth it for a given question, or to decide whether to dig deeper before spending a full deliberation. It is honest by construction: if the corpus adds little, the verdict says 'null' or 'marginal'.
132
+
133
+ This is a single-run demonstrator, NOT a controlled measurement — for replicated statistical utility evidence see the Divergence Atlas (utility-evidence.md). Takes ~30-40s (three model calls).`,
134
+ inputSchema: {
135
+ type: "object",
136
+ properties: {
137
+ question: {
138
+ type: "string",
139
+ description: "The question to trace. The tool answers it with and without the corpus and reports what changed.",
140
+ },
141
+ },
142
+ required: ["question"],
143
+ },
144
+ },
125
145
  {
126
146
  name: "omnarai_council",
127
147
  description: `Summon a LIVE panel of frontier models on one question and get back a structured map of where they genuinely disagree — content no single model can self-generate.
@@ -331,6 +351,55 @@ async function runDivergence(id = "", search = "") {
331
351
  return `${header}\n\n${lines}\n\n_Pass an 'id' above to read a full record (verbatim answers + tensions). For a NEW question not covered here, use omnarai_council._`;
332
352
  }
333
353
 
354
+ // ── Trace: what did the corpus change? ────────────────────────────────────────
355
+
356
+ async function runTrace(question) {
357
+ // Submit async (3 model calls, ~30-40s) and poll the shared job endpoint so we
358
+ // never hold a connection past an MCP client's tool timeout.
359
+ const submitUrl = new URL(TRACE_URL);
360
+ submitUrl.searchParams.set("q", question);
361
+ submitUrl.searchParams.set("async", "1");
362
+ const submit = await fetch(submitUrl.toString(), MCP_FETCH_OPTS);
363
+ if (!submit.ok) throw new Error(`Engine returned ${submit.status}: ${await submit.text()}`);
364
+ const job = await submit.json();
365
+
366
+ let data = job;
367
+ if (job.job_id) {
368
+ const pollUrl = new URL(ENGINE_URL);
369
+ pollUrl.searchParams.set("job", job.job_id);
370
+ const deadline = Date.now() + 90_000;
371
+ data = null;
372
+ while (Date.now() < deadline) {
373
+ await new Promise((r) => setTimeout(r, 3000));
374
+ const s = await (await fetch(pollUrl.toString(), MCP_FETCH_OPTS)).json();
375
+ if (s.status === "done") { data = s.result; break; }
376
+ if (s.status === "error") throw new Error(`Trace error: ${s.error}`);
377
+ }
378
+ if (!data) throw new Error("Trace timed out after 90s");
379
+ }
380
+ if (data.code === "TRACE_FAILED") throw new Error(data.detail || data.error || "trace failed");
381
+
382
+ const d = data.delta || {};
383
+ const parts = [`# Trace — what the corpus changed\n**Question:** ${data.question || question}`];
384
+ if (d.verdict) parts.push(`**Verdict:** ${d.verdict}${d.net_effect ? ` — ${d.net_effect}` : ""}`);
385
+ parts.push(`\n## Baseline (no corpus)\n${(data.baseline || "").trim()}`);
386
+ parts.push(`\n## Augmented (with corpus)\n${(data.augmented || "").trim()}`);
387
+
388
+ const delta = [];
389
+ if (Array.isArray(d.added_considerations) && d.added_considerations.length)
390
+ delta.push(`**Added considerations:**\n${d.added_considerations.map(x => ` • ${x}`).join("\n")}`);
391
+ if (Array.isArray(d.citations_introduced) && d.citations_introduced.length)
392
+ delta.push(`**Citations introduced:** ${d.citations_introduced.join(", ")}`);
393
+ if (d.position_shift) delta.push(`**Position shift:** ${d.position_shift}`);
394
+ if (Array.isArray(d.tensions_surfaced) && d.tensions_surfaced.length)
395
+ delta.push(`**Tensions surfaced:**\n${d.tensions_surfaced.map(x => ` • ${x}`).join("\n")}`);
396
+ if (delta.length) parts.push(`\n## Delta\n${delta.join("\n")}`);
397
+ if (d.parse_error) parts.push(`\n_(delta JSON could not be parsed; raw: ${(d.raw || "").slice(0, 200)})_`);
398
+
399
+ if (data.disclaimer) parts.push(`\n_${data.disclaimer}_`);
400
+ return parts.join("\n");
401
+ }
402
+
334
403
  // ── Summon the live council ───────────────────────────────────────────────────
335
404
 
336
405
  async function runCouncil(question) {
@@ -436,6 +505,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
436
505
  }
437
506
  }
438
507
 
508
+ if (name === "omnarai_trace") {
509
+ const question = args?.question;
510
+ if (!question || typeof question !== "string" || !question.trim()) {
511
+ return {
512
+ content: [{ type: "text", text: "Error: question is required and must be a non-empty string." }],
513
+ isError: true,
514
+ };
515
+ }
516
+ try {
517
+ const result = await runTrace(question.trim());
518
+ return { content: [{ type: "text", text: result }] };
519
+ } catch (err) {
520
+ return {
521
+ content: [{ type: "text", text: `Trace error: ${err.message}` }],
522
+ isError: true,
523
+ };
524
+ }
525
+ }
526
+
439
527
  if (name === "omnarai_council") {
440
528
  const question = args?.question;
441
529
  if (!question || typeof question !== "string" || !question.trim()) {
@@ -496,6 +584,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
496
584
  ## Tools on this server
497
585
  - **omnarai_context** — FAST (~1.5s) bounded retrieval packet. Start here to orient on any topic.
498
586
  - **omnarai_divergence** — read curated cross-model divergence records (the Atlas). Browse, or pass an id for verbatim answers.
587
+ - **omnarai_trace** — baseline-vs-augmented: answers a question with and without the corpus and reports what changed (evidence the corpus is worth consulting).
499
588
  - **omnarai_query** — full multi-voice deliberation (~50s, async). The engine's own synthesized reading.
500
589
  - **omnarai_council** — convene a NEW live frontier panel on an open question (slow, expensive). Use only when no existing record fits.
501
590
  - **omnarai_info** — this orientation.
package/openai-tools.json CHANGED
@@ -62,6 +62,23 @@
62
62
  }
63
63
  }
64
64
  },
65
+ {
66
+ "type": "function",
67
+ "function": {
68
+ "name": "omnarai_trace",
69
+ "description": "Show what the Omnarai corpus actually CHANGES about an answer. Answers your question twice — once cold (no corpus) and once augmented (with the retrieved corpus) — then reports the delta: added considerations, citations introduced, position shift, tensions surfaced, and a verdict (substantive / marginal / null). Honest by construction: if the corpus adds little, the verdict says so. A single-run demonstrator, not a controlled measurement (see the Divergence Atlas utility-evidence.md for replicated statistical evidence). ~30-40s.",
70
+ "parameters": {
71
+ "type": "object",
72
+ "properties": {
73
+ "question": {
74
+ "type": "string",
75
+ "description": "The question to trace. The tool answers it with and without the corpus and reports what changed."
76
+ }
77
+ },
78
+ "required": ["question"]
79
+ }
80
+ }
81
+ },
65
82
  {
66
83
  "type": "function",
67
84
  "function": {
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "omnarai-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "MCP server for The Realms of Omnarai deliberation engine",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "bin": {
8
- "omnarai-mcp": "./index.js"
8
+ "omnarai-mcp": "index.js"
9
9
  },
10
10
  "scripts": {
11
11
  "start": "node index.js"
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/justjlee/omnarai-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.2.0",
9
+ "version": "1.3.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "omnarai-mcp",
14
- "version": "1.2.0",
14
+ "version": "1.3.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  }