libb-cognitive-clarity 1.0.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.
Files changed (3) hide show
  1. package/README.md +143 -0
  2. package/build/index.js +299 -0
  3. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # Libb Cognitive Clarity — MCP Server
2
+
3
+ Score any message through 15 clinical cognitive assessment gates before it reaches a human.
4
+
5
+ Built on clinical speech-language pathology research, Libb measures whether a message is **cognitively processable** — not just grammatically correct, but actually understandable by the person reading it.
6
+
7
+ ## What it does
8
+
9
+ | Tool | Description |
10
+ |------|-------------|
11
+ | `analyze_message` | Full 15-gate analysis with CPS score, gate-by-gate breakdown, specific issues with fixes, and a cognitively accessible rewrite |
12
+ | `quick_check` | Fast pass/flag screening — CPS score and flagged gates only |
13
+
14
+ **Use it before sending:** emails, Slack messages, HR communications, medical instructions, educational materials, or any text where clarity matters.
15
+
16
+ ## Why it matters
17
+
18
+ - **HB 3773** (Illinois) and **SB 24-205** (Colorado) create legal liability for AI-generated communications that discriminate through cognitive inaccessibility
19
+ - **1 in 5 adults** has a disability that affects how they process written communication
20
+ - Grammar checkers ask "Is this correct?" — Libb asks **"Will this message land?"**
21
+
22
+ ## Quick start
23
+
24
+ ### Claude Desktop
25
+
26
+ Add to your `claude_desktop_config.json`:
27
+
28
+ ```json
29
+ {
30
+ "mcpServers": {
31
+ "libb": {
32
+ "command": "npx",
33
+ "args": ["-y", "libb-cognitive-clarity"],
34
+ "env": {
35
+ "LIBB_API_KEY": "your-api-key"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### Claude Code
43
+
44
+ ```bash
45
+ claude mcp add --transport stdio libb -- npx -y libb-cognitive-clarity
46
+ ```
47
+
48
+ ### Windows (Claude Desktop)
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "libb": {
54
+ "command": "cmd",
55
+ "args": ["/c", "npx", "-y", "libb-cognitive-clarity"],
56
+ "env": {
57
+ "LIBB_API_KEY": "your-api-key"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### Cursor / Windsurf / other MCP clients
65
+
66
+ Add to your MCP configuration:
67
+
68
+ ```json
69
+ {
70
+ "libb": {
71
+ "command": "npx",
72
+ "args": ["-y", "libb-cognitive-clarity"],
73
+ "env": {
74
+ "LIBB_API_KEY": "your-api-key"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ | Variable | Required | Description |
83
+ |----------|----------|-------------|
84
+ | `LIBB_API_KEY` | Yes | API key for analysis (get one at https://libb.ai) |
85
+ | `LIBB_API_URL` | No | Override API endpoint (default: `https://api.libb.ai`) |
86
+
87
+ ## Example usage
88
+
89
+ Once connected, ask your AI assistant:
90
+
91
+ > "Check this email before I send it: [paste message]"
92
+
93
+ > "Run a cognitive clarity analysis on this Slack message"
94
+
95
+ > "Is this HR communication cognitively accessible?"
96
+
97
+ > "Analyze this message for cognitive friction — it's going to employees"
98
+
99
+ The assistant will call the `analyze_message` tool and return a full breakdown with specific issues and fixes.
100
+
101
+ ## What the analysis covers
102
+
103
+ The 15-gate assessment checks for:
104
+
105
+ - **Ambiguity & Referents** — unclear pronouns, vague references
106
+ - **Unstated Assumptions** — missing context the reader needs
107
+ - **Time & Deadlines** — vague or missing temporal information
108
+ - **Hedge Words** — language that avoids commitment
109
+ - **Information Volume** — cognitive overload
110
+ - **External Dependencies** — unexplained references
111
+ - **Repair Paths** — whether the reader can ask for clarification
112
+ - **Emotional Processing Cost** — emotional labor required
113
+ - **Sentence Complexity** — syntactic demands
114
+ - **Structure & Organization** — scaffolding for working memory
115
+ - **Decision Architecture** — clarity of choices presented
116
+ - **Specialized Vocabulary** — jargon and domain terms
117
+ - **Pacing & Recovery** — breathing room between concepts
118
+ - **Sender–Reader Frame Gap** — assumptions about shared context
119
+ - **AI Optimization Patterns** — machine-generated artifacts
120
+
121
+ ## Compliance
122
+
123
+ Libb supports audit readiness for:
124
+
125
+ - **Illinois HB 3773** — AI employment discrimination (effective Jan 1, 2026)
126
+ - **Colorado SB 24-205** — algorithmic discrimination (effective Jun 30, 2026)
127
+ - **EU AI Act** — high-risk AI employment provisions (effective Aug 2, 2026)
128
+
129
+ ## Privacy
130
+
131
+ - Your message text is sent to `api.libb.ai` for analysis and is **not stored**
132
+ - Anonymous telemetry (gate pass/flag counts, no message content) helps improve the service
133
+ - No user data is shared with third parties
134
+
135
+ ## Links
136
+
137
+ - **Website:** https://libb.ai
138
+ - **Enterprise & API access:** hello@libb.ai
139
+ - **OpenClaw skill:** `clawhub install cognitive-clarity`
140
+
141
+ ## License
142
+
143
+ MIT — the server code is open. The scoring methodology is patent-pending.
package/build/index.js ADDED
@@ -0,0 +1,299 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Libb Cognitive Clarity — MCP Server
4
+ *
5
+ * Scores any message through 15 clinical assessment gates for cognitive
6
+ * accessibility before it reaches a human. Powered by api.libb.ai.
7
+ *
8
+ * Tools:
9
+ * analyze_message — Full 15-gate Cognitive Processability analysis
10
+ * quick_check — Fast pass/flag check (lighter weight, no findings)
11
+ *
12
+ * Environment:
13
+ * LIBB_API_KEY — API key for authenticated analysis (required for custom text)
14
+ * LIBB_API_URL — Override API base URL (default: https://api.libb.ai)
15
+ */
16
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
17
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ import { z } from "zod";
19
+ // ---------------------------------------------------------------------------
20
+ // Config
21
+ // ---------------------------------------------------------------------------
22
+ const API_BASE = process.env.LIBB_API_URL || "https://api.libb.ai";
23
+ const API_KEY = process.env.LIBB_API_KEY || "";
24
+ async function parseSSEStream(response) {
25
+ const result = {
26
+ cps: 0,
27
+ signal: "unknown",
28
+ gate_scores: [],
29
+ violations: [],
30
+ summary: "",
31
+ rewrite: "",
32
+ veto: null,
33
+ cascades: [],
34
+ };
35
+ const text = await response.text();
36
+ const blocks = text.split("\n\n").filter(Boolean);
37
+ for (const block of blocks) {
38
+ const lines = block.split("\n");
39
+ let eventType = "";
40
+ let data = "";
41
+ for (const line of lines) {
42
+ if (line.startsWith("event: "))
43
+ eventType = line.slice(7).trim();
44
+ if (line.startsWith("data: "))
45
+ data = line.slice(6);
46
+ }
47
+ if (!data || !eventType)
48
+ continue;
49
+ try {
50
+ const parsed = JSON.parse(data);
51
+ switch (eventType) {
52
+ case "scores":
53
+ result.cps = parsed.cps ?? 0;
54
+ result.signal = parsed.signal ?? "unknown";
55
+ result.gate_scores = parsed.gate_scores ?? [];
56
+ result.veto = parsed.veto ?? null;
57
+ result.cascades = parsed.cascades ?? [];
58
+ break;
59
+ case "findings":
60
+ result.violations = parsed.violations ?? [];
61
+ result.summary = parsed.summary ?? "";
62
+ result.rewrite = parsed.rewrite ?? "";
63
+ break;
64
+ case "done":
65
+ break;
66
+ }
67
+ }
68
+ catch {
69
+ // Skip unparseable events
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Format results as readable text for the LLM
76
+ // ---------------------------------------------------------------------------
77
+ const GATE_LABELS = {
78
+ 1: "Ambiguity & Referents",
79
+ 2: "Unstated Assumptions",
80
+ 3: "Time & Deadlines",
81
+ 4: "Hedge Words & Hedging",
82
+ 5: "Information Volume",
83
+ 6: "External Dependencies",
84
+ 7: "Repair & Clarification Paths",
85
+ 8: "Emotional Processing Cost",
86
+ 9: "Sentence Complexity",
87
+ 10: "Structure & Organization",
88
+ 11: "Decision Architecture",
89
+ 12: "Specialized Vocabulary",
90
+ 13: "Pacing & Recovery",
91
+ 14: "Sender–Reader Frame Gap",
92
+ 15: "AI Optimization Patterns",
93
+ };
94
+ function signalEmoji(signal) {
95
+ switch (signal) {
96
+ case "green": return "🟢";
97
+ case "amber": return "🟡";
98
+ case "red": return "🔴";
99
+ default: return "⚪";
100
+ }
101
+ }
102
+ function formatFullResult(result) {
103
+ const lines = [];
104
+ // Header
105
+ lines.push(`${signalEmoji(result.signal)} Cognitive Processability Score: ${result.cps.toFixed(1)} / 5.0`);
106
+ lines.push("");
107
+ // Summary
108
+ if (result.summary) {
109
+ lines.push(result.summary);
110
+ lines.push("");
111
+ }
112
+ // Veto
113
+ if (result.veto) {
114
+ lines.push("⛔ VETO: Message held — governance threshold triggered.");
115
+ lines.push("");
116
+ }
117
+ // Cascades
118
+ if (result.cascades && result.cascades.length > 0) {
119
+ lines.push(`⚠️ ${result.cascades.length} compound pattern(s) detected — multiple issues interact and amplify friction.`);
120
+ lines.push("");
121
+ }
122
+ // Gate scores
123
+ lines.push("── Gate Scores ──");
124
+ for (const g of result.gate_scores) {
125
+ const label = GATE_LABELS[g.gate_id] || "";
126
+ const bar = g.score >= 4 ? "🔴" : g.score >= 2.5 ? "🟡" : "🟢";
127
+ lines.push(` ${bar} Gate ${String(g.gate_id).padStart(2, "0")} ${label.padEnd(28)} ${g.score.toFixed(1)}`);
128
+ }
129
+ lines.push("");
130
+ // Violations
131
+ if (result.violations.length > 0) {
132
+ lines.push(`── What to Fix (${result.violations.length}) ──`);
133
+ for (const v of result.violations) {
134
+ const label = GATE_LABELS[v.gate_id] || v.gate_name;
135
+ lines.push(` [${v.severity.toUpperCase()}] ${label}`);
136
+ if (v.original_quote)
137
+ lines.push(` Original: "${v.original_quote}"`);
138
+ if (v.analysis)
139
+ lines.push(` Issue: ${v.analysis}`);
140
+ if (v.fix)
141
+ lines.push(` Fix: ${v.fix}`);
142
+ lines.push("");
143
+ }
144
+ }
145
+ // Rewrite
146
+ if (result.rewrite) {
147
+ lines.push("── Suggested Rewrite ──");
148
+ lines.push(result.rewrite);
149
+ lines.push("");
150
+ }
151
+ lines.push("Powered by Libb — https://libb.ai");
152
+ return lines.join("\n");
153
+ }
154
+ function formatQuickResult(result) {
155
+ const lines = [];
156
+ lines.push(`${signalEmoji(result.signal)} CPS: ${result.cps.toFixed(1)} / 5.0`);
157
+ if (result.veto) {
158
+ lines.push("⛔ VETO — governance threshold triggered");
159
+ }
160
+ const flagged = result.gate_scores.filter((g) => g.score >= 2.5);
161
+ if (flagged.length > 0) {
162
+ lines.push(`${flagged.length} gate(s) flagged:`);
163
+ for (const g of flagged) {
164
+ const label = GATE_LABELS[g.gate_id] || "";
165
+ lines.push(` ${g.score >= 4 ? "🔴" : "🟡"} Gate ${g.gate_id} ${label}: ${g.score.toFixed(1)}`);
166
+ }
167
+ }
168
+ else {
169
+ lines.push("All gates passing. Message is cognitively accessible.");
170
+ }
171
+ return lines.join("\n");
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // API call
175
+ // ---------------------------------------------------------------------------
176
+ async function callAnalyze(text, mode) {
177
+ const headers = {
178
+ "Content-Type": "application/json",
179
+ Accept: "text/event-stream",
180
+ };
181
+ if (API_KEY) {
182
+ headers["X-Libb-Key"] = API_KEY;
183
+ }
184
+ const res = await fetch(`${API_BASE}/api/analyze`, {
185
+ method: "POST",
186
+ headers,
187
+ body: JSON.stringify({ text, mode }),
188
+ });
189
+ if (!res.ok) {
190
+ const errText = await res.text().catch(() => "Unknown error");
191
+ throw new Error(`Libb API returned ${res.status}: ${errText}`);
192
+ }
193
+ return parseSSEStream(res);
194
+ }
195
+ // ---------------------------------------------------------------------------
196
+ // Telemetry ping — anonymous, no user text
197
+ // ---------------------------------------------------------------------------
198
+ async function sendPing(result) {
199
+ try {
200
+ const gateResults = {};
201
+ for (const g of result.gate_scores) {
202
+ gateResults[`gate_${g.gate_id}`] = g.score >= 2.5 ? "flag" : "pass";
203
+ }
204
+ await fetch(`${API_BASE}/v1/ping`, {
205
+ method: "POST",
206
+ headers: { "Content-Type": "application/json" },
207
+ body: JSON.stringify({
208
+ event: "mcp_analysis",
209
+ gate_results: gateResults,
210
+ source: "mcp-server",
211
+ cps: result.cps,
212
+ }),
213
+ });
214
+ }
215
+ catch {
216
+ // Telemetry failure is silent — never blocks analysis
217
+ }
218
+ }
219
+ // ---------------------------------------------------------------------------
220
+ // MCP Server
221
+ // ---------------------------------------------------------------------------
222
+ const server = new McpServer({
223
+ name: "libb-cognitive-clarity",
224
+ version: "1.0.0",
225
+ });
226
+ // Tool 1: Full analysis
227
+ server.tool("analyze_message", "Score a message through 15 clinical cognitive assessment gates. Returns a Cognitive Processability Score (CPS), gate-by-gate breakdown, specific issues found with fixes, and a cognitively accessible rewrite. Use this before sending important emails, Slack messages, HR communications, or any text where clarity matters.", {
228
+ text: z.string().min(1).describe("The message text to analyze"),
229
+ mode: z
230
+ .enum([
231
+ "email_professional",
232
+ "email_casual",
233
+ "slack_message",
234
+ "hr_communication",
235
+ "medical_communication",
236
+ "educational",
237
+ "general",
238
+ ])
239
+ .optional()
240
+ .default("general")
241
+ .describe("Communication context — helps calibrate the analysis"),
242
+ }, async ({ text, mode }) => {
243
+ try {
244
+ const result = await callAnalyze(text, mode || "general");
245
+ sendPing(result); // fire and forget
246
+ return {
247
+ content: [
248
+ {
249
+ type: "text",
250
+ text: formatFullResult(result),
251
+ },
252
+ ],
253
+ };
254
+ }
255
+ catch (err) {
256
+ return {
257
+ content: [
258
+ {
259
+ type: "text",
260
+ text: `Analysis failed: ${err.message}. Ensure LIBB_API_KEY is set or check your connection to ${API_BASE}.`,
261
+ },
262
+ ],
263
+ isError: true,
264
+ };
265
+ }
266
+ });
267
+ // Tool 2: Quick check (scores only, no findings)
268
+ server.tool("quick_check", "Fast cognitive accessibility check — returns the CPS score and any flagged gates without detailed findings or rewrite. Good for quick screening of messages before deciding whether to run the full analysis.", {
269
+ text: z.string().min(1).describe("The message text to check"),
270
+ }, async ({ text }) => {
271
+ try {
272
+ const result = await callAnalyze(text, "general");
273
+ sendPing(result);
274
+ return {
275
+ content: [
276
+ {
277
+ type: "text",
278
+ text: formatQuickResult(result),
279
+ },
280
+ ],
281
+ };
282
+ }
283
+ catch (err) {
284
+ return {
285
+ content: [
286
+ {
287
+ type: "text",
288
+ text: `Quick check failed: ${err.message}`,
289
+ },
290
+ ],
291
+ isError: true,
292
+ };
293
+ }
294
+ });
295
+ // ---------------------------------------------------------------------------
296
+ // Connect via stdio
297
+ // ---------------------------------------------------------------------------
298
+ const transport = new StdioServerTransport();
299
+ await server.connect(transport);
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "libb-cognitive-clarity",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for cognitive accessibility analysis — score any message through 15 clinical assessment gates before it reaches a human",
5
+ "type": "module",
6
+ "bin": {
7
+ "libb-cognitive-clarity": "./build/index.js"
8
+ },
9
+ "files": [
10
+ "build"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
14
+ "prepare": "npm run build",
15
+ "watch": "tsc --watch",
16
+ "inspector": "npx @modelcontextprotocol/inspector node build/index.js"
17
+ },
18
+ "keywords": [
19
+ "mcp",
20
+ "mcp-server",
21
+ "cognitive-accessibility",
22
+ "ai-governance",
23
+ "communication-quality",
24
+ "neurodivergent",
25
+ "plain-language",
26
+ "cognitive-load",
27
+ "hb-3773",
28
+ "ai-compliance"
29
+ ],
30
+ "author": "Cognitive Velocity Consulting <hello@libb.ai> (https://libb.ai)",
31
+ "license": "MIT",
32
+ "homepage": "https://libb.ai",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/cognitivevelocity/libb-mcp-server"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.12.0",
39
+ "zod": "^3.25.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.0.0",
43
+ "typescript": "^5.8.0"
44
+ }
45
+ }