prism-mcp-server 9.0.5 β 9.0.6
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 +13 -8
- package/dist/dashboard/authUtils.js +39 -12
- package/dist/dashboard/server.js +26 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -725,13 +725,13 @@ The Generator strips the `console.log`, resubmits, and the next `EVALUATE` retur
|
|
|
725
725
|
|
|
726
726
|
## π What's New
|
|
727
727
|
|
|
728
|
-
> **Current release:
|
|
728
|
+
> **Current release: v9.0.5 β JWKS Auth Security Hardening**
|
|
729
729
|
|
|
730
|
-
-
|
|
731
|
-
-
|
|
732
|
-
-
|
|
733
|
-
-
|
|
734
|
-
-
|
|
730
|
+
- π **v9.0.5 β JWKS 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, Keycloak, and custom JWKS endpoints.
|
|
731
|
+
- π§ **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)
|
|
732
|
+
- π§ **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)
|
|
733
|
+
- π **v7.7.0 β Cloud-Native SSE Transport:** Full Server-Sent Events MCP support for seamless network deployments.
|
|
734
|
+
- βοΈ **v7.4.0 β Adversarial Evaluation:** Split-brain anti-sycophancy pipeline with evidence-bound findings.
|
|
735
735
|
|
|
736
736
|
π **[Full release history β CHANGELOG.md](CHANGELOG.md)** Β· **[ROADMAP β](ROADMAP.md)**
|
|
737
737
|
|
|
@@ -971,6 +971,9 @@ Requires `PRISM_DARK_FACTORY_ENABLED=true`.
|
|
|
971
971
|
| `PRISM_ACTR_WEIGHT_ACTIVATION` | No | Composite score ACT-R activation weight (default: `0.3`) |
|
|
972
972
|
| `PRISM_ACTR_ACCESS_LOG_RETENTION_DAYS` | No | Days before access logs are pruned by background scheduler (default: `90`) |
|
|
973
973
|
| `PRISM_DARK_FACTORY_ENABLED` | No | `"true"` to enable Dark Factory autonomous pipeline tools (`session_start_pipeline`, `session_check_pipeline_status`, `session_abort_pipeline`) |
|
|
974
|
+
| `PRISM_JWKS_URI` | No | JWKS endpoint URL for vendor-neutral JWT auth (e.g., `https://your-tenant.auth0.com/.well-known/jwks.json`) |
|
|
975
|
+
| `PRISM_JWT_AUDIENCE` | No | Expected JWT `aud` claim β prevents cross-service token confusion |
|
|
976
|
+
| `PRISM_JWT_ISSUER` | No | Expected JWT `iss` claim β validates token origin |
|
|
974
977
|
|
|
975
978
|
</details>
|
|
976
979
|
|
|
@@ -1099,10 +1102,12 @@ Prism has evolved from smart session logging into a **cognitive memory architect
|
|
|
1099
1102
|
|
|
1100
1103
|
## π¦ Milestones & Roadmap
|
|
1101
1104
|
|
|
1102
|
-
> **Current:
|
|
1105
|
+
> **Current: v9.0.5** β JWKS Auth Security Hardening ([CHANGELOG](CHANGELOG.md))
|
|
1103
1106
|
|
|
1104
1107
|
| Release | Headline |
|
|
1105
1108
|
|---------|----------|
|
|
1109
|
+
| **v9.0.5** | π JWKS Auth Security Hardening β audience/issuer validation, JWT failure logging, typed agent identity |
|
|
1110
|
+
| **v9.0** | π§ Autonomous Cognitive OS β Surprisal Gate, Cognitive Budget, Affect-Tagged Memory |
|
|
1106
1111
|
| **v7.8** | π§ Cognitive Architecture β Hebbian consolidation, multi-hop reasoning, rejection gate, dynamic decay |
|
|
1107
1112
|
| **v7.7** | π Cloud-Native SSE Transport |
|
|
1108
1113
|
| **v7.5** | π©Ί Intent Health Dashboard + Security Hardening |
|
|
@@ -1145,7 +1150,7 @@ A: Run `npm run build && npm test`, then open the Mind Palace dashboard (`localh
|
|
|
1145
1150
|
- **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
1151
|
- **No real-time sync without Supabase.** Local SQLite mode is single-machine only. Multi-device or team sync requires a Supabase backend.
|
|
1147
1152
|
- **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`.
|
|
1153
|
+
- **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
1154
|
- **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
1155
|
- **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
1156
|
- **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.
|
|
@@ -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
|
-
*
|
|
56
|
-
* 1. Auth
|
|
57
|
-
* 2.
|
|
58
|
-
* 3.
|
|
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
|
|
61
|
-
*
|
|
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
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
78
|
-
|
|
104
|
+
const code = err.code || "UNKNOWN";
|
|
105
|
+
console.error(`[Auth] JWT verification failed (${code}):`, err.message);
|
|
79
106
|
return false;
|
|
80
107
|
}
|
|
81
108
|
}
|
package/dist/dashboard/server.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prism-mcp-server",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.6",
|
|
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",
|