prism-mcp-server 9.0.5 → 9.1.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
@@ -20,6 +20,8 @@ npx -y prism-mcp-server
20
20
 
21
21
  Works with **Claude Desktop · Claude Code · Cursor · Windsurf · Cline · Gemini · Antigravity** — **any MCP client.**
22
22
 
23
+ https://github.com/dcostenco/prism-mcp/raw/main/docs/prism_mcp_demo.mp4
24
+
23
25
  ## 📖 Table of Contents
24
26
 
25
27
  - [Why Prism?](#why-prism)
@@ -437,13 +439,13 @@ A gorgeous glassmorphism UI at `localhost:3000` that lets you see exactly what y
437
439
 
438
440
 
439
441
  ### 🧬 10× Memory Compression
440
- Powered by a pure TypeScript port of Google's TurboQuant (inspired by Google's ICLR research), Prism compresses 768-dim embeddings from **3,072 bytes → ~400 bytes** — enabling decades of session history on a standard laptop. No native modules. No vector database required.
442
+ Powered by a pure TypeScript port of Google's TurboQuant (inspired by Google's ICLR research), Prism compresses 768-dim embeddings from **3,072 bytes → ~400 bytes** — enabling decades of session history on a standard laptop. No native modules. No vector database required. To mitigate quantization degradation (where repeated compress/decompress cycles could smear subtle corrections after 10k+ memories), Prism leverages autonomous **ledger compaction** and **Deep Storage cleanup** to guarantee high-fidelity memory integrity over time.
441
443
 
442
- ### 🐝 Multi-Agent Hivemind
443
- Multiple agents (dev, QA, PM) can work on the same project with **role-isolated memory**. Agents discover each other automatically, share context in real-time via Telepathy sync, and see a team roster during context loading. → [Multi-agent setup example](examples/multi-agent-hivemind/)
444
+ ### 🐝 Multi-Agent Hivemind & Enterprise Sync
445
+ While local SQLite is amazing for solo developers, enterprise teams cannot share a local SQLite file. Prism breaks the "local-only" ceiling via **Supabase Sync** and the **Multi-Agent Hivemind**—scaling effortlessly to teams of 50+ developers using agents. Multiple agents (dev, QA, PM) can work on the same project with **role-isolated memory**, discover each other automatically, and share context in real-time via Telepathy sync to a shared Postgres backend. → [Multi-agent setup example](examples/multi-agent-hivemind/)
444
446
 
445
447
  ### 🚦 Task Router
446
- Prism can score coding tasks and recommend whether to keep execution on the host model or delegate to a **local Claw agent** (a lightweight sub-agent powered by Ollama/vLLM for fast, local-safe edits). This enables faster handling of small edits while preserving host execution for complex work. In client startup/skill flows, use defensive delegation: route only coding tasks, call `session_task_route` only when available, delegate to `claw` only when executor tooling exists and task is non-destructive, and fallback to host when router/executor is unavailable. → [Task router real-life example](examples/router_real_life_test.ts)
448
+ Prism scores coding tasks across **6 weighted heuristic signals** (keyword analysis, file count, file-type complexity, scope, length, multi-step detection) and recommends whether to keep execution on the host cloud model or delegate to a **local Claw agent** (powered by deepseek-r1 / qwen2.5-coder via Ollama). File-type awareness routes config/docs edits locally while reserving systems-programming tasks for the host. The local agent features buffered streaming (handles split `<think>` tags), stateful multi-turn conversations, and automatic memory trimming. In client startup/skill flows, use defensive delegation: route only coding tasks, call `session_task_route` only when available, delegate to `claw` only when executor tooling exists and task is non-destructive, and fallback to host when router/executor is unavailable. → [Task router real-life example](examples/router_real_life_test.ts)
447
449
 
448
450
  ### 🖼️ Visual Memory
449
451
  Save UI screenshots, architecture diagrams, and bug states to a searchable vault. Images are auto-captioned by a VLM (Claude Vision / GPT-4V / Gemini) and become semantically searchable across sessions.
@@ -725,13 +727,13 @@ The Generator strips the `console.log`, resubmits, and the next `EVALUATE` retur
725
727
 
726
728
  ## 🆕 What's New
