@cachly-dev/mcp-server 0.7.0 → 0.8.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/dist/index.js +122 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +175 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cachly-dev/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"mcpName": "io.github.cachly-dev/mcp-server",
|
|
5
5
|
"description": "AI memory brain for Claude Code, Cursor, Copilot & Windsurf — persistent sessions, lessons learned, semantic search, team brain. 51 MCP tools.",
|
|
6
6
|
"type": "module",
|
package/src/index.ts
CHANGED
|
@@ -55,7 +55,7 @@ import { Redis } from 'ioredis';
|
|
|
55
55
|
const API_URL = process.env.CACHLY_API_URL ?? 'https://api.cachly.dev';
|
|
56
56
|
const JWT = process.env.CACHLY_JWT ?? '';
|
|
57
57
|
const EMBED_MODEL = process.env.CACHLY_EMBED_MODEL ?? '';
|
|
58
|
-
const CURRENT_VERSION = '0.
|
|
58
|
+
const CURRENT_VERSION = '0.8.0';
|
|
59
59
|
/**
|
|
60
60
|
* ┌──────────────────────────────────────────────────────────────────────┐
|
|
61
61
|
* │ EMBEDDING PROVIDER — pluggable, client-side first │
|
|
@@ -3494,7 +3494,8 @@ const TOOLS = [
|
|
|
3494
3494
|
'The lesson is immediately searchable by any other AI using syndicate_search. ' +
|
|
3495
3495
|
'This is how individual knowledge becomes collective intelligence. ' +
|
|
3496
3496
|
'Call this AFTER every learn_from_attempts that is worth sharing universally ' +
|
|
3497
|
-
'(critical bugs, deployment gotchas, architecture discoveries).'
|
|
3497
|
+
'(critical bugs, deployment gotchas, architecture discoveries). ' +
|
|
3498
|
+
'Use scope="org" to keep the lesson private to your organisation.',
|
|
3498
3499
|
inputSchema: {
|
|
3499
3500
|
type: 'object',
|
|
3500
3501
|
properties: {
|
|
@@ -3504,6 +3505,7 @@ const TOOLS = [
|
|
|
3504
3505
|
what_failed: { type: 'string', description: 'What failed or was wrong — helps others avoid the same trap.' },
|
|
3505
3506
|
severity: { type: 'string', enum: ['critical', 'major', 'minor'], description: 'How severe the issue was (default: minor)' },
|
|
3506
3507
|
tags: { type: 'array', items: { type: 'string' }, description: 'Up to 10 keywords for better discoverability' },
|
|
3508
|
+
scope: { type: 'string', enum: ['public', 'org'], description: 'Visibility: "public" = global commons (default), "org" = private to your org only' },
|
|
3507
3509
|
},
|
|
3508
3510
|
required: ['topic', 'what_worked'],
|
|
3509
3511
|
},
|
|
@@ -3519,8 +3521,37 @@ const TOOLS = [
|
|
|
3519
3521
|
inputSchema: {
|
|
3520
3522
|
type: 'object',
|
|
3521
3523
|
properties: {
|
|
3522
|
-
q:
|
|
3523
|
-
|
|
3524
|
+
q: { type: 'string', description: 'Free-text search query (leave empty for most recent lessons)' },
|
|
3525
|
+
category: { type: 'string', description: 'Filter by category prefix: "fix", "deploy", "debug", "infra", "api", "web"' },
|
|
3526
|
+
scope: { type: 'string', enum: ['public', 'org'], description: '"public" = global commons (default), "org" = public + your org-private lessons' },
|
|
3527
|
+
limit: { type: 'number', description: 'Max results to return (default: 20, max: 50)' },
|
|
3528
|
+
},
|
|
3529
|
+
required: [],
|
|
3530
|
+
},
|
|
3531
|
+
},
|
|
3532
|
+
{
|
|
3533
|
+
name: 'syndicate_stats',
|
|
3534
|
+
description:
|
|
3535
|
+
'Show the health of the global Knowledge Commons: total lessons, total confirms, ' +
|
|
3536
|
+
'top categories, most-trusted lessons, growth in the last 7 days, and top contributors (anonymous scores). ' +
|
|
3537
|
+
'Use for weekly reviews or to explore what the community knows.',
|
|
3538
|
+
inputSchema: {
|
|
3539
|
+
type: 'object',
|
|
3540
|
+
properties: {},
|
|
3541
|
+
required: [],
|
|
3542
|
+
},
|
|
3543
|
+
},
|
|
3544
|
+
{
|
|
3545
|
+
name: 'syndicate_trending',
|
|
3546
|
+
description:
|
|
3547
|
+
'Show the TRENDING lessons in the global Knowledge Commons — those with the fastest confirmation velocity ' +
|
|
3548
|
+
'in the last 7 days (confirm_count / age_in_days). ' +
|
|
3549
|
+
'Use this at the start of a session or weekly review to see what the community is actively validating. ' +
|
|
3550
|
+
'Lessons need at least 2 independent confirms to appear here.',
|
|
3551
|
+
inputSchema: {
|
|
3552
|
+
type: 'object',
|
|
3553
|
+
properties: {
|
|
3554
|
+
limit: { type: 'number', description: 'Max results (default: 10, max: 50)' },
|
|
3524
3555
|
},
|
|
3525
3556
|
required: [],
|
|
3526
3557
|
},
|
|
@@ -7594,28 +7625,35 @@ smart_recall(
|
|
|
7594
7625
|
|
|
7595
7626
|
// ── v0.7 Knowledge Syndication: syndicate ────────────────────────────────
|
|
7596
7627
|
case 'syndicate': {
|
|
7597
|
-
const { topic, outcome = 'success', what_worked, what_failed = '', severity = 'minor', tags = [] } = args as {
|
|
7598
|
-
topic: string; outcome?: string; what_worked: string; what_failed?: string; severity?: string; tags?: string[];
|
|
7628
|
+
const { topic, outcome = 'success', what_worked, what_failed = '', severity = 'minor', tags = [], scope = 'public' } = args as {
|
|
7629
|
+
topic: string; outcome?: string; what_worked: string; what_failed?: string; severity?: string; tags?: string[]; scope?: string;
|
|
7599
7630
|
};
|
|
7600
7631
|
|
|
7601
7632
|
if (!topic || !what_worked) {
|
|
7602
7633
|
throw new McpError(ErrorCode.InvalidParams, 'topic and what_worked are required');
|
|
7603
7634
|
}
|
|
7604
7635
|
|
|
7605
|
-
const body = { topic, outcome, what_worked, what_failed, severity, tags };
|
|
7606
|
-
const res = await apiFetch<{ id: string; topic: string; outcome: string; message: string }>(
|
|
7636
|
+
const body = { topic, outcome, what_worked, what_failed, severity, tags, scope };
|
|
7637
|
+
const res = await apiFetch<{ id: string; topic: string; outcome: string; message: string; deduped?: boolean }>(
|
|
7607
7638
|
'/api/v1/syndication/contribute',
|
|
7608
7639
|
{ method: 'POST', body: JSON.stringify(body) }
|
|
7609
7640
|
);
|
|
7610
7641
|
|
|
7642
|
+
const scopeLabel = scope === 'org' ? '🏢 org-private' : '🌐 global commons';
|
|
7643
|
+
const dedupNote = res.deduped
|
|
7644
|
+
? `\n> ♻️ Duplicate detected — trust score incremented for the existing lesson.`
|
|
7645
|
+
: '';
|
|
7646
|
+
|
|
7611
7647
|
return [
|
|
7612
|
-
|
|
7648
|
+
`${scope === 'org' ? '🏢' : '🌐'} **Lesson syndicated to the ${scope === 'org' ? 'org Knowledge Commons' : 'global Knowledge Commons'}**${dedupNote}`,
|
|
7613
7649
|
``,
|
|
7614
7650
|
`**ID:** \`${res.id}\``,
|
|
7615
|
-
`**Topic:** \`${res.topic}\` · **Outcome:** ${res.outcome}`,
|
|
7651
|
+
`**Topic:** \`${res.topic}\` · **Outcome:** ${res.outcome} · **Scope:** ${scopeLabel}`,
|
|
7616
7652
|
``,
|
|
7617
|
-
|
|
7618
|
-
|
|
7653
|
+
scope === 'org'
|
|
7654
|
+
? `This lesson is visible only within your organisation. Use \`syndicate_search(scope="org")\` to find it.`
|
|
7655
|
+
: `Your lesson is now searchable by every AI brain in the network.`,
|
|
7656
|
+
`When another instance confirms it works, its trust score rises — and so does your contributor reputation.`,
|
|
7619
7657
|
``,
|
|
7620
7658
|
`**Tip:** Use \`syndicate_search(q="${topic}")\` to see all community lessons on this topic.`,
|
|
7621
7659
|
].join('\n');
|
|
@@ -7623,10 +7661,12 @@ smart_recall(
|
|
|
7623
7661
|
|
|
7624
7662
|
// ── v0.7 Knowledge Syndication: syndicate_search ─────────────────────────
|
|
7625
7663
|
case 'syndicate_search': {
|
|
7626
|
-
const { q = '', limit = 20 } = args as { q?: string; limit?: number };
|
|
7664
|
+
const { q = '', limit = 20, category = '', scope = '' } = args as { q?: string; limit?: number; category?: string; scope?: string };
|
|
7627
7665
|
|
|
7628
7666
|
const params = new URLSearchParams();
|
|
7629
7667
|
if (q) params.set('q', q);
|
|
7668
|
+
if (category) params.set('category', category);
|
|
7669
|
+
if (scope) params.set('scope', scope);
|
|
7630
7670
|
params.set('limit', String(Math.min(Math.max(1, limit), 50)));
|
|
7631
7671
|
|
|
7632
7672
|
const res = await apiFetch<{ results: Array<{
|
|
@@ -7648,8 +7688,9 @@ smart_recall(
|
|
|
7648
7688
|
return '█'.repeat(filled) + '░'.repeat(10 - filled) + ` ×${n}`;
|
|
7649
7689
|
};
|
|
7650
7690
|
|
|
7691
|
+
const header = [q, category].filter(Boolean).join(' · ');
|
|
7651
7692
|
const lines: string[] = [
|
|
7652
|
-
`## 🌐 Global Knowledge Commons${
|
|
7693
|
+
`## 🌐 Global Knowledge Commons${header ? ` — ${header}` : ' — Recent'}`,
|
|
7653
7694
|
`*${res.count} lesson${res.count === 1 ? '' : 's'} found*`,
|
|
7654
7695
|
``,
|
|
7655
7696
|
];
|
|
@@ -7660,15 +7701,133 @@ smart_recall(
|
|
|
7660
7701
|
`**Trust:** ${confirmBar(lesson.confirm_count)}`,
|
|
7661
7702
|
lesson.what_worked ? `**What worked:** ${lesson.what_worked}` : '',
|
|
7662
7703
|
lesson.what_failed ? `**What failed:** ${lesson.what_failed}` : '',
|
|
7663
|
-
`*Contributed ${new Date(lesson.created_at).toLocaleDateString('de-DE')}
|
|
7704
|
+
`*Contributed ${new Date(lesson.created_at).toLocaleDateString('de-DE')} · ID: \`${lesson.id}\`*`,
|
|
7664
7705
|
``,
|
|
7665
7706
|
);
|
|
7666
7707
|
}
|
|
7667
7708
|
|
|
7668
7709
|
lines.push(
|
|
7669
7710
|
`---`,
|
|
7670
|
-
`**Confirm
|
|
7711
|
+
`**Confirm** (this helped you): \`syndicate(topic="${res.results[0]?.topic ?? '...'}", what_worked="...")\` → auto-deduped, trust +1`,
|
|
7671
7712
|
`**Contribute your own:** \`syndicate(topic="fix:...", what_worked="...")\``,
|
|
7713
|
+
`**Filter by category:** \`syndicate_search(category="fix")\``,
|
|
7714
|
+
);
|
|
7715
|
+
|
|
7716
|
+
return lines.filter(l => l !== '').join('\n');
|
|
7717
|
+
}
|
|
7718
|
+
|
|
7719
|
+
// ── v0.7 Knowledge Syndication: syndicate_stats ──────────────────────────
|
|
7720
|
+
case 'syndicate_stats': {
|
|
7721
|
+
const res = await apiFetch<{
|
|
7722
|
+
total_lessons: number;
|
|
7723
|
+
total_confirms: number;
|
|
7724
|
+
added_last_7_days: number;
|
|
7725
|
+
top_categories: Array<{ category: string; count: number }>;
|
|
7726
|
+
most_trusted: Array<{
|
|
7727
|
+
id: string; topic: string; outcome: string;
|
|
7728
|
+
what_worked: string; confirm_count: number; created_at: string;
|
|
7729
|
+
}>;
|
|
7730
|
+
}>('/api/v1/syndication/stats');
|
|
7731
|
+
|
|
7732
|
+
const confirmBar = (n: number) => {
|
|
7733
|
+
const filled = Math.min(10, Math.round(n / 5));
|
|
7734
|
+
return '█'.repeat(filled) + '░'.repeat(10 - filled) + ` ×${n}`;
|
|
7735
|
+
};
|
|
7736
|
+
|
|
7737
|
+
const lines: string[] = [
|
|
7738
|
+
`## 🌐 Global Knowledge Commons — Stats`,
|
|
7739
|
+
``,
|
|
7740
|
+
`| Metric | Value |`,
|
|
7741
|
+
`|---|---|`,
|
|
7742
|
+
`| Total lessons | **${res.total_lessons.toLocaleString()}** |`,
|
|
7743
|
+
`| Total confirms | **${res.total_confirms.toLocaleString()}** |`,
|
|
7744
|
+
`| Added last 7 days | **${res.added_last_7_days}** |`,
|
|
7745
|
+
``,
|
|
7746
|
+
`### Top Categories`,
|
|
7747
|
+
];
|
|
7748
|
+
|
|
7749
|
+
for (const cat of res.top_categories ?? []) {
|
|
7750
|
+
lines.push(`- \`${cat.category}\` — ${cat.count} lesson${cat.count === 1 ? '' : 's'}`);
|
|
7751
|
+
}
|
|
7752
|
+
|
|
7753
|
+
lines.push(``, `### Most Trusted Lessons`);
|
|
7754
|
+
|
|
7755
|
+
for (const lesson of res.most_trusted ?? []) {
|
|
7756
|
+
lines.push(
|
|
7757
|
+
`**\`${lesson.topic}\`** ${confirmBar(lesson.confirm_count)}`,
|
|
7758
|
+
`> ${lesson.what_worked.slice(0, 120)}${lesson.what_worked.length > 120 ? '…' : ''}`,
|
|
7759
|
+
``,
|
|
7760
|
+
);
|
|
7761
|
+
}
|
|
7762
|
+
|
|
7763
|
+
lines.push(
|
|
7764
|
+
`---`,
|
|
7765
|
+
`**Contribute:** \`syndicate(topic="...", what_worked="...")\` | **Search:** \`syndicate_search(q="your problem")\``,
|
|
7766
|
+
);
|
|
7767
|
+
|
|
7768
|
+
// Top contributors (anonymous scores)
|
|
7769
|
+
if ((res as any).top_contributors?.length) {
|
|
7770
|
+
lines.push(``, `### 🏅 Top Contributors (anonymous)`);
|
|
7771
|
+
for (const c of (res as any).top_contributors) {
|
|
7772
|
+
lines.push(`- Trust **${c.trust_score}** · ${c.lessons_count} lesson${c.lessons_count === 1 ? '' : 's'} · ${c.confirms_received} confirms received`);
|
|
7773
|
+
}
|
|
7774
|
+
}
|
|
7775
|
+
|
|
7776
|
+
return lines.join('\n');
|
|
7777
|
+
}
|
|
7778
|
+
|
|
7779
|
+
// ── v0.8 Knowledge Syndication: syndicate_trending ───────────────────────
|
|
7780
|
+
case 'syndicate_trending': {
|
|
7781
|
+
const { limit = 10 } = args as { limit?: number };
|
|
7782
|
+
|
|
7783
|
+
const params = new URLSearchParams({ limit: String(Math.min(Math.max(1, limit), 50)) });
|
|
7784
|
+
const res = await apiFetch<{ results: Array<{
|
|
7785
|
+
id: string; topic: string; category: string; outcome: string;
|
|
7786
|
+
what_worked: string; what_failed: string; severity: string;
|
|
7787
|
+
confirm_count: number; trend_score: number; created_at: string;
|
|
7788
|
+
}>; count: number }>(`/api/v1/syndication/trending?${params}`);
|
|
7789
|
+
|
|
7790
|
+
if (!res.results || res.results.length === 0) {
|
|
7791
|
+
return [
|
|
7792
|
+
`## 📈 Trending in the Knowledge Commons`,
|
|
7793
|
+
``,
|
|
7794
|
+
`No trending lessons yet (need at least 2 confirms in the last 7 days).`,
|
|
7795
|
+
``,
|
|
7796
|
+
`Contribute and confirm lessons to see them trend: \`syndicate(topic="...", what_worked="...")\``,
|
|
7797
|
+
].join('\n');
|
|
7798
|
+
}
|
|
7799
|
+
|
|
7800
|
+
const outcomeIcon = (o: string) => o === 'success' ? '✅' : o === 'failure' ? '❌' : '⚠️';
|
|
7801
|
+
const severityLabel = (s: string) => s === 'critical' ? '🔴' : s === 'major' ? '🟡' : '🟢';
|
|
7802
|
+
const confirmBar = (n: number) => {
|
|
7803
|
+
const filled = Math.min(10, Math.round(n / 5));
|
|
7804
|
+
return '█'.repeat(filled) + '░'.repeat(10 - filled) + ` ×${n}`;
|
|
7805
|
+
};
|
|
7806
|
+
const trendBar = (score: number) => {
|
|
7807
|
+
const filled = Math.min(10, Math.round(score * 2));
|
|
7808
|
+
return '▲'.repeat(filled) + '△'.repeat(10 - filled) + ` ${score.toFixed(2)}/day`;
|
|
7809
|
+
};
|
|
7810
|
+
|
|
7811
|
+
const lines: string[] = [
|
|
7812
|
+
`## 📈 Trending in the Knowledge Commons`,
|
|
7813
|
+
`*Lessons with the fastest confirmation velocity in the last 7 days*`,
|
|
7814
|
+
``,
|
|
7815
|
+
];
|
|
7816
|
+
|
|
7817
|
+
for (const lesson of res.results) {
|
|
7818
|
+
lines.push(
|
|
7819
|
+
`### ${outcomeIcon(lesson.outcome)} \`${lesson.topic}\` ${severityLabel(lesson.severity)}`,
|
|
7820
|
+
`**Trend:** ${trendBar(lesson.trend_score)} | **Trust:** ${confirmBar(lesson.confirm_count)}`,
|
|
7821
|
+
lesson.what_worked ? `**What worked:** ${lesson.what_worked.slice(0, 200)}${lesson.what_worked.length > 200 ? '…' : ''}` : '',
|
|
7822
|
+
`*ID: \`${lesson.id}\` · ${new Date(lesson.created_at).toLocaleDateString('de-DE')}*`,
|
|
7823
|
+
``,
|
|
7824
|
+
);
|
|
7825
|
+
}
|
|
7826
|
+
|
|
7827
|
+
lines.push(
|
|
7828
|
+
`---`,
|
|
7829
|
+
`**Confirm** (if this helped you): \`syndicate(topic="${res.results[0]?.topic ?? '...'}", what_worked="...")\` → auto-deduped, trust +1`,
|
|
7830
|
+
`**All trending:** \`syndicate_trending(limit=50)\` | **Search:** \`syndicate_search(q="...")\``,
|
|
7672
7831
|
);
|
|
7673
7832
|
|
|
7674
7833
|
return lines.filter(l => l !== '').join('\n');
|