@steno-ai/mcp 0.1.10 → 0.1.12
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 +11 -1
- package/dist/cli.d.ts +0 -0
- package/dist/cli.d.ts.map +0 -0
- package/dist/cli.js.map +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.d.ts.map +0 -0
- package/dist/index.js +0 -0
- package/dist/index.js.map +0 -0
- package/dist/init.d.ts +0 -0
- package/dist/init.d.ts.map +0 -0
- package/dist/init.js +159 -28
- package/dist/init.js.map +1 -1
- package/dist/local-server.d.ts +0 -0
- package/dist/local-server.d.ts.map +1 -1
- package/dist/local-server.js +213 -7
- package/dist/local-server.js.map +1 -1
- package/dist/local.d.ts +0 -0
- package/dist/local.d.ts.map +0 -0
- package/dist/local.js +0 -0
- package/dist/local.js.map +0 -0
- package/dist/server.d.ts +0 -0
- package/dist/server.d.ts.map +0 -0
- package/dist/server.js +0 -0
- package/dist/server.js.map +0 -0
- package/package.json +15 -12
- package/src/cli.ts +0 -0
- package/src/index.ts +0 -0
- package/src/init.ts +160 -21
- package/src/local-server.ts +232 -17
- package/src/local.ts +0 -0
- package/src/server.ts +0 -0
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@ That's it. Your data stays in YOUR Supabase project. Nothing is shared.
|
|
|
42
42
|
| `steno_remember` | Stores facts, preferences, decisions, people, events |
|
|
43
43
|
| `steno_recall` | Searches memory with 6-signal fusion (vector + keyword + graph + temporal + recency + salience) |
|
|
44
44
|
| `steno_flush` | Forces extraction of buffered session messages |
|
|
45
|
+
| `steno_update_status` | Updates priority/roadmap item status (not_started, in_progress, done, blocked) |
|
|
45
46
|
| `steno_feedback` | Rates whether a recalled memory was useful |
|
|
46
47
|
| `steno_stats` | Shows memory statistics |
|
|
47
48
|
|
|
@@ -59,7 +60,16 @@ That's it. Your data stays in YOUR Supabase project. Nothing is shared.
|
|
|
59
60
|
- Session buffering for cross-message context
|
|
60
61
|
- Source chunk preservation for full-context answers
|
|
61
62
|
|
|
62
|
-
##
|
|
63
|
+
## Claude Code Setup
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
claude mcp add steno-memory -- npx -y @steno-ai/mcp \
|
|
67
|
+
--env SUPABASE_URL=https://YOUR-PROJECT.supabase.co \
|
|
68
|
+
--env SUPABASE_SERVICE_ROLE_KEY=eyJ... \
|
|
69
|
+
--env OPENAI_API_KEY=sk-...
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Claude Desktop — Manual Setup
|
|
63
73
|
|
|
64
74
|
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
65
75
|
|
package/dist/cli.d.ts
CHANGED
|
File without changes
|
package/dist/cli.d.ts.map
CHANGED
|
File without changes
|
package/dist/cli.js.map
CHANGED
|
File without changes
|
package/dist/index.d.ts
CHANGED
|
File without changes
|
package/dist/index.d.ts.map
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/index.js.map
CHANGED
|
File without changes
|
package/dist/init.d.ts
CHANGED
|
File without changes
|
package/dist/init.d.ts.map
CHANGED
|
File without changes
|
package/dist/init.js
CHANGED
|
@@ -73,7 +73,7 @@ const MIGRATIONS = [
|
|
|
73
73
|
input_size INTEGER,
|
|
74
74
|
scope TEXT NOT NULL,
|
|
75
75
|
scope_id TEXT NOT NULL,
|
|
76
|
-
session_id
|
|
76
|
+
session_id TEXT,
|
|
77
77
|
tier_used TEXT,
|
|
78
78
|
llm_model TEXT,
|
|
79
79
|
facts_created INTEGER NOT NULL DEFAULT 0,
|
|
@@ -96,7 +96,7 @@ const MIGRATIONS = [
|
|
|
96
96
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
97
97
|
scope TEXT NOT NULL CHECK (scope IN ('user','agent','session','hive')),
|
|
98
98
|
scope_id TEXT NOT NULL,
|
|
99
|
-
session_id
|
|
99
|
+
session_id TEXT,
|
|
100
100
|
content TEXT NOT NULL,
|
|
101
101
|
embedding VECTOR(2000),
|
|
102
102
|
embedding_model TEXT,
|
|
@@ -276,6 +276,133 @@ const MIGRATIONS = [
|
|
|
276
276
|
AND f.search_vector @@ plainto_tsquery('english', search_query)
|
|
277
277
|
ORDER BY ts_rank(f.search_vector, plainto_tsquery('english', search_query)) DESC LIMIT match_count);
|
|
278
278
|
END; $$;`,
|
|
279
|
+
// Usage records unique constraint (required by increment_usage)
|
|
280
|
+
`ALTER TABLE usage_records ADD CONSTRAINT IF NOT EXISTS usage_records_tenant_period_unique UNIQUE (tenant_id, period_start);`,
|
|
281
|
+
// Extraction hash unique index
|
|
282
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS idx_extractions_hash ON extractions(tenant_id, input_hash);`,
|
|
283
|
+
// match_facts RPC
|
|
284
|
+
`CREATE OR REPLACE FUNCTION match_facts(
|
|
285
|
+
query_embedding TEXT, match_tenant_id UUID, match_scope TEXT,
|
|
286
|
+
match_scope_id TEXT, match_count INT, min_similarity FLOAT DEFAULT 0,
|
|
287
|
+
match_as_of TIMESTAMPTZ DEFAULT NULL
|
|
288
|
+
) RETURNS TABLE (
|
|
289
|
+
id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
290
|
+
content TEXT, embedding_model TEXT, embedding_dim INT, version INT,
|
|
291
|
+
lineage_id UUID, valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ,
|
|
292
|
+
operation TEXT, parent_id UUID, importance NUMERIC, frequency INT,
|
|
293
|
+
last_accessed TIMESTAMPTZ, decay_score NUMERIC, contradiction_status TEXT,
|
|
294
|
+
contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
295
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT,
|
|
296
|
+
modality TEXT, tags TEXT[], metadata JSONB,
|
|
297
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT,
|
|
298
|
+
created_at TIMESTAMPTZ, similarity FLOAT
|
|
299
|
+
) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT
|
|
300
|
+
f.id, f.tenant_id, f.scope, f.scope_id, f.session_id,
|
|
301
|
+
f.content, f.embedding_model, f.embedding_dim, f.version, f.lineage_id,
|
|
302
|
+
f.valid_from, f.valid_until, f.operation, f.parent_id, f.importance, f.frequency,
|
|
303
|
+
f.last_accessed, f.decay_score, f.contradiction_status, f.contradicts_id,
|
|
304
|
+
f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id,
|
|
305
|
+
f.extraction_tier, f.modality, f.tags, f.metadata,
|
|
306
|
+
f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
307
|
+
(1 - (f.embedding <=> query_embedding::vector)) AS similarity
|
|
308
|
+
FROM facts f WHERE f.tenant_id = match_tenant_id AND f.scope = match_scope
|
|
309
|
+
AND f.scope_id = match_scope_id
|
|
310
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN f.valid_from <= match_as_of AND (f.valid_until IS NULL OR f.valid_until > match_as_of) ELSE f.valid_until IS NULL END)
|
|
311
|
+
AND (1 - (f.embedding <=> query_embedding::vector)) >= min_similarity
|
|
312
|
+
ORDER BY f.embedding <=> query_embedding::vector LIMIT match_count; END; $$;`,
|
|
313
|
+
// increment_usage RPC
|
|
314
|
+
`CREATE OR REPLACE FUNCTION increment_usage(p_tenant_id UUID, p_tokens INT, p_queries INT, p_extractions INT, p_cost_usd FLOAT)
|
|
315
|
+
RETURNS VOID LANGUAGE plpgsql AS $$ DECLARE p_start DATE := date_trunc('month', CURRENT_DATE)::date;
|
|
316
|
+
p_end DATE := (date_trunc('month', CURRENT_DATE) + interval '1 month' - interval '1 day')::date;
|
|
317
|
+
BEGIN INSERT INTO usage_records (id, tenant_id, period_start, period_end, tokens_used, queries_used, extractions_count, cost_usd)
|
|
318
|
+
VALUES (gen_random_uuid(), p_tenant_id, p_start, p_end, p_tokens, p_queries, p_extractions, p_cost_usd)
|
|
319
|
+
ON CONFLICT (tenant_id, period_start) DO UPDATE SET
|
|
320
|
+
tokens_used = usage_records.tokens_used + EXCLUDED.tokens_used,
|
|
321
|
+
queries_used = usage_records.queries_used + EXCLUDED.queries_used,
|
|
322
|
+
extractions_count = usage_records.extractions_count + EXCLUDED.extractions_count,
|
|
323
|
+
cost_usd = usage_records.cost_usd + EXCLUDED.cost_usd, updated_at = NOW(); END; $$;`,
|
|
324
|
+
// match_entities RPC
|
|
325
|
+
`CREATE OR REPLACE FUNCTION match_entities(query_embedding TEXT, match_tenant_id UUID, match_count INT DEFAULT 10, min_similarity FLOAT DEFAULT 0.3)
|
|
326
|
+
RETURNS TABLE (id UUID, tenant_id UUID, name TEXT, entity_type TEXT, canonical_name TEXT, properties JSONB,
|
|
327
|
+
embedding_model TEXT, embedding_dim INT, merge_target_id UUID, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, similarity FLOAT)
|
|
328
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT e.id, e.tenant_id, e.name, e.entity_type, e.canonical_name,
|
|
329
|
+
e.properties, e.embedding_model, e.embedding_dim, e.merge_target_id, e.created_at, e.updated_at,
|
|
330
|
+
(1 - (e.embedding <=> query_embedding::vector))::float AS similarity
|
|
331
|
+
FROM entities e WHERE e.tenant_id = match_tenant_id AND e.embedding IS NOT NULL
|
|
332
|
+
AND (1 - (e.embedding <=> query_embedding::vector)) >= min_similarity
|
|
333
|
+
ORDER BY e.embedding <=> query_embedding::vector LIMIT match_count; END; $$;`,
|
|
334
|
+
// graph_traverse RPC
|
|
335
|
+
`CREATE OR REPLACE FUNCTION graph_traverse(match_tenant_id UUID, seed_entity_ids UUID[], max_depth INT DEFAULT 3, max_entities INT DEFAULT 200, match_as_of TIMESTAMPTZ DEFAULT NULL)
|
|
336
|
+
RETURNS TABLE (entity_id UUID, entity_name TEXT, entity_type TEXT, canonical_name TEXT, properties JSONB, hop_depth INT,
|
|
337
|
+
edge_id UUID, edge_source_id UUID, edge_target_id UUID, edge_relation TEXT, edge_type TEXT, edge_weight FLOAT,
|
|
338
|
+
edge_valid_from TIMESTAMPTZ, edge_valid_until TIMESTAMPTZ, edge_confidence FLOAT)
|
|
339
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY WITH RECURSIVE traversal AS (
|
|
340
|
+
SELECT e.id AS entity_id, e.name AS entity_name, e.entity_type, e.canonical_name, e.properties, 0 AS hop_depth,
|
|
341
|
+
NULL::UUID AS edge_id, NULL::UUID AS edge_source_id, NULL::UUID AS edge_target_id, NULL::TEXT AS edge_relation,
|
|
342
|
+
NULL::TEXT AS edge_type, NULL::FLOAT AS edge_weight, NULL::TIMESTAMPTZ AS edge_valid_from,
|
|
343
|
+
NULL::TIMESTAMPTZ AS edge_valid_until, NULL::FLOAT AS edge_confidence, ARRAY[e.id] AS visited_ids
|
|
344
|
+
FROM entities e WHERE e.id = ANY(seed_entity_ids) AND e.tenant_id = match_tenant_id
|
|
345
|
+
UNION ALL
|
|
346
|
+
SELECT e2.id, e2.name, e2.entity_type, e2.canonical_name, e2.properties, t.hop_depth + 1,
|
|
347
|
+
ed.id, ed.source_id, ed.target_id, ed.relation, ed.edge_type, ed.weight, ed.valid_from, ed.valid_until, ed.confidence,
|
|
348
|
+
t.visited_ids || e2.id
|
|
349
|
+
FROM traversal t JOIN edges ed ON (ed.source_id = t.entity_id OR ed.target_id = t.entity_id) AND ed.tenant_id = match_tenant_id
|
|
350
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN ed.valid_from <= match_as_of AND (ed.valid_until IS NULL OR ed.valid_until > match_as_of) ELSE ed.valid_until IS NULL END)
|
|
351
|
+
JOIN entities e2 ON e2.id = CASE WHEN ed.source_id = t.entity_id THEN ed.target_id ELSE ed.source_id END AND e2.tenant_id = match_tenant_id
|
|
352
|
+
WHERE t.hop_depth < max_depth AND e2.id != ALL(t.visited_ids)
|
|
353
|
+
) SELECT traversal.entity_id, traversal.entity_name, traversal.entity_type, traversal.canonical_name, traversal.properties,
|
|
354
|
+
traversal.hop_depth, traversal.edge_id, traversal.edge_source_id, traversal.edge_target_id, traversal.edge_relation,
|
|
355
|
+
traversal.edge_type, traversal.edge_weight, traversal.edge_valid_from, traversal.edge_valid_until, traversal.edge_confidence
|
|
356
|
+
FROM traversal LIMIT max_entities; END; $$;`,
|
|
357
|
+
// get_facts_for_entities RPC
|
|
358
|
+
`CREATE OR REPLACE FUNCTION get_facts_for_entities(match_tenant_id UUID, entity_ids UUID[], per_entity_limit INT DEFAULT 20)
|
|
359
|
+
RETURNS TABLE (entity_id UUID, fact_id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
360
|
+
content TEXT, embedding_model TEXT, embedding_dim INTEGER, version INTEGER, lineage_id UUID,
|
|
361
|
+
valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ, operation TEXT, parent_id UUID,
|
|
362
|
+
importance NUMERIC, frequency INTEGER, last_accessed TIMESTAMPTZ, decay_score NUMERIC,
|
|
363
|
+
contradiction_status TEXT, contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
364
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT, modality TEXT, tags TEXT[], metadata JSONB,
|
|
365
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT, created_at TIMESTAMPTZ)
|
|
366
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT ranked.entity_id, ranked.fact_id, ranked.tenant_id, ranked.scope,
|
|
367
|
+
ranked.scope_id, ranked.session_id, ranked.content, ranked.embedding_model, ranked.embedding_dim, ranked.version,
|
|
368
|
+
ranked.lineage_id, ranked.valid_from, ranked.valid_until, ranked.operation, ranked.parent_id, ranked.importance,
|
|
369
|
+
ranked.frequency, ranked.last_accessed, ranked.decay_score, ranked.contradiction_status, ranked.contradicts_id,
|
|
370
|
+
ranked.source_type, ranked.source_ref, ranked.confidence, ranked.original_content, ranked.extraction_id,
|
|
371
|
+
ranked.extraction_tier, ranked.modality, ranked.tags, ranked.metadata,
|
|
372
|
+
ranked.event_date, ranked.document_date, ranked.source_chunk, ranked.created_at
|
|
373
|
+
FROM (SELECT fe.entity_id, f.id AS fact_id, f.tenant_id, f.scope, f.scope_id, f.session_id, f.content,
|
|
374
|
+
f.embedding_model, f.embedding_dim, f.version, f.lineage_id, f.valid_from, f.valid_until, f.operation,
|
|
375
|
+
f.parent_id, f.importance, f.frequency, f.last_accessed, f.decay_score, f.contradiction_status, f.contradicts_id,
|
|
376
|
+
f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id, f.extraction_tier, f.modality,
|
|
377
|
+
f.tags, f.metadata, f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
378
|
+
ROW_NUMBER() OVER (PARTITION BY fe.entity_id ORDER BY f.importance DESC, f.created_at DESC) AS rn
|
|
379
|
+
FROM fact_entities fe JOIN facts f ON f.id = fe.fact_id WHERE fe.entity_id = ANY(entity_ids)
|
|
380
|
+
AND f.tenant_id = match_tenant_id AND f.valid_until IS NULL AND NOT ('raw_chunk' = ANY(f.tags))) ranked
|
|
381
|
+
WHERE ranked.rn <= per_entity_limit; END; $$;`,
|
|
382
|
+
// keyword_search_facts RPC
|
|
383
|
+
`CREATE OR REPLACE FUNCTION keyword_search_facts(search_query TEXT, match_tenant_id UUID, match_scope TEXT,
|
|
384
|
+
match_scope_id TEXT, match_count INT, match_as_of TIMESTAMPTZ DEFAULT NULL)
|
|
385
|
+
RETURNS TABLE (id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
386
|
+
content TEXT, embedding_model TEXT, embedding_dim INT, version INT, lineage_id UUID,
|
|
387
|
+
valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ, operation TEXT, parent_id UUID,
|
|
388
|
+
importance NUMERIC, frequency INT, last_accessed TIMESTAMPTZ, decay_score NUMERIC,
|
|
389
|
+
contradiction_status TEXT, contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
390
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT, modality TEXT, tags TEXT[], metadata JSONB,
|
|
391
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT, created_at TIMESTAMPTZ, rank_score FLOAT)
|
|
392
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT f.id, f.tenant_id, f.scope, f.scope_id, f.session_id,
|
|
393
|
+
f.content, f.embedding_model, f.embedding_dim, f.version, f.lineage_id, f.valid_from, f.valid_until,
|
|
394
|
+
f.operation, f.parent_id, f.importance, f.frequency, f.last_accessed, f.decay_score, f.contradiction_status,
|
|
395
|
+
f.contradicts_id, f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id,
|
|
396
|
+
f.extraction_tier, f.modality, f.tags, f.metadata, f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
397
|
+
ts_rank(f.search_vector, plainto_tsquery('english', search_query)) AS rank_score
|
|
398
|
+
FROM facts f WHERE f.tenant_id = match_tenant_id AND f.scope = match_scope AND f.scope_id = match_scope_id
|
|
399
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN f.valid_from <= match_as_of AND (f.valid_until IS NULL OR f.valid_until > match_as_of) ELSE f.valid_until IS NULL END)
|
|
400
|
+
AND f.search_vector @@ plainto_tsquery('english', search_query)
|
|
401
|
+
ORDER BY rank_score DESC LIMIT match_count; END; $$;`,
|
|
402
|
+
// increment_trigger_fired RPC
|
|
403
|
+
`CREATE OR REPLACE FUNCTION increment_trigger_fired(p_tenant_id UUID, p_trigger_id UUID)
|
|
404
|
+
RETURNS VOID LANGUAGE plpgsql AS $$ BEGIN UPDATE triggers SET times_fired = times_fired + 1,
|
|
405
|
+
last_fired_at = NOW(), updated_at = NOW() WHERE tenant_id = p_tenant_id AND id = p_trigger_id; END; $$;`,
|
|
279
406
|
// Default tenant
|
|
280
407
|
`INSERT INTO tenants (id, name, slug, plan) VALUES ('00000000-0000-0000-0000-000000000001', 'Default', 'default', 'enterprise') ON CONFLICT DO NOTHING;`,
|
|
281
408
|
];
|
|
@@ -293,34 +420,38 @@ async function main() {
|
|
|
293
420
|
// 2. Run migrations
|
|
294
421
|
console.log('\n Running database migrations...');
|
|
295
422
|
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
else {
|
|
312
|
-
skipped++;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
success++;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
catch {
|
|
320
|
-
skipped++;
|
|
423
|
+
// Try running migrations via Supabase Management API (requires service role key)
|
|
424
|
+
// If that fails, write SQL to a file for manual execution
|
|
425
|
+
const allSql = MIGRATIONS.join('\n\n');
|
|
426
|
+
const sqlPath = path.join(process.cwd(), 'steno-migrations.sql');
|
|
427
|
+
// Attempt automatic migration via Supabase SQL endpoint
|
|
428
|
+
let autoMigrated = false;
|
|
429
|
+
try {
|
|
430
|
+
const res = await fetch(`${supabaseUrl}/rest/v1/rpc/exec_sql`, {
|
|
431
|
+
method: 'POST',
|
|
432
|
+
headers: { 'apikey': supabaseKey, 'Authorization': `Bearer ${supabaseKey}`, 'Content-Type': 'application/json' },
|
|
433
|
+
body: JSON.stringify({ query: allSql }),
|
|
434
|
+
});
|
|
435
|
+
if (res.ok) {
|
|
436
|
+
autoMigrated = true;
|
|
437
|
+
console.log(' ✓ All migrations applied automatically');
|
|
321
438
|
}
|
|
322
439
|
}
|
|
323
|
-
|
|
440
|
+
catch { /* RPC not available */ }
|
|
441
|
+
if (!autoMigrated) {
|
|
442
|
+
// Write SQL file for manual execution
|
|
443
|
+
fs.writeFileSync(sqlPath, allSql);
|
|
444
|
+
console.log(`
|
|
445
|
+
⚠️ Could not run migrations automatically.
|
|
446
|
+
|
|
447
|
+
Please run the SQL manually:
|
|
448
|
+
1. Open your Supabase dashboard → SQL Editor
|
|
449
|
+
2. Paste the contents of: ${sqlPath}
|
|
450
|
+
3. Click "Run"
|
|
451
|
+
4. Come back here and press Enter to continue
|
|
452
|
+
`);
|
|
453
|
+
await ask(' Press Enter after running the SQL... ');
|
|
454
|
+
}
|
|
324
455
|
// 3. Write Claude Desktop config
|
|
325
456
|
const configDir = path.join(os.homedir(), 'Library', 'Application Support', 'Claude');
|
|
326
457
|
const configPath = path.join(configDir, 'claude_desktop_config.json');
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAErC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACtF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAmB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEhF,0BAA0B;AAC1B,MAAM,UAAU,GAAG;IACjB,6CAA6C;IAC7C,0CAA0C;IAC1C,2CAA2C;IAC3C,UAAU;IACV;;;;;;;;;;;;;KAaG;IACH,WAAW;IACX;;;;;;;;;;;KAWG;IACH,WAAW;IACX;;;;;;;;;;;;;KAaG;IACH,cAAc;IACd;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BG;IACH,QAAQ;IACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCG;IACH,eAAe;IACf;;;sGAGoG;IACpG,oBAAoB;IACpB,4IAA4I;IAC5I,WAAW;IACX;;;;;;;;;;;;;;gHAc8G;IAC9G,uBAAuB;IACvB;;;;;;KAMG;IACH,QAAQ;IACR;;;;;;;;;;;;;;;;8EAgB4E;IAC5E,WAAW;IACX;;;;;;;;;;;;;;KAcG;IACH,kBAAkB;IAClB;;;;;;;;;;;;;;KAcG;IACH,gBAAgB;IAChB;;;;;;;;;;;KAWG;IACH,WAAW;IACX;;;;;;;;;KASG;IACH,sBAAsB;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAyCS;IACT,iBAAiB;IACjB,wJAAwJ;CACzJ,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAEpD,cAAc;IACd,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,wDAAwD,CAAC,CAAC;IAE1F,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAExD,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
package/dist/local-server.d.ts
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-server.d.ts","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAErF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;CACnE;AAkDD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"local-server.d.ts","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAErF,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;CACnE;AAkDD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAsgBtE"}
|
package/dist/local-server.js
CHANGED
|
@@ -46,6 +46,15 @@ export function createLocalServer(config) {
|
|
|
46
46
|
const server = new McpServer({
|
|
47
47
|
name: 'steno-local',
|
|
48
48
|
version: '0.1.0',
|
|
49
|
+
...{ instructions: `You have access to the user's persistent long-term memory via Steno.
|
|
50
|
+
|
|
51
|
+
CRITICAL RULES:
|
|
52
|
+
1. ALWAYS call steno_recall BEFORE answering ANY question about the user, their life, work, projects, people they know, preferences, past events, companies, or decisions.
|
|
53
|
+
2. When the user shares personal information, call steno_remember to store it, then ALWAYS call steno_flush immediately after to ensure extraction happens now.
|
|
54
|
+
3. Before context compaction or session end, call steno_remember with a summary of key decisions and progress, then steno_flush.
|
|
55
|
+
4. Never say "I don't have information about that" without first checking steno_recall.
|
|
56
|
+
5. Steno memory persists across ALL conversations — it knows things from past sessions that your conversation history does not.
|
|
57
|
+
6. Use steno_update_status to change priority/roadmap item status when the user starts, completes, or gets blocked on a task.` },
|
|
49
58
|
});
|
|
50
59
|
// Lazy import to avoid loading heavy modules at startup
|
|
51
60
|
let _search = null;
|
|
@@ -224,8 +233,146 @@ export function createLocalServer(config) {
|
|
|
224
233
|
if (results.results.length === 0) {
|
|
225
234
|
return { content: [{ type: 'text', text: 'No memories found.' }] };
|
|
226
235
|
}
|
|
227
|
-
|
|
228
|
-
|
|
236
|
+
// Build priority label map: factId → "Priority #N (short name)"
|
|
237
|
+
// Query ALL facts with priority_order metadata — not just the ones in results
|
|
238
|
+
// This ensures labels resolve even for facts referenced by edges but not in recall
|
|
239
|
+
const priorityLabels = new Map();
|
|
240
|
+
try {
|
|
241
|
+
const { data: allPriorityFacts } = await config.storage.client
|
|
242
|
+
.from('facts')
|
|
243
|
+
.select('id, content, metadata')
|
|
244
|
+
.eq('tenant_id', config.tenantId)
|
|
245
|
+
.not('metadata->priority_order', 'is', null);
|
|
246
|
+
if (allPriorityFacts) {
|
|
247
|
+
for (const f of allPriorityFacts) {
|
|
248
|
+
const order = f.metadata?.priority_order;
|
|
249
|
+
if (order) {
|
|
250
|
+
const shortName = f.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants|Steno)\s+/i, '').slice(0, 35).replace(/\s+\S*$/, '');
|
|
251
|
+
priorityLabels.set(f.id, `Priority #${order} (${shortName})`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch { /* fallback to results-only labels */ }
|
|
257
|
+
// Also add labels from results (in case metadata query missed any)
|
|
258
|
+
for (const r of results.results) {
|
|
259
|
+
if (priorityLabels.has(r.fact.id))
|
|
260
|
+
continue;
|
|
261
|
+
const meta = r.fact.metadata;
|
|
262
|
+
const order = meta?.priority_order;
|
|
263
|
+
if (order) {
|
|
264
|
+
const shortName = r.fact.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants)\s+/i, '').slice(0, 35).replace(/\s+\S*$/, '');
|
|
265
|
+
priorityLabels.set(r.fact.id, `Priority #${order} (${shortName})`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Build dependency map — ONE batch query for ALL dependency edges in this tenant
|
|
269
|
+
const factIds = results.results.map(r => r.fact.id);
|
|
270
|
+
const depMap = new Map();
|
|
271
|
+
try {
|
|
272
|
+
// Query ALL precedes/depends_on/deadline edges — not just for these fact_ids
|
|
273
|
+
// because edges reference sourceFactId/targetFactId in metadata, not in fact_id column
|
|
274
|
+
const { data: depEdges } = await config.storage.client
|
|
275
|
+
.from('edges')
|
|
276
|
+
.select('relation, fact_id, metadata')
|
|
277
|
+
.eq('tenant_id', config.tenantId)
|
|
278
|
+
.in('relation', ['precedes', 'depends_on', 'deadline']);
|
|
279
|
+
if (depEdges) {
|
|
280
|
+
for (const edge of depEdges) {
|
|
281
|
+
const edgeMeta = edge.metadata;
|
|
282
|
+
const sourceFactId = edgeMeta?.sourceFactId || edge.fact_id;
|
|
283
|
+
const targetFactId = edgeMeta?.targetFactId;
|
|
284
|
+
// Only process edges involving facts in our result set
|
|
285
|
+
const sourceInResults = factIds.includes(sourceFactId);
|
|
286
|
+
const targetInResults = targetFactId ? factIds.includes(targetFactId) : false;
|
|
287
|
+
if (!sourceInResults && !targetInResults)
|
|
288
|
+
continue;
|
|
289
|
+
if (!depMap.has(sourceFactId))
|
|
290
|
+
depMap.set(sourceFactId, { blocks: [], blockedBy: [], deadlines: [] });
|
|
291
|
+
if (edge.relation === 'precedes' && targetFactId) {
|
|
292
|
+
const label = priorityLabels.get(targetFactId) || 'another priority';
|
|
293
|
+
depMap.get(sourceFactId).blocks.push(label);
|
|
294
|
+
}
|
|
295
|
+
if (edge.relation === 'depends_on' && targetFactId) {
|
|
296
|
+
const label = priorityLabels.get(targetFactId) || 'another priority';
|
|
297
|
+
depMap.get(sourceFactId).blockedBy.push(label);
|
|
298
|
+
}
|
|
299
|
+
if (edge.relation === 'deadline') {
|
|
300
|
+
const deadline = edgeMeta?.deadline;
|
|
301
|
+
if (deadline) {
|
|
302
|
+
depMap.get(sourceFactId).deadlines.push(deadline);
|
|
303
|
+
// Cascade deadline upstream: if X blocks Y and Y has deadline, X gets it too
|
|
304
|
+
for (const [fid, deps2] of depMap) {
|
|
305
|
+
if (deps2.blocks.some(b => b.includes(sourceFactId.slice(0, 8)) || priorityLabels.get(sourceFactId)?.includes(b.split('(')[1]?.slice(0, 10) || ''))) {
|
|
306
|
+
if (!deps2.deadlines.includes(deadline))
|
|
307
|
+
deps2.deadlines.push(deadline + ' (cascaded)');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Second pass: cascade deadlines through depends_on chain
|
|
314
|
+
// If A depends_on B, and B has a deadline, A implicitly has that deadline
|
|
315
|
+
for (const [factId, deps] of depMap) {
|
|
316
|
+
if (deps.deadlines.length === 0) {
|
|
317
|
+
// Check if anything this blocks has a deadline
|
|
318
|
+
for (const blockLabel of deps.blocks) {
|
|
319
|
+
for (const [otherId, otherDeps] of depMap) {
|
|
320
|
+
if (priorityLabels.get(otherId) === blockLabel && otherDeps.deadlines.length > 0) {
|
|
321
|
+
for (const dl of otherDeps.deadlines) {
|
|
322
|
+
if (!dl.includes('cascaded') && !deps.deadlines.includes(dl)) {
|
|
323
|
+
deps.deadlines.push(dl + ' (implicit — blocks deadline item)');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
catch { /* batch edge lookup failed */ }
|
|
334
|
+
// Inject missing priority facts that are referenced by edges but not in recall results
|
|
335
|
+
// This ensures Priority #1 (root node) always shows up when its children are recalled
|
|
336
|
+
const resultFactIds = new Set(results.results.map(r => r.fact.id));
|
|
337
|
+
try {
|
|
338
|
+
const { data: allPriorities } = await config.storage.client
|
|
339
|
+
.from('facts')
|
|
340
|
+
.select('*')
|
|
341
|
+
.eq('tenant_id', config.tenantId)
|
|
342
|
+
.not('metadata->priority_order', 'is', null);
|
|
343
|
+
if (allPriorities) {
|
|
344
|
+
for (const pf of allPriorities) {
|
|
345
|
+
if (!resultFactIds.has(pf.id) && (depMap.has(pf.id) || priorityLabels.has(pf.id))) {
|
|
346
|
+
// This priority is referenced but not in results — inject it
|
|
347
|
+
const camelFact = Object.fromEntries(Object.entries(pf).map(([k, v]) => [k.replace(/_([a-z])/g, (_, c) => c.toUpperCase()), v]));
|
|
348
|
+
results.results.push({
|
|
349
|
+
fact: camelFact,
|
|
350
|
+
score: 0.1, // Low score since it wasn't directly matched
|
|
351
|
+
signals: { vectorScore: 0, keywordScore: 0, graphScore: 0.5, recencyScore: 0, salienceScore: 0, temporalScore: 0 },
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch { /* injection failed */ }
|
|
358
|
+
// Sort results: priorities first (by priority_order), then regular memories
|
|
359
|
+
const sortedResults = [...results.results].sort((a, b) => {
|
|
360
|
+
const aOrder = a.fact.metadata?.priority_order;
|
|
361
|
+
const bOrder = b.fact.metadata?.priority_order;
|
|
362
|
+
if (aOrder && bOrder)
|
|
363
|
+
return aOrder - bOrder;
|
|
364
|
+
if (aOrder)
|
|
365
|
+
return -1;
|
|
366
|
+
if (bOrder)
|
|
367
|
+
return 1;
|
|
368
|
+
return b.score - a.score;
|
|
369
|
+
});
|
|
370
|
+
const enrichedLines = [];
|
|
371
|
+
for (const r of sortedResults) {
|
|
372
|
+
const meta = r.fact.metadata;
|
|
373
|
+
const status = meta?.status;
|
|
374
|
+
const priorityOrder = meta?.priority_order;
|
|
375
|
+
const deps = depMap.get(r.fact.id);
|
|
229
376
|
const dateParts = [];
|
|
230
377
|
if (r.fact.eventDate)
|
|
231
378
|
dateParts.push(`event: ${new Date(r.fact.eventDate).toISOString().slice(0, 10)}`);
|
|
@@ -236,14 +383,34 @@ export function createLocalServer(config) {
|
|
|
236
383
|
.filter(([, v]) => v > 0)
|
|
237
384
|
.map(([k, v]) => `${k.replace('Score', '')}=${v.toFixed(2)}`)
|
|
238
385
|
.join(', ');
|
|
239
|
-
|
|
240
|
-
|
|
386
|
+
const isPriority = status || priorityOrder;
|
|
387
|
+
const blocks = deps?.blocks ?? [];
|
|
388
|
+
const blockedBy = deps?.blockedBy ?? [];
|
|
389
|
+
const deadlines = deps?.deadlines ?? [];
|
|
390
|
+
let line;
|
|
391
|
+
if (isPriority) {
|
|
392
|
+
line = `[Priority${priorityOrder ? ` #${priorityOrder}` : ''}] ${r.fact.content}`;
|
|
393
|
+
line += `\n status: ${status || 'unknown'}`;
|
|
394
|
+
if (blocks.length > 0)
|
|
395
|
+
line += `\n blocks: → ${blocks.join(', ')}`;
|
|
396
|
+
if (blockedBy.length > 0)
|
|
397
|
+
line += `\n blocked_by: ← ${blockedBy.join(', ')}`;
|
|
398
|
+
else if (status === 'not_started')
|
|
399
|
+
line += `\n blocked_by: none`;
|
|
400
|
+
if (deadlines.length > 0)
|
|
401
|
+
line += `\n deadline: ${deadlines.join(', ')}`;
|
|
402
|
+
line += `\n (score: ${r.score.toFixed(2)}${dateStr})`;
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
line = `[Memory] ${r.fact.content} (score: ${r.score.toFixed(2)}${dateStr}${signals ? `, ${signals}` : ''})`;
|
|
406
|
+
}
|
|
407
|
+
if (r.fact.sourceChunk && !isPriority) {
|
|
241
408
|
line += `\n[Source Context] ${r.fact.sourceChunk}`;
|
|
242
409
|
}
|
|
243
410
|
line += '\n---';
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
|
|
411
|
+
enrichedLines.push(line);
|
|
412
|
+
}
|
|
413
|
+
const text = enrichedLines.join('\n');
|
|
247
414
|
return {
|
|
248
415
|
content: [
|
|
249
416
|
{
|
|
@@ -272,6 +439,45 @@ export function createLocalServer(config) {
|
|
|
272
439
|
],
|
|
273
440
|
};
|
|
274
441
|
});
|
|
442
|
+
// ─── UPDATE STATUS ───
|
|
443
|
+
server.tool('steno_update_status', 'Update the status of a priority/roadmap item. Use when a task changes state (e.g., started working on it, completed it, or it became blocked).', {
|
|
444
|
+
priority: z.number().describe('Priority number (1-6)'),
|
|
445
|
+
status: z.enum(['not_started', 'in_progress', 'done', 'blocked']).describe('New status'),
|
|
446
|
+
}, async ({ priority, status }) => {
|
|
447
|
+
try {
|
|
448
|
+
// Find the fact with this priority_order
|
|
449
|
+
const { data: facts, error: findError } = await config.storage.client
|
|
450
|
+
.from('facts')
|
|
451
|
+
.select('id, content, metadata')
|
|
452
|
+
.eq('tenant_id', config.tenantId)
|
|
453
|
+
.not('metadata->priority_order', 'is', null);
|
|
454
|
+
if (findError)
|
|
455
|
+
throw findError;
|
|
456
|
+
const fact = facts?.find((f) => f.metadata?.priority_order === priority);
|
|
457
|
+
if (!fact) {
|
|
458
|
+
return { content: [{ type: 'text', text: `No priority #${priority} found.` }] };
|
|
459
|
+
}
|
|
460
|
+
const oldStatus = fact.metadata?.status || 'unknown';
|
|
461
|
+
const newMetadata = { ...fact.metadata, status };
|
|
462
|
+
const { error: updateError } = await config.storage.client
|
|
463
|
+
.from('facts')
|
|
464
|
+
.update({ metadata: newMetadata })
|
|
465
|
+
.eq('id', fact.id)
|
|
466
|
+
.eq('tenant_id', config.tenantId);
|
|
467
|
+
if (updateError)
|
|
468
|
+
throw updateError;
|
|
469
|
+
const shortName = fact.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants|Steno)\s+/i, '').slice(0, 50);
|
|
470
|
+
return {
|
|
471
|
+
content: [{
|
|
472
|
+
type: 'text',
|
|
473
|
+
text: `Priority #${priority} (${shortName}): ${oldStatus} → ${status}`,
|
|
474
|
+
}],
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
catch (err) {
|
|
478
|
+
return { content: [{ type: 'text', text: `Error updating status: ${err?.message ?? err}` }] };
|
|
479
|
+
}
|
|
480
|
+
});
|
|
275
481
|
// ─── STATS ───
|
|
276
482
|
server.tool('steno_stats', 'Get memory statistics — how many facts, entities, and edges are stored.', {}, async () => {
|
|
277
483
|
const facts = await config.storage.getFactsByScope(config.tenantId, config.scope, config.scopeId, { limit: 1 });
|
package/dist/local-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../src/local-server.ts"],"names":[],"mappings":"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"}
|
package/dist/local.d.ts
CHANGED
|
File without changes
|
package/dist/local.d.ts.map
CHANGED
|
File without changes
|
package/dist/local.js
CHANGED
|
File without changes
|
package/dist/local.js.map
CHANGED
|
File without changes
|
package/dist/server.d.ts
CHANGED
|
File without changes
|
package/dist/server.d.ts.map
CHANGED
|
File without changes
|
package/dist/server.js
CHANGED
|
File without changes
|
package/dist/server.js.map
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steno-ai/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "MCP server for Claude Code, Claude Desktop, and other MCP clients",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
"directory": "packages/mcp-server"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
|
-
"bin":
|
|
12
|
+
"bin": {
|
|
13
|
+
"steno-mcp": "./dist/cli.js",
|
|
14
|
+
"steno-mcp-init": "./dist/init.js"
|
|
15
|
+
},
|
|
13
16
|
"exports": {
|
|
14
17
|
".": {
|
|
15
18
|
"import": "./dist/index.js",
|
|
@@ -23,23 +26,23 @@
|
|
|
23
26
|
"src",
|
|
24
27
|
"README.md"
|
|
25
28
|
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"typecheck": "tsc --noEmit"
|
|
33
|
+
},
|
|
26
34
|
"dependencies": {
|
|
27
35
|
"@modelcontextprotocol/sdk": "^1",
|
|
36
|
+
"@steno-ai/engine": "workspace:*",
|
|
37
|
+
"@steno-ai/openai-adapter": "workspace:*",
|
|
38
|
+
"@steno-ai/supabase-adapter": "workspace:*",
|
|
28
39
|
"@supabase/supabase-js": "^2.49.0",
|
|
29
40
|
"openai": "^4.0.0",
|
|
30
|
-
"zod": "^3.25"
|
|
31
|
-
"@steno-ai/engine": "0.1.7",
|
|
32
|
-
"@steno-ai/openai-adapter": "0.1.2",
|
|
33
|
-
"@steno-ai/supabase-adapter": "0.1.4"
|
|
41
|
+
"zod": "^3.25"
|
|
34
42
|
},
|
|
35
43
|
"devDependencies": {
|
|
36
44
|
"@types/node": "^22",
|
|
37
45
|
"typescript": "^5.7",
|
|
38
46
|
"vitest": "^3"
|
|
39
|
-
},
|
|
40
|
-
"scripts": {
|
|
41
|
-
"test": "vitest run",
|
|
42
|
-
"build": "tsc",
|
|
43
|
-
"typecheck": "tsc --noEmit"
|
|
44
47
|
}
|
|
45
|
-
}
|
|
48
|
+
}
|
package/src/cli.ts
CHANGED
|
File without changes
|
package/src/index.ts
CHANGED
|
File without changes
|
package/src/init.ts
CHANGED
|
@@ -75,7 +75,7 @@ const MIGRATIONS = [
|
|
|
75
75
|
input_size INTEGER,
|
|
76
76
|
scope TEXT NOT NULL,
|
|
77
77
|
scope_id TEXT NOT NULL,
|
|
78
|
-
session_id
|
|
78
|
+
session_id TEXT,
|
|
79
79
|
tier_used TEXT,
|
|
80
80
|
llm_model TEXT,
|
|
81
81
|
facts_created INTEGER NOT NULL DEFAULT 0,
|
|
@@ -98,7 +98,7 @@ const MIGRATIONS = [
|
|
|
98
98
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
99
99
|
scope TEXT NOT NULL CHECK (scope IN ('user','agent','session','hive')),
|
|
100
100
|
scope_id TEXT NOT NULL,
|
|
101
|
-
session_id
|
|
101
|
+
session_id TEXT,
|
|
102
102
|
content TEXT NOT NULL,
|
|
103
103
|
embedding VECTOR(2000),
|
|
104
104
|
embedding_model TEXT,
|
|
@@ -278,6 +278,133 @@ const MIGRATIONS = [
|
|
|
278
278
|
AND f.search_vector @@ plainto_tsquery('english', search_query)
|
|
279
279
|
ORDER BY ts_rank(f.search_vector, plainto_tsquery('english', search_query)) DESC LIMIT match_count);
|
|
280
280
|
END; $$;`,
|
|
281
|
+
// Usage records unique constraint (required by increment_usage)
|
|
282
|
+
`ALTER TABLE usage_records ADD CONSTRAINT IF NOT EXISTS usage_records_tenant_period_unique UNIQUE (tenant_id, period_start);`,
|
|
283
|
+
// Extraction hash unique index
|
|
284
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS idx_extractions_hash ON extractions(tenant_id, input_hash);`,
|
|
285
|
+
// match_facts RPC
|
|
286
|
+
`CREATE OR REPLACE FUNCTION match_facts(
|
|
287
|
+
query_embedding TEXT, match_tenant_id UUID, match_scope TEXT,
|
|
288
|
+
match_scope_id TEXT, match_count INT, min_similarity FLOAT DEFAULT 0,
|
|
289
|
+
match_as_of TIMESTAMPTZ DEFAULT NULL
|
|
290
|
+
) RETURNS TABLE (
|
|
291
|
+
id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
292
|
+
content TEXT, embedding_model TEXT, embedding_dim INT, version INT,
|
|
293
|
+
lineage_id UUID, valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ,
|
|
294
|
+
operation TEXT, parent_id UUID, importance NUMERIC, frequency INT,
|
|
295
|
+
last_accessed TIMESTAMPTZ, decay_score NUMERIC, contradiction_status TEXT,
|
|
296
|
+
contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
297
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT,
|
|
298
|
+
modality TEXT, tags TEXT[], metadata JSONB,
|
|
299
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT,
|
|
300
|
+
created_at TIMESTAMPTZ, similarity FLOAT
|
|
301
|
+
) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT
|
|
302
|
+
f.id, f.tenant_id, f.scope, f.scope_id, f.session_id,
|
|
303
|
+
f.content, f.embedding_model, f.embedding_dim, f.version, f.lineage_id,
|
|
304
|
+
f.valid_from, f.valid_until, f.operation, f.parent_id, f.importance, f.frequency,
|
|
305
|
+
f.last_accessed, f.decay_score, f.contradiction_status, f.contradicts_id,
|
|
306
|
+
f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id,
|
|
307
|
+
f.extraction_tier, f.modality, f.tags, f.metadata,
|
|
308
|
+
f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
309
|
+
(1 - (f.embedding <=> query_embedding::vector)) AS similarity
|
|
310
|
+
FROM facts f WHERE f.tenant_id = match_tenant_id AND f.scope = match_scope
|
|
311
|
+
AND f.scope_id = match_scope_id
|
|
312
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN f.valid_from <= match_as_of AND (f.valid_until IS NULL OR f.valid_until > match_as_of) ELSE f.valid_until IS NULL END)
|
|
313
|
+
AND (1 - (f.embedding <=> query_embedding::vector)) >= min_similarity
|
|
314
|
+
ORDER BY f.embedding <=> query_embedding::vector LIMIT match_count; END; $$;`,
|
|
315
|
+
// increment_usage RPC
|
|
316
|
+
`CREATE OR REPLACE FUNCTION increment_usage(p_tenant_id UUID, p_tokens INT, p_queries INT, p_extractions INT, p_cost_usd FLOAT)
|
|
317
|
+
RETURNS VOID LANGUAGE plpgsql AS $$ DECLARE p_start DATE := date_trunc('month', CURRENT_DATE)::date;
|
|
318
|
+
p_end DATE := (date_trunc('month', CURRENT_DATE) + interval '1 month' - interval '1 day')::date;
|
|
319
|
+
BEGIN INSERT INTO usage_records (id, tenant_id, period_start, period_end, tokens_used, queries_used, extractions_count, cost_usd)
|
|
320
|
+
VALUES (gen_random_uuid(), p_tenant_id, p_start, p_end, p_tokens, p_queries, p_extractions, p_cost_usd)
|
|
321
|
+
ON CONFLICT (tenant_id, period_start) DO UPDATE SET
|
|
322
|
+
tokens_used = usage_records.tokens_used + EXCLUDED.tokens_used,
|
|
323
|
+
queries_used = usage_records.queries_used + EXCLUDED.queries_used,
|
|
324
|
+
extractions_count = usage_records.extractions_count + EXCLUDED.extractions_count,
|
|
325
|
+
cost_usd = usage_records.cost_usd + EXCLUDED.cost_usd, updated_at = NOW(); END; $$;`,
|
|
326
|
+
// match_entities RPC
|
|
327
|
+
`CREATE OR REPLACE FUNCTION match_entities(query_embedding TEXT, match_tenant_id UUID, match_count INT DEFAULT 10, min_similarity FLOAT DEFAULT 0.3)
|
|
328
|
+
RETURNS TABLE (id UUID, tenant_id UUID, name TEXT, entity_type TEXT, canonical_name TEXT, properties JSONB,
|
|
329
|
+
embedding_model TEXT, embedding_dim INT, merge_target_id UUID, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, similarity FLOAT)
|
|
330
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT e.id, e.tenant_id, e.name, e.entity_type, e.canonical_name,
|
|
331
|
+
e.properties, e.embedding_model, e.embedding_dim, e.merge_target_id, e.created_at, e.updated_at,
|
|
332
|
+
(1 - (e.embedding <=> query_embedding::vector))::float AS similarity
|
|
333
|
+
FROM entities e WHERE e.tenant_id = match_tenant_id AND e.embedding IS NOT NULL
|
|
334
|
+
AND (1 - (e.embedding <=> query_embedding::vector)) >= min_similarity
|
|
335
|
+
ORDER BY e.embedding <=> query_embedding::vector LIMIT match_count; END; $$;`,
|
|
336
|
+
// graph_traverse RPC
|
|
337
|
+
`CREATE OR REPLACE FUNCTION graph_traverse(match_tenant_id UUID, seed_entity_ids UUID[], max_depth INT DEFAULT 3, max_entities INT DEFAULT 200, match_as_of TIMESTAMPTZ DEFAULT NULL)
|
|
338
|
+
RETURNS TABLE (entity_id UUID, entity_name TEXT, entity_type TEXT, canonical_name TEXT, properties JSONB, hop_depth INT,
|
|
339
|
+
edge_id UUID, edge_source_id UUID, edge_target_id UUID, edge_relation TEXT, edge_type TEXT, edge_weight FLOAT,
|
|
340
|
+
edge_valid_from TIMESTAMPTZ, edge_valid_until TIMESTAMPTZ, edge_confidence FLOAT)
|
|
341
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY WITH RECURSIVE traversal AS (
|
|
342
|
+
SELECT e.id AS entity_id, e.name AS entity_name, e.entity_type, e.canonical_name, e.properties, 0 AS hop_depth,
|
|
343
|
+
NULL::UUID AS edge_id, NULL::UUID AS edge_source_id, NULL::UUID AS edge_target_id, NULL::TEXT AS edge_relation,
|
|
344
|
+
NULL::TEXT AS edge_type, NULL::FLOAT AS edge_weight, NULL::TIMESTAMPTZ AS edge_valid_from,
|
|
345
|
+
NULL::TIMESTAMPTZ AS edge_valid_until, NULL::FLOAT AS edge_confidence, ARRAY[e.id] AS visited_ids
|
|
346
|
+
FROM entities e WHERE e.id = ANY(seed_entity_ids) AND e.tenant_id = match_tenant_id
|
|
347
|
+
UNION ALL
|
|
348
|
+
SELECT e2.id, e2.name, e2.entity_type, e2.canonical_name, e2.properties, t.hop_depth + 1,
|
|
349
|
+
ed.id, ed.source_id, ed.target_id, ed.relation, ed.edge_type, ed.weight, ed.valid_from, ed.valid_until, ed.confidence,
|
|
350
|
+
t.visited_ids || e2.id
|
|
351
|
+
FROM traversal t JOIN edges ed ON (ed.source_id = t.entity_id OR ed.target_id = t.entity_id) AND ed.tenant_id = match_tenant_id
|
|
352
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN ed.valid_from <= match_as_of AND (ed.valid_until IS NULL OR ed.valid_until > match_as_of) ELSE ed.valid_until IS NULL END)
|
|
353
|
+
JOIN entities e2 ON e2.id = CASE WHEN ed.source_id = t.entity_id THEN ed.target_id ELSE ed.source_id END AND e2.tenant_id = match_tenant_id
|
|
354
|
+
WHERE t.hop_depth < max_depth AND e2.id != ALL(t.visited_ids)
|
|
355
|
+
) SELECT traversal.entity_id, traversal.entity_name, traversal.entity_type, traversal.canonical_name, traversal.properties,
|
|
356
|
+
traversal.hop_depth, traversal.edge_id, traversal.edge_source_id, traversal.edge_target_id, traversal.edge_relation,
|
|
357
|
+
traversal.edge_type, traversal.edge_weight, traversal.edge_valid_from, traversal.edge_valid_until, traversal.edge_confidence
|
|
358
|
+
FROM traversal LIMIT max_entities; END; $$;`,
|
|
359
|
+
// get_facts_for_entities RPC
|
|
360
|
+
`CREATE OR REPLACE FUNCTION get_facts_for_entities(match_tenant_id UUID, entity_ids UUID[], per_entity_limit INT DEFAULT 20)
|
|
361
|
+
RETURNS TABLE (entity_id UUID, fact_id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
362
|
+
content TEXT, embedding_model TEXT, embedding_dim INTEGER, version INTEGER, lineage_id UUID,
|
|
363
|
+
valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ, operation TEXT, parent_id UUID,
|
|
364
|
+
importance NUMERIC, frequency INTEGER, last_accessed TIMESTAMPTZ, decay_score NUMERIC,
|
|
365
|
+
contradiction_status TEXT, contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
366
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT, modality TEXT, tags TEXT[], metadata JSONB,
|
|
367
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT, created_at TIMESTAMPTZ)
|
|
368
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT ranked.entity_id, ranked.fact_id, ranked.tenant_id, ranked.scope,
|
|
369
|
+
ranked.scope_id, ranked.session_id, ranked.content, ranked.embedding_model, ranked.embedding_dim, ranked.version,
|
|
370
|
+
ranked.lineage_id, ranked.valid_from, ranked.valid_until, ranked.operation, ranked.parent_id, ranked.importance,
|
|
371
|
+
ranked.frequency, ranked.last_accessed, ranked.decay_score, ranked.contradiction_status, ranked.contradicts_id,
|
|
372
|
+
ranked.source_type, ranked.source_ref, ranked.confidence, ranked.original_content, ranked.extraction_id,
|
|
373
|
+
ranked.extraction_tier, ranked.modality, ranked.tags, ranked.metadata,
|
|
374
|
+
ranked.event_date, ranked.document_date, ranked.source_chunk, ranked.created_at
|
|
375
|
+
FROM (SELECT fe.entity_id, f.id AS fact_id, f.tenant_id, f.scope, f.scope_id, f.session_id, f.content,
|
|
376
|
+
f.embedding_model, f.embedding_dim, f.version, f.lineage_id, f.valid_from, f.valid_until, f.operation,
|
|
377
|
+
f.parent_id, f.importance, f.frequency, f.last_accessed, f.decay_score, f.contradiction_status, f.contradicts_id,
|
|
378
|
+
f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id, f.extraction_tier, f.modality,
|
|
379
|
+
f.tags, f.metadata, f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
380
|
+
ROW_NUMBER() OVER (PARTITION BY fe.entity_id ORDER BY f.importance DESC, f.created_at DESC) AS rn
|
|
381
|
+
FROM fact_entities fe JOIN facts f ON f.id = fe.fact_id WHERE fe.entity_id = ANY(entity_ids)
|
|
382
|
+
AND f.tenant_id = match_tenant_id AND f.valid_until IS NULL AND NOT ('raw_chunk' = ANY(f.tags))) ranked
|
|
383
|
+
WHERE ranked.rn <= per_entity_limit; END; $$;`,
|
|
384
|
+
// keyword_search_facts RPC
|
|
385
|
+
`CREATE OR REPLACE FUNCTION keyword_search_facts(search_query TEXT, match_tenant_id UUID, match_scope TEXT,
|
|
386
|
+
match_scope_id TEXT, match_count INT, match_as_of TIMESTAMPTZ DEFAULT NULL)
|
|
387
|
+
RETURNS TABLE (id UUID, tenant_id UUID, scope TEXT, scope_id TEXT, session_id TEXT,
|
|
388
|
+
content TEXT, embedding_model TEXT, embedding_dim INT, version INT, lineage_id UUID,
|
|
389
|
+
valid_from TIMESTAMPTZ, valid_until TIMESTAMPTZ, operation TEXT, parent_id UUID,
|
|
390
|
+
importance NUMERIC, frequency INT, last_accessed TIMESTAMPTZ, decay_score NUMERIC,
|
|
391
|
+
contradiction_status TEXT, contradicts_id UUID, source_type TEXT, source_ref JSONB, confidence NUMERIC,
|
|
392
|
+
original_content TEXT, extraction_id UUID, extraction_tier TEXT, modality TEXT, tags TEXT[], metadata JSONB,
|
|
393
|
+
event_date TIMESTAMPTZ, document_date TIMESTAMPTZ, source_chunk TEXT, created_at TIMESTAMPTZ, rank_score FLOAT)
|
|
394
|
+
LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT f.id, f.tenant_id, f.scope, f.scope_id, f.session_id,
|
|
395
|
+
f.content, f.embedding_model, f.embedding_dim, f.version, f.lineage_id, f.valid_from, f.valid_until,
|
|
396
|
+
f.operation, f.parent_id, f.importance, f.frequency, f.last_accessed, f.decay_score, f.contradiction_status,
|
|
397
|
+
f.contradicts_id, f.source_type, f.source_ref, f.confidence, f.original_content, f.extraction_id,
|
|
398
|
+
f.extraction_tier, f.modality, f.tags, f.metadata, f.event_date, f.document_date, f.source_chunk, f.created_at,
|
|
399
|
+
ts_rank(f.search_vector, plainto_tsquery('english', search_query)) AS rank_score
|
|
400
|
+
FROM facts f WHERE f.tenant_id = match_tenant_id AND f.scope = match_scope AND f.scope_id = match_scope_id
|
|
401
|
+
AND (CASE WHEN match_as_of IS NOT NULL THEN f.valid_from <= match_as_of AND (f.valid_until IS NULL OR f.valid_until > match_as_of) ELSE f.valid_until IS NULL END)
|
|
402
|
+
AND f.search_vector @@ plainto_tsquery('english', search_query)
|
|
403
|
+
ORDER BY rank_score DESC LIMIT match_count; END; $$;`,
|
|
404
|
+
// increment_trigger_fired RPC
|
|
405
|
+
`CREATE OR REPLACE FUNCTION increment_trigger_fired(p_tenant_id UUID, p_trigger_id UUID)
|
|
406
|
+
RETURNS VOID LANGUAGE plpgsql AS $$ BEGIN UPDATE triggers SET times_fired = times_fired + 1,
|
|
407
|
+
last_fired_at = NOW(), updated_at = NOW() WHERE tenant_id = p_tenant_id AND id = p_trigger_id; END; $$;`,
|
|
281
408
|
// Default tenant
|
|
282
409
|
`INSERT INTO tenants (id, name, slug, plan) VALUES ('00000000-0000-0000-0000-000000000001', 'Default', 'default', 'enterprise') ON CONFLICT DO NOTHING;`,
|
|
283
410
|
];
|
|
@@ -300,27 +427,39 @@ async function main() {
|
|
|
300
427
|
console.log('\n Running database migrations...');
|
|
301
428
|
const supabase = createClient(supabaseUrl, supabaseKey);
|
|
302
429
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
} catch {
|
|
320
|
-
skipped++;
|
|
430
|
+
// Try running migrations via Supabase Management API (requires service role key)
|
|
431
|
+
// If that fails, write SQL to a file for manual execution
|
|
432
|
+
const allSql = MIGRATIONS.join('\n\n');
|
|
433
|
+
const sqlPath = path.join(process.cwd(), 'steno-migrations.sql');
|
|
434
|
+
|
|
435
|
+
// Attempt automatic migration via Supabase SQL endpoint
|
|
436
|
+
let autoMigrated = false;
|
|
437
|
+
try {
|
|
438
|
+
const res = await fetch(`${supabaseUrl}/rest/v1/rpc/exec_sql`, {
|
|
439
|
+
method: 'POST',
|
|
440
|
+
headers: { 'apikey': supabaseKey, 'Authorization': `Bearer ${supabaseKey}`, 'Content-Type': 'application/json' },
|
|
441
|
+
body: JSON.stringify({ query: allSql }),
|
|
442
|
+
});
|
|
443
|
+
if (res.ok) {
|
|
444
|
+
autoMigrated = true;
|
|
445
|
+
console.log(' ✓ All migrations applied automatically');
|
|
321
446
|
}
|
|
447
|
+
} catch { /* RPC not available */ }
|
|
448
|
+
|
|
449
|
+
if (!autoMigrated) {
|
|
450
|
+
// Write SQL file for manual execution
|
|
451
|
+
fs.writeFileSync(sqlPath, allSql);
|
|
452
|
+
console.log(`
|
|
453
|
+
⚠️ Could not run migrations automatically.
|
|
454
|
+
|
|
455
|
+
Please run the SQL manually:
|
|
456
|
+
1. Open your Supabase dashboard → SQL Editor
|
|
457
|
+
2. Paste the contents of: ${sqlPath}
|
|
458
|
+
3. Click "Run"
|
|
459
|
+
4. Come back here and press Enter to continue
|
|
460
|
+
`);
|
|
461
|
+
await ask(' Press Enter after running the SQL... ');
|
|
322
462
|
}
|
|
323
|
-
console.log(` ✓ ${success} migrations applied, ${skipped} skipped (may already exist)`);
|
|
324
463
|
|
|
325
464
|
// 3. Write Claude Desktop config
|
|
326
465
|
const configDir = path.join(os.homedir(), 'Library', 'Application Support', 'Claude');
|
package/src/local-server.ts
CHANGED
|
@@ -70,6 +70,15 @@ export function createLocalServer(config: LocalServerConfig): McpServer {
|
|
|
70
70
|
const server = new McpServer({
|
|
71
71
|
name: 'steno-local',
|
|
72
72
|
version: '0.1.0',
|
|
73
|
+
...({ instructions: `You have access to the user's persistent long-term memory via Steno.
|
|
74
|
+
|
|
75
|
+
CRITICAL RULES:
|
|
76
|
+
1. ALWAYS call steno_recall BEFORE answering ANY question about the user, their life, work, projects, people they know, preferences, past events, companies, or decisions.
|
|
77
|
+
2. When the user shares personal information, call steno_remember to store it, then ALWAYS call steno_flush immediately after to ensure extraction happens now.
|
|
78
|
+
3. Before context compaction or session end, call steno_remember with a summary of key decisions and progress, then steno_flush.
|
|
79
|
+
4. Never say "I don't have information about that" without first checking steno_recall.
|
|
80
|
+
5. Steno memory persists across ALL conversations — it knows things from past sessions that your conversation history does not.
|
|
81
|
+
6. Use steno_update_status to change priority/roadmap item status when the user starts, completes, or gets blocked on a task.` } as any),
|
|
73
82
|
});
|
|
74
83
|
|
|
75
84
|
// Lazy import to avoid loading heavy modules at startup
|
|
@@ -291,24 +300,182 @@ export function createLocalServer(config: LocalServerConfig): McpServer {
|
|
|
291
300
|
return { content: [{ type: 'text' as const, text: 'No memories found.' }] };
|
|
292
301
|
}
|
|
293
302
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
303
|
+
// Build priority label map: factId → "Priority #N (short name)"
|
|
304
|
+
// Query ALL facts with priority_order metadata — not just the ones in results
|
|
305
|
+
// This ensures labels resolve even for facts referenced by edges but not in recall
|
|
306
|
+
const priorityLabels = new Map<string, string>();
|
|
307
|
+
try {
|
|
308
|
+
const { data: allPriorityFacts } = await (config.storage as any).client
|
|
309
|
+
.from('facts')
|
|
310
|
+
.select('id, content, metadata')
|
|
311
|
+
.eq('tenant_id', config.tenantId)
|
|
312
|
+
.not('metadata->priority_order', 'is', null);
|
|
313
|
+
if (allPriorityFacts) {
|
|
314
|
+
for (const f of allPriorityFacts) {
|
|
315
|
+
const order = f.metadata?.priority_order;
|
|
316
|
+
if (order) {
|
|
317
|
+
const shortName = f.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants|Steno)\s+/i, '').slice(0, 35).replace(/\s+\S*$/, '');
|
|
318
|
+
priorityLabels.set(f.id, `Priority #${order} (${shortName})`);
|
|
319
|
+
}
|
|
307
320
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
321
|
+
}
|
|
322
|
+
} catch { /* fallback to results-only labels */ }
|
|
323
|
+
// Also add labels from results (in case metadata query missed any)
|
|
324
|
+
for (const r of results.results) {
|
|
325
|
+
if (priorityLabels.has(r.fact.id)) continue;
|
|
326
|
+
const meta = r.fact.metadata as Record<string, unknown> | undefined;
|
|
327
|
+
const order = meta?.priority_order as number | undefined;
|
|
328
|
+
if (order) {
|
|
329
|
+
const shortName = r.fact.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants)\s+/i, '').slice(0, 35).replace(/\s+\S*$/, '');
|
|
330
|
+
priorityLabels.set(r.fact.id, `Priority #${order} (${shortName})`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Build dependency map — ONE batch query for ALL dependency edges in this tenant
|
|
335
|
+
const factIds = results.results.map(r => r.fact.id);
|
|
336
|
+
const depMap = new Map<string, { blocks: string[]; blockedBy: string[]; deadlines: string[] }>();
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
// Query ALL precedes/depends_on/deadline edges — not just for these fact_ids
|
|
340
|
+
// because edges reference sourceFactId/targetFactId in metadata, not in fact_id column
|
|
341
|
+
const { data: depEdges } = await (config.storage as any).client
|
|
342
|
+
.from('edges')
|
|
343
|
+
.select('relation, fact_id, metadata')
|
|
344
|
+
.eq('tenant_id', config.tenantId)
|
|
345
|
+
.in('relation', ['precedes', 'depends_on', 'deadline']);
|
|
346
|
+
|
|
347
|
+
if (depEdges) {
|
|
348
|
+
for (const edge of depEdges) {
|
|
349
|
+
const edgeMeta = edge.metadata as Record<string, unknown> | undefined;
|
|
350
|
+
const sourceFactId = (edgeMeta?.sourceFactId as string) || edge.fact_id;
|
|
351
|
+
const targetFactId = edgeMeta?.targetFactId as string | undefined;
|
|
352
|
+
|
|
353
|
+
// Only process edges involving facts in our result set
|
|
354
|
+
const sourceInResults = factIds.includes(sourceFactId);
|
|
355
|
+
const targetInResults = targetFactId ? factIds.includes(targetFactId) : false;
|
|
356
|
+
if (!sourceInResults && !targetInResults) continue;
|
|
357
|
+
|
|
358
|
+
if (!depMap.has(sourceFactId)) depMap.set(sourceFactId, { blocks: [], blockedBy: [], deadlines: [] });
|
|
359
|
+
|
|
360
|
+
if (edge.relation === 'precedes' && targetFactId) {
|
|
361
|
+
const label = priorityLabels.get(targetFactId) || 'another priority';
|
|
362
|
+
depMap.get(sourceFactId)!.blocks.push(label);
|
|
363
|
+
}
|
|
364
|
+
if (edge.relation === 'depends_on' && targetFactId) {
|
|
365
|
+
const label = priorityLabels.get(targetFactId) || 'another priority';
|
|
366
|
+
depMap.get(sourceFactId)!.blockedBy.push(label);
|
|
367
|
+
}
|
|
368
|
+
if (edge.relation === 'deadline') {
|
|
369
|
+
const deadline = edgeMeta?.deadline as string | undefined;
|
|
370
|
+
if (deadline) {
|
|
371
|
+
depMap.get(sourceFactId)!.deadlines.push(deadline);
|
|
372
|
+
// Cascade deadline upstream: if X blocks Y and Y has deadline, X gets it too
|
|
373
|
+
for (const [fid, deps2] of depMap) {
|
|
374
|
+
if (deps2.blocks.some(b => b.includes(sourceFactId.slice(0, 8)) || priorityLabels.get(sourceFactId)?.includes(b.split('(')[1]?.slice(0, 10) || ''))) {
|
|
375
|
+
if (!deps2.deadlines.includes(deadline)) deps2.deadlines.push(deadline + ' (cascaded)');
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Second pass: cascade deadlines through depends_on chain
|
|
383
|
+
// If A depends_on B, and B has a deadline, A implicitly has that deadline
|
|
384
|
+
for (const [factId, deps] of depMap) {
|
|
385
|
+
if (deps.deadlines.length === 0) {
|
|
386
|
+
// Check if anything this blocks has a deadline
|
|
387
|
+
for (const blockLabel of deps.blocks) {
|
|
388
|
+
for (const [otherId, otherDeps] of depMap) {
|
|
389
|
+
if (priorityLabels.get(otherId) === blockLabel && otherDeps.deadlines.length > 0) {
|
|
390
|
+
for (const dl of otherDeps.deadlines) {
|
|
391
|
+
if (!dl.includes('cascaded') && !deps.deadlines.includes(dl)) {
|
|
392
|
+
deps.deadlines.push(dl + ' (implicit — blocks deadline item)');
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
} catch { /* batch edge lookup failed */ }
|
|
402
|
+
|
|
403
|
+
// Inject missing priority facts that are referenced by edges but not in recall results
|
|
404
|
+
// This ensures Priority #1 (root node) always shows up when its children are recalled
|
|
405
|
+
const resultFactIds = new Set(results.results.map(r => r.fact.id));
|
|
406
|
+
try {
|
|
407
|
+
const { data: allPriorities } = await (config.storage as any).client
|
|
408
|
+
.from('facts')
|
|
409
|
+
.select('*')
|
|
410
|
+
.eq('tenant_id', config.tenantId)
|
|
411
|
+
.not('metadata->priority_order', 'is', null);
|
|
412
|
+
if (allPriorities) {
|
|
413
|
+
for (const pf of allPriorities) {
|
|
414
|
+
if (!resultFactIds.has(pf.id) && (depMap.has(pf.id) || priorityLabels.has(pf.id))) {
|
|
415
|
+
// This priority is referenced but not in results — inject it
|
|
416
|
+
const camelFact = Object.fromEntries(
|
|
417
|
+
Object.entries(pf).map(([k, v]) => [k.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase()), v])
|
|
418
|
+
);
|
|
419
|
+
results.results.push({
|
|
420
|
+
fact: camelFact as any,
|
|
421
|
+
score: 0.1, // Low score since it wasn't directly matched
|
|
422
|
+
signals: { vectorScore: 0, keywordScore: 0, graphScore: 0.5, recencyScore: 0, salienceScore: 0, temporalScore: 0 },
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
} catch { /* injection failed */ }
|
|
428
|
+
|
|
429
|
+
// Sort results: priorities first (by priority_order), then regular memories
|
|
430
|
+
const sortedResults = [...results.results].sort((a, b) => {
|
|
431
|
+
const aOrder = (a.fact.metadata as any)?.priority_order as number | undefined;
|
|
432
|
+
const bOrder = (b.fact.metadata as any)?.priority_order as number | undefined;
|
|
433
|
+
if (aOrder && bOrder) return aOrder - bOrder;
|
|
434
|
+
if (aOrder) return -1;
|
|
435
|
+
if (bOrder) return 1;
|
|
436
|
+
return b.score - a.score;
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
const enrichedLines: string[] = [];
|
|
440
|
+
for (const r of sortedResults) {
|
|
441
|
+
const meta = r.fact.metadata as Record<string, unknown> | undefined;
|
|
442
|
+
const status = meta?.status as string | undefined;
|
|
443
|
+
const priorityOrder = meta?.priority_order as number | undefined;
|
|
444
|
+
const deps = depMap.get(r.fact.id);
|
|
445
|
+
|
|
446
|
+
const dateParts: string[] = [];
|
|
447
|
+
if (r.fact.eventDate) dateParts.push(`event: ${new Date(r.fact.eventDate).toISOString().slice(0, 10)}`);
|
|
448
|
+
if (r.fact.documentDate) dateParts.push(`doc: ${new Date(r.fact.documentDate).toISOString().slice(0, 10)}`);
|
|
449
|
+
const dateStr = dateParts.length > 0 ? `, ${dateParts.join(', ')}` : '';
|
|
450
|
+
const signals = Object.entries(r.signals)
|
|
451
|
+
.filter(([, v]) => v > 0)
|
|
452
|
+
.map(([k, v]) => `${k.replace('Score', '')}=${(v as number).toFixed(2)}`)
|
|
453
|
+
.join(', ');
|
|
454
|
+
|
|
455
|
+
const isPriority = status || priorityOrder;
|
|
456
|
+
const blocks = deps?.blocks ?? [];
|
|
457
|
+
const blockedBy = deps?.blockedBy ?? [];
|
|
458
|
+
const deadlines = deps?.deadlines ?? [];
|
|
459
|
+
let line: string;
|
|
460
|
+
if (isPriority) {
|
|
461
|
+
line = `[Priority${priorityOrder ? ` #${priorityOrder}` : ''}] ${r.fact.content}`;
|
|
462
|
+
line += `\n status: ${status || 'unknown'}`;
|
|
463
|
+
if (blocks.length > 0) line += `\n blocks: → ${blocks.join(', ')}`;
|
|
464
|
+
if (blockedBy.length > 0) line += `\n blocked_by: ← ${blockedBy.join(', ')}`;
|
|
465
|
+
else if (status === 'not_started') line += `\n blocked_by: none`;
|
|
466
|
+
if (deadlines.length > 0) line += `\n deadline: ${deadlines.join(', ')}`;
|
|
467
|
+
line += `\n (score: ${r.score.toFixed(2)}${dateStr})`;
|
|
468
|
+
} else {
|
|
469
|
+
line = `[Memory] ${r.fact.content} (score: ${r.score.toFixed(2)}${dateStr}${signals ? `, ${signals}` : ''})`;
|
|
470
|
+
}
|
|
471
|
+
if (r.fact.sourceChunk && !isPriority) {
|
|
472
|
+
line += `\n[Source Context] ${r.fact.sourceChunk}`;
|
|
473
|
+
}
|
|
474
|
+
line += '\n---';
|
|
475
|
+
enrichedLines.push(line);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const text = enrichedLines.join('\n');
|
|
312
479
|
|
|
313
480
|
return {
|
|
314
481
|
content: [
|
|
@@ -346,6 +513,54 @@ export function createLocalServer(config: LocalServerConfig): McpServer {
|
|
|
346
513
|
},
|
|
347
514
|
);
|
|
348
515
|
|
|
516
|
+
// ─── UPDATE STATUS ───
|
|
517
|
+
server.tool(
|
|
518
|
+
'steno_update_status',
|
|
519
|
+
'Update the status of a priority/roadmap item. Use when a task changes state (e.g., started working on it, completed it, or it became blocked).',
|
|
520
|
+
{
|
|
521
|
+
priority: z.number().describe('Priority number (1-6)'),
|
|
522
|
+
status: z.enum(['not_started', 'in_progress', 'done', 'blocked']).describe('New status'),
|
|
523
|
+
},
|
|
524
|
+
async ({ priority, status }) => {
|
|
525
|
+
try {
|
|
526
|
+
// Find the fact with this priority_order
|
|
527
|
+
const { data: facts, error: findError } = await (config.storage as any).client
|
|
528
|
+
.from('facts')
|
|
529
|
+
.select('id, content, metadata')
|
|
530
|
+
.eq('tenant_id', config.tenantId)
|
|
531
|
+
.not('metadata->priority_order', 'is', null);
|
|
532
|
+
|
|
533
|
+
if (findError) throw findError;
|
|
534
|
+
|
|
535
|
+
const fact = facts?.find((f: any) => f.metadata?.priority_order === priority);
|
|
536
|
+
if (!fact) {
|
|
537
|
+
return { content: [{ type: 'text' as const, text: `No priority #${priority} found.` }] };
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const oldStatus = fact.metadata?.status || 'unknown';
|
|
541
|
+
const newMetadata = { ...fact.metadata, status };
|
|
542
|
+
|
|
543
|
+
const { error: updateError } = await (config.storage as any).client
|
|
544
|
+
.from('facts')
|
|
545
|
+
.update({ metadata: newMetadata })
|
|
546
|
+
.eq('id', fact.id)
|
|
547
|
+
.eq('tenant_id', config.tenantId);
|
|
548
|
+
|
|
549
|
+
if (updateError) throw updateError;
|
|
550
|
+
|
|
551
|
+
const shortName = fact.content.replace(/^User('s)?\s+(plans|added|believes|is planning|wants|Steno)\s+/i, '').slice(0, 50);
|
|
552
|
+
return {
|
|
553
|
+
content: [{
|
|
554
|
+
type: 'text' as const,
|
|
555
|
+
text: `Priority #${priority} (${shortName}): ${oldStatus} → ${status}`,
|
|
556
|
+
}],
|
|
557
|
+
};
|
|
558
|
+
} catch (err: any) {
|
|
559
|
+
return { content: [{ type: 'text' as const, text: `Error updating status: ${err?.message ?? err}` }] };
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
);
|
|
563
|
+
|
|
349
564
|
// ─── STATS ───
|
|
350
565
|
server.tool(
|
|
351
566
|
'steno_stats',
|
package/src/local.ts
CHANGED
|
File without changes
|
package/src/server.ts
CHANGED
|
File without changes
|