727
729
 
728
- > **Current release: v7.8.2Cognitive Architecture**
730
+ > **Current release: v9.1.0Task Router v2 & Local Agent Hardening**
729
731
 
730
- - 🧠 **v7.8.0 — Cognitive Architecture:** The biggest leap forward yet. Moved beyond flat vector search into a true cognitive architecture inspired by human brain mechanics. Episodic-to-Semantic memory consolidation (Hebbian learning), ACT-R Spreading Activation with multi-hop causal reasoning, Uncertainty-Aware Rejection Gate (your agent can say "I don't know"), and Dynamic Fast Weight Decay (semantic memories outlive episodic chatter by 2×). **Your agents don't just remember; they learn.** → [Cognitive Architecture](#-cognitive-architecture-v78)
731
- - 🌐 **v7.7.0Cloud-Native SSE Transport:** Full unauthenticated and authenticated Server-Sent Events MCP support for seamless network deployments.
732
- - 🩺 **v7.5.0 — Intent Health Dashboard + Security Hardening:** Real-time 0–100 project health scoring (staleness × TODO load × decisions). 10 XSS injection vectors patched. Algorithm hardened with NaN guards and score ceiling.
733
- - ⚔️ **v7.4.0 — Adversarial Evaluation:** Split-brain anti-sycophancy pipeline. Generator and evaluator in isolated roles with evidence-bound findings.
734
- - 🏭 **v7.3.xDark Factory + Stability:** Fail-closed 3-gate execution pipeline. Dashboard stability and verification diagnostics.
732
+ - 🚦 **v9.1.0 — Task Router v2:** File-type complexity signal for intelligent code-vs-config routing, 6-signal weighted heuristic engine, multi-step false-positive fix, expanded file extension classification. Local agent hardened with buffered streaming, system prompts, memory trimming, and stateful `/api/chat` API.
733
+ - 🔒 **v9.0.5JWKS Auth Security Hardening:** JWT audience/issuer claim validation (`PRISM_JWT_AUDIENCE`, `PRISM_JWT_ISSUER`), structured error logging for JWT failures, typed `PrismAuthenticatedRequest` interface, 11 new JWKS unit tests, Smithery server card fix. Vendor-neutral — tested with Auth0, AgentLair ([llms.txt](https://agentlair.com/llms.txt)), Keycloak, and custom JWKS endpoints.
734
+ - 🧠 **v9.0.0 — Autonomous Cognitive OS:** Token-Economic Reinforcement Learning (Surprisal Gate + Cognitive Budget), Affect-Tagged Memory (valence-scored retrieval), and Episodic→Semantic Consolidation. Your agents learn compression and develop intuition. [Cognitive OS](#-autonomous-cognitive-os-v90)
735
+ - 🧠 **v7.8.0 — Cognitive Architecture:** Episodic-to-Semantic memory consolidation (Hebbian learning), ACT-R Spreading Activation with multi-hop causal reasoning, Uncertainty-Aware Rejection Gate, and Dynamic Fast Weight Decay. → [Cognitive Architecture](#-cognitive-architecture-v78)
736
+ - 🌐 **v7.7.0Cloud-Native SSE Transport:** Full Server-Sent Events MCP support for seamless network deployments.
735
737
 
736
738
  👉 **[Full release history → CHANGELOG.md](CHANGELOG.md)** · **[ROADMAP →](ROADMAP.md)**
737
739
 
@@ -971,6 +973,9 @@ Requires `PRISM_DARK_FACTORY_ENABLED=true`.
971
973
  | `PRISM_ACTR_WEIGHT_ACTIVATION` | No | Composite score ACT-R activation weight (default: `0.3`) |
972
974
  | `PRISM_ACTR_ACCESS_LOG_RETENTION_DAYS` | No | Days before access logs are pruned by background scheduler (default: `90`) |
973
975
  | `PRISM_DARK_FACTORY_ENABLED` | No | `"true"` to enable Dark Factory autonomous pipeline tools (`session_start_pipeline`, `session_check_pipeline_status`, `session_abort_pipeline`) |
976
+ | `PRISM_JWKS_URI` | No | JWKS endpoint URL for vendor-neutral JWT auth (e.g., `https://your-tenant.auth0.com/.well-known/jwks.json`) |
977
+ | `PRISM_JWT_AUDIENCE` | No | Expected JWT `aud` claim — prevents cross-service token confusion |
978
+ | `PRISM_JWT_ISSUER` | No | Expected JWT `iss` claim — validates token origin |
974
979
 
975
980
  </details>
976
981
 
@@ -1097,12 +1102,39 @@ Prism has evolved from smart session logging into a **cognitive memory architect
1097
1102
 
1098
1103
  ---
1099
1104
 
1105
+ ## 💼 B2B Consulting & Enterprise Support
1106
+
1107
+ Prism MCP is open-source and free for individual developers. For teams and enterprises building autonomous AI workflows or integrating MCP-native memory at scale, we offer professional consulting and setup packages.
1108
+
1109
+ ### 🥉 Team Pilot Package
1110
+ *Perfect for engineering teams adopting MCP tools and collaborative agents.*
1111
+ * **What's included:** Full team rollout, managed Supabase configuration (for multi-device sync), Universal Import of legacy chat history, and dedicated setup support.
1112
+ * **Model:** Fixed-price engagement.
1113
+
1114
+ ### 🥈 Cognitive Architecture Tuning
1115
+ *For teams building advanced AI agents or autonomous pipelines.*
1116
+ * **What's included:** "Dark Factory" pipeline implementation tailored to your workflows, adversarial evaluator tuning, custom HDC cognitive route configuration, and local open-weight model integration (BYOM).
1117
+ * **Model:** Retainer or project-based.
1118
+
1119
+ ### 🥇 Enterprise Integration
1120
+ *Full-scale deployment for high-compliance environments.*
1121
+ * **What's included:** Active Directory / custom JWKS auth integration, Air-gapped on-premise deployment, custom OTel Grafana dashboards for cognitive observability, and custom skills/tools development.
1122
+ * **Model:** Custom enterprise quote.
1123
+
1124
+ **Interested in accelerating your team's autonomous workflows?**
1125
+ [📧 Contact us for a consultation](mailto:inquiries@prism-mcp.com) — let's build your organization's cognitive memory engine.
1126
+
1127
+ ---
1128
+
1100
1129
  ## 📦 Milestones & Roadmap
1101
1130
 
1102
- > **Current: v7.8.2** — Cognitive Architecture ([CHANGELOG](CHANGELOG.md))
1131
+ > **Current: v9.1.0** — Task Router v2 & Local Agent Hardening ([CHANGELOG](CHANGELOG.md))
1103
1132
 
1104
1133
  | Release | Headline |
1105
1134
  |---------|----------|
1135
+ | **v9.1.0** | 🚦 Task Router v2 — file-type routing signal, 6-signal heuristics, local agent streaming buffer |
1136
+ | **v9.0.5** | 🔒 JWKS Auth Security Hardening — audience/issuer validation, JWT failure logging, typed agent identity |
1137
+ | **v9.0** | 🧠 Autonomous Cognitive OS — Surprisal Gate, Cognitive Budget, Affect-Tagged Memory |
1106
1138
  | **v7.8** | 🧠 Cognitive Architecture — Hebbian consolidation, multi-hop reasoning, rejection gate, dynamic decay |
1107
1139
  | **v7.7** | 🌐 Cloud-Native SSE Transport |
1108
1140
  | **v7.5** | 🩺 Intent Health Dashboard + Security Hardening |
@@ -1145,7 +1177,7 @@ A: Run `npm run build && npm test`, then open the Mind Palace dashboard (`localh
1145
1177
  - **MCP client race conditions.** Some MCP clients may not finish tool enumeration before the model generates its first response, causing transient `unknown_tool` errors. This is a client-side timing issue — Prism's server completes the MCP handshake in ~60ms. Workaround: the server-side auto-push fallback and the startup skill's retry logic.
1146
1178
  - **No real-time sync without Supabase.** Local SQLite mode is single-machine only. Multi-device or team sync requires a Supabase backend.
1147
1179
  - **Embedding quality varies by provider.** Gemini `text-embedding-004` and OpenAI `text-embedding-3-small` produce high-quality 768-dim vectors. Prism passes `dimensions: 768` via the Matryoshka API for OpenAI models (native output is 1536-dim; this truncation is lossless and outperforms ada-002 at full 1536 dims). Ollama embeddings (e.g., `nomic-embed-text`) are usable but may reduce retrieval accuracy.
1148
- - **Dashboard is HTTP-only.** The Mind Palace dashboard at `localhost:3000` does not support HTTPS. For remote access, use a reverse proxy (nginx/Caddy) or SSH tunnel. Basic auth is available via `PRISM_DASHBOARD_USER` / `PRISM_DASHBOARD_PASS`.
1180
+ - **Dashboard is HTTP-only.** The Mind Palace dashboard at `localhost:3000` does not support HTTPS. For remote access, use a reverse proxy (nginx/Caddy) or SSH tunnel. Basic auth is available via `PRISM_DASHBOARD_USER` / `PRISM_DASHBOARD_PASS`. JWKS JWT auth is available via `PRISM_JWKS_URI` for agent-native authentication (works with Auth0, AgentLair ([llms.txt](https://agentlair.com/llms.txt)), Keycloak, Cognito, or any standard JWKS endpoint).
1149
1181
  - **Long-lived clients can accumulate zombie processes.** MCP clients that run for extended periods (e.g., Claude CLI) may leave orphaned Prism server processes. The lifecycle manager detects true orphans (PPID=1) but allows coexistence for active parent processes. Use `PRISM_INSTANCE` to isolate instances across clients.
1150
1182
  - **Migration is one-way.** Universal Import ingests sessions *into* Prism but does not export back to Claude/Gemini/OpenAI formats. Use `session_export_memory` for portable JSON/Markdown export, or the `vault` format for Obsidian/Logseq-compatible `.zip` archives.
1151
1183
  - **Export ceiling at 10,000 ledger entries.** The `session_export_memory` tool and the dashboard export button cap vault/JSON exports at 10,000 entries per project as an OOM guard. Projects exceeding this limit should use per-project exports and time-based filtering to stay within the ceiling. This limit does not affect search or context loading.
package/dist/cli.js CHANGED
File without changes
@@ -41,24 +41,39 @@ let jwksCache = null;
41
41
  export function initJWKS(uri) {
42
42
  try {
43
43
  jwksCache = createRemoteJWKSet(new URL(uri));
44
+ console.error(`[Auth] 🔑 JWKS remote key set initialized: ${uri}`);
44
45
  }
45
46
  catch (err) {
46
- console.error(`Failed to initialize JWKS from ${uri}:`, err);
47
+ console.error(`[Auth] ❌ Failed to initialize JWKS from ${uri}:`, err);
47
48
  }
48
49
  }
50
+ /**
51
+ * Reset JWKS cache — for testing only.
52
+ * @internal
53
+ */
54
+ export function _resetJWKS(cache = null) {
55
+ jwksCache = cache;
56
+ }
57
+ /** Expose JWKS cache state for testing. @internal */
58
+ export function _getJWKSCache() {
59
+ return jwksCache;
60
+ }
49
61
  // ─────────────────────────────────────────────────────────────────
50
62
  // AUTHENTICATION CHECK
51
63
  // ─────────────────────────────────────────────────────────────────
52
64
  /**
53
65
  * Check if a request is authenticated against the provided config.
54
66
  *
55
- * Returns true if:
56
- * 1. Auth is disabled (authEnabled === false) → pass-through
57
- * 2. Request has a valid, non-expired session cookie
58
- * 3. Request has valid Basic Auth credentials
67
+ * Authentication is checked in priority order:
68
+ * 1. Auth disabled (authEnabled === false) → pass-through
69
+ * 2. Bearer JWT token verified against JWKS remote key set
70
+ * 3. Valid, non-expired session cookie
71
+ * 4. Valid Basic Auth credentials
59
72
  *
60
- * Side effect: expired session tokens are lazily cleaned up when
61
- * encountered, preventing unbounded memory growth.
73
+ * Side effects:
74
+ * - Expired session tokens are lazily cleaned up when encountered
75
+ * - On successful JWT verification, `req.agent_id` is set for
76
+ * downstream traceability (audit logging, access control)
62
77
  */
63
78
  export async function isAuthenticated(req, config) {
64
79
  if (!config.authEnabled)
@@ -68,14 +83,26 @@ export async function isAuthenticated(req, config) {
68
83
  if (authHeader.startsWith("Bearer ") && jwksCache) {
69
84
  try {
70
85
  const token = authHeader.slice(7);
71
- const { payload } = await jwtVerify(token, jwksCache);
72
- // Attach agent_id to the request for traceability if needed downstream
73
- req.agent_id = payload.agent_id || payload.sub;
86
+ const verifyOpts = {
87
+ clockTolerance: 30, // 30s clock skew tolerance
88
+ };
89
+ if (config.jwtAudience)
90
+ verifyOpts.audience = config.jwtAudience;
91
+ if (config.jwtIssuer)
92
+ verifyOpts.issuer = config.jwtIssuer;
93
+ const { payload } = await jwtVerify(token, jwksCache, verifyOpts);
94
+ const payloadDict = payload;
95
+ // Attach agent_id and AgentLair audit metadata to the request for downstream traceability
96
+ const authReq = req;
97
+ authReq.agent_id =
98
+ payloadDict.agent_id || payload.sub;
99
+ authReq.al_name = payloadDict.al_name;
100
+ authReq.al_audit_url = payloadDict.al_audit_url;
74
101
  return true;
75
102
  }
76
103
  catch (err) {
77
- // Verification failed let it fall through or return false
78
- // console.error("JWT verification failed:", err);
104
+ const code = err.code || "UNKNOWN";
105
+ console.error(`[Auth] JWT verification failed (${code}):`, err.message);
79
106
  return false;
80
107
  }
81
108
  }
@@ -90,6 +90,8 @@ export async function startDashboardServer() {
90
90
  authUser: AUTH_USER,
91
91
  authPass: AUTH_PASS,
92
92
  activeSessions,
93
+ jwtAudience: process.env.PRISM_JWT_AUDIENCE || undefined,
94
+ jwtIssuer: process.env.PRISM_JWT_ISSUER || undefined,
93
95
  };
94
96
  // v6.5.1: Rate limiter for login endpoint — 5 attempts per 60 seconds per IP
95
97
  const loginRateLimiter = createRateLimiter({
@@ -141,7 +143,18 @@ return false;}
141
143
  </script></body></html>`;
142
144
  }
143
145
  if (AUTH_ENABLED) {
144
- console.error(`[Dashboard] 🔒 Auth enabled for user "${AUTH_USER}"`);
146
+ if (AUTH_USER) {
147
+ console.error(`[Dashboard] 🔒 Basic auth enabled for user "${AUTH_USER}"`);
148
+ }
149
+ if (AUTH_JWKS_URI) {
150
+ console.error(`[Dashboard] 🔑 JWKS auth enabled: ${AUTH_JWKS_URI}`);
151
+ if (process.env.PRISM_JWT_AUDIENCE) {
152
+ console.error(`[Dashboard] Audience: ${process.env.PRISM_JWT_AUDIENCE}`);
153
+ }
154
+ else {
155
+ console.error(`[Dashboard] ⚠️ No PRISM_JWT_AUDIENCE set — any valid JWT from this JWKS will be accepted.`);
156
+ }
157
+ }
145
158
  // Security advisory: HTTP Basic Auth transmits credentials in cleartext.
146
159
  // When auth is enabled for remote access, HTTPS (reverse proxy) is strongly recommended.
147
160
  console.error(`[Dashboard] ⚠️ WARNING: Dashboard uses HTTP (not HTTPS). ` +
@@ -228,7 +241,7 @@ return false;}
228
241
  version: SERVER_CONFIG.version,
229
242
  },
230
243
  authentication: {
231
- required: false
244
+ required: AUTH_ENABLED
232
245
  },
233
246
  configSchema: {
234
247
  type: "object",
@@ -318,6 +331,17 @@ return false;}
318
331
  res.writeHead(401, { "Content-Type": "text/html; charset=utf-8" });
319
332
  return res.end(renderLoginPage());
320
333
  }
334
+ // ─── AUDIT LOGGING (JWKS / AgentLair) ───
335
+ const authReq = req;
336
+ // Log successful agent access (identified via JWKS JWT)
337
+ if (authReq.agent_id && reqUrl.pathname !== "/api/scheduler") {
338
+ let auditLog = `[Dashboard] 🚦 Access: ${req.method} ${reqUrl.pathname} by agent ${authReq.agent_id}`;
339
+ if (authReq.al_name)
340
+ auditLog += ` (${authReq.al_name})`;
341
+ if (authReq.al_audit_url)
342
+ auditLog += ` - Audit: ${authReq.al_audit_url}`;
343
+ console.error(auditLog);
344
+ }
321
345
  try {
322
346
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
323
347
  // ─── SSE: MCP Transport Endpoint ───
package/dist/server.js CHANGED
File without changes
@@ -1,20 +1,20 @@
1
1
  /**
2
- * Task Router Handler (v7.1.0)
2
+ * Task Router Handler (v9.1.0)
3
3
  *
4
4
  * Pure, deterministic heuristic-based routing engine that analyzes a coding
5
5
  * task description and recommends whether it should be handled by the host
6
- * cloud model or delegated to the local claw-code-agent (Qwen3).
6
+ * cloud model or delegated to the local claw-code-agent (deepseek-r1 / qwen2.5-coder).
7
7
  *
8
- * No database queries. No API calls. Fully testable.
8
+ * No database queries in the pure route. No API calls. Fully testable.
9
+ * Experience-based ML bias (v7.2.0+) is applied post-hoc in the handler.
9
10
  *
10
- * Heuristic Signals (v7.1.0):
11
+ * Heuristic Signals:
11
12
  * 1. Keyword analysis (weight: 0.35)
12
- * 2. File count (weight: 0.20)
13
- * 3. estimated_scope enum (weight: 0.25)
14
- * 4. Task length proxy (weight: 0.10)
15
- * 5. Multi-step detection (weight: 0.10)
16
- *
17
- * v7.2.0 will add experience-based ML routing using SQLite feedback data.
13
+ * 2. File count (weight: 0.15)
14
+ * 3. File type / extension (weight: 0.10)
15
+ * 4. estimated_scope enum (weight: 0.20)
16
+ * 5. Task length proxy (weight: 0.10)
17
+ * 6. Multi-step detection (weight: 0.10)
18
18
  */
19
19
  import { isSessionTaskRouteArgs, } from "./sessionMemoryDefinitions.js";
20
20
  import { getStorage } from "../storage/index.js";
@@ -59,7 +59,8 @@ const MULTI_STEP_MARKERS = [
59
59
  "step 1", "step 2", "step 3",
60
60
  "then update", "then modify", "then create",
61
61
  "followed by", "subsequently",
62
- "1.", "2.", "3.",
62
+ // Note: removed bare "1.", "2.", "3." — too many false positives
63
+ // on version numbers (v1.2.3), decimals, and IP addresses.
63
64
  ];
64
65
  // ─── Heuristic Engine ────────────────────────────────────────
65
66
  /**
@@ -108,7 +109,32 @@ function fileCountSignal(files) {
108
109
  return -1.0;
109
110
  }
110
111
  /**
111
- * Compute a claw-affinity score from estimated_scope.
112
+ * Compute a claw-affinity score from file extentions.
113
+ * Simple configs/docs -> claw (+0.5)
114
+ * Complex low-level languages -> host (-0.5)
115
+ */
116
+ function fileTypeSignal(files) {
117
+ if (!files || files.length === 0)
118
+ return 0;
119
+ let simple = 0;
120
+ let complex = 0;
121
+ for (const f of files) {
122
+ if (f.match(/\.(md|json|yml|yaml|txt|csv|env|ini|toml|cfg)$/i))
123
+ simple++;
124
+ else if (f.match(/\.(cpp|cc|cxx|c|h|hpp|rs|go|java|swift|zig)$/i))
125
+ complex++;
126
+ // .ts, .js, .py, .rb, .sh, .css, .html — common scripting/web langs stay neutral (0)
127
+ }
128
+ if (simple > 0 && complex === 0)
129
+ return 0.5;
130
+ if (complex > 0 && simple === 0)
131
+ return -0.5;
132
+ if (complex > 0 && simple > 0)
133
+ return -0.2; // Complex outweighs simple
134
+ return 0;
135
+ }
136
+ /**
137
+ * Compute a claw-affinity score from scope.
112
138
  * minor_edit → strongly claw (+1.0)
113
139
  * bug_fix → moderate claw (+0.4) — some bugs are complex
114
140
  * new_feature → moderate host (-0.3)
@@ -125,17 +151,23 @@ function scopeSignal(scope) {
125
151
  }
126
152
  /**
127
153
  * Compute a claw-affinity score from task description length.
128
- * Short (< 200 chars) → claw-favoring (+0.5)
154
+ * Short (< 100 chars) → strongly claw (+1.0)
155
+ * Short-medium (< 200 chars) → claw (+0.5)
129
156
  * Medium (200-500 chars) → neutral (0.0)
130
- * Long (> 500 chars) → host-favoring (-0.5) — long = complex context
157
+ * Long (500-1500 chars) → host-favoring (-0.5)
158
+ * Very long (> 1500 chars) → strongly host (-1.0) due to context complexity
131
159
  */
132
160
  function lengthSignal(description) {
133
161
  const len = description.length;
162
+ if (len < 100)
163
+ return 1.0;
134
164
  if (len < 200)
135
165
  return 0.5;
136
166
  if (len <= 500)
137
167
  return 0.0;
138
- return -0.5;
168
+ if (len <= 1500)
169
+ return -0.5;
170
+ return -1.0;
139
171
  }
140
172
  /**
141
173
  * Detect multi-step task patterns.
@@ -153,8 +185,9 @@ function multiStepSignal(description) {
153
185
  // ─── Weights ─────────────────────────────────────────────────
154
186
  const WEIGHTS = {
155
187
  keyword: 0.35,
156
- fileCount: 0.20,
157
- scope: 0.25,
188
+ fileCount: 0.15,
189
+ fileType: 0.10,
190
+ scope: 0.20,
158
191
  length: 0.10,
159
192
  multiStep: 0.10,
160
193
  };
@@ -177,6 +210,7 @@ export function computeRoute(args) {
177
210
  // ── Compute individual signals ──
178
211
  const kw = keywordSignal(task_description);
179
212
  const fc = fileCountSignal(files_involved);
213
+ const ft = fileTypeSignal(files_involved);
180
214
  const sc = scopeSignal(estimated_scope);
181
215
  const ln = lengthSignal(task_description);
182
216
  const ms = multiStepSignal(task_description);
@@ -184,6 +218,7 @@ export function computeRoute(args) {
184
218
  // Positive = claw-favoring, Negative = host-favoring
185
219
  const composite = kw * WEIGHTS.keyword +
186
220
  fc * WEIGHTS.fileCount +
221
+ ft * WEIGHTS.fileType +
187
222
  sc * WEIGHTS.scope +
188
223
  ln * WEIGHTS.length +
189
224
  ms * WEIGHTS.multiStep;
@@ -206,6 +241,8 @@ export function computeRoute(args) {
206
241
  signals.push(`keyword analysis ${kw > 0 ? "favors claw" : "favors host"} (${kw.toFixed(2)})`);
207
242
  if (fc !== 0)
208
243
  signals.push(`file count signal: ${fc.toFixed(1)}`);
244
+ if (ft !== 0)
245
+ signals.push(`file type signal: ${ft.toFixed(1)}`);
209
246
  if (sc !== 0)
210
247
  signals.push(`scope "${estimated_scope}" signal: ${sc.toFixed(1)}`);
211
248
  if (ms !== 0)
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prism-mcp-server",
3
- "version": "9.0.5",
3
+ "version": "9.1.0",
4
4
  "mcpName": "io.github.dcostenco/prism-mcp",
5
5
  "description": "The Mind Palace for AI Agents — a true Cognitive Architecture with Hebbian learning (episodic→semantic consolidation), ACT-R spreading activation (multi-hop causal reasoning), uncertainty-aware rejection gates (agents that know when they don't know), adversarial evaluation (anti-sycophancy), fail-closed Dark Factory pipelines, persistent memory (SQLite/Supabase), multi-agent Hivemind, time travel & visual dashboard. Zero-config local mode.",
6
6
  "module": "index.ts",