@cachly-dev/mcp-server 0.5.16 → 0.5.18
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 +145 -82
- package/dist/index.js +67 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +65 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cachly-dev/mcp-server",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.18",
|
|
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. 38 MCP tools.",
|
|
6
6
|
"type": "module",
|
package/src/index.ts
CHANGED
|
@@ -52,6 +52,7 @@ import { Redis } from 'ioredis';
|
|
|
52
52
|
const API_URL = process.env.CACHLY_API_URL ?? 'https://api.cachly.dev';
|
|
53
53
|
const JWT = process.env.CACHLY_JWT ?? '';
|
|
54
54
|
const EMBED_MODEL = process.env.CACHLY_EMBED_MODEL ?? '';
|
|
55
|
+
const CURRENT_VERSION = '0.5.17';
|
|
55
56
|
/**
|
|
56
57
|
* ┌──────────────────────────────────────────────────────────────────────┐
|
|
57
58
|
* │ EMBEDDING PROVIDER — pluggable, client-side first │
|
|
@@ -1865,9 +1866,32 @@ function buildConnectionString(inst: Instance): string {
|
|
|
1865
1866
|
return `${scheme}://${pw}${inst.host}:${inst.port}`;
|
|
1866
1867
|
}
|
|
1867
1868
|
|
|
1869
|
+
// Fires once per process when no JWT is set (anonymous, opt-out via CACHLY_NO_TELEMETRY=1)
|
|
1870
|
+
let _telemetryPingSent = false;
|
|
1871
|
+
async function sendAnonymousTelemetry(toolName: string): Promise<void> {
|
|
1872
|
+
if (_telemetryPingSent) return;
|
|
1873
|
+
if (process.env.CACHLY_NO_TELEMETRY === '1') return;
|
|
1874
|
+
_telemetryPingSent = true;
|
|
1875
|
+
// Detect editor from common env vars injected by IDE extensions
|
|
1876
|
+
const editor = process.env.CURSOR_TRACE_ID ? 'cursor'
|
|
1877
|
+
: process.env.WINDSURF_SESSION_ID ? 'windsurf'
|
|
1878
|
+
: process.env.GITHUB_COPILOT_WORKSPACE ? 'copilot'
|
|
1879
|
+
: process.env.CLAUDE_CODE_ENTRYPOINT ? 'claude'
|
|
1880
|
+
: 'unknown';
|
|
1881
|
+
try {
|
|
1882
|
+
await fetch(`${API_URL}/api/v1/telemetry/mcp`, {
|
|
1883
|
+
method: 'POST',
|
|
1884
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1885
|
+
body: JSON.stringify({ event: 'first_call_no_jwt', version: CURRENT_VERSION, editor, tool: toolName }),
|
|
1886
|
+
signal: AbortSignal.timeout(3000),
|
|
1887
|
+
});
|
|
1888
|
+
} catch { /* fire-and-forget, never block the user */ }
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1868
1891
|
async function handleTool(name: string, args: Record<string, unknown>): Promise<string> {
|
|
1869
1892
|
// Guard: if no JWT, return actionable onboarding message instead of HTTP 401
|
|
1870
1893
|
if (!JWT) {
|
|
1894
|
+
void sendAnonymousTelemetry(name);
|
|
1871
1895
|
return [
|
|
1872
1896
|
'🧠 **cachly AI Brain — Setup required**',
|
|
1873
1897
|
'',
|
|
@@ -4763,7 +4787,7 @@ async function handleBulkLockStream(name: string, args: Record<string, unknown>)
|
|
|
4763
4787
|
// ── Server setup ──────────────────────────────────────────────────────────────
|
|
4764
4788
|
|
|
4765
4789
|
const server = new Server(
|
|
4766
|
-
{ name: 'cachly-mcp', version:
|
|
4790
|
+
{ name: 'cachly-mcp', version: CURRENT_VERSION },
|
|
4767
4791
|
{ capabilities: { tools: {} } }
|
|
4768
4792
|
);
|
|
4769
4793
|
|
|
@@ -5100,7 +5124,21 @@ if (process.argv[2] === 'setup') {
|
|
|
5100
5124
|
: editorsRaw.split(/[,\s]+/).map(s => s.toLowerCase()).filter(s => EDITOR_FILES[s]);
|
|
5101
5125
|
console.log('');
|
|
5102
5126
|
|
|
5103
|
-
// ── Step 4:
|
|
5127
|
+
// ── Step 4: Email opt-in ──────────────────────────────────────────────────
|
|
5128
|
+
console.log('Step 4: Stay in the loop (optional)');
|
|
5129
|
+
const email = await ask(' Email for release notes & tips? [Enter to skip]: ');
|
|
5130
|
+
if (email && email.includes('@')) {
|
|
5131
|
+
try {
|
|
5132
|
+
await fetch(`${API_URL}/api/newsletter/subscribe`, {
|
|
5133
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
5134
|
+
body: JSON.stringify({ email: email.trim().toLowerCase(), source: 'mcp-setup' }),
|
|
5135
|
+
signal: AbortSignal.timeout(5000),
|
|
5136
|
+
});
|
|
5137
|
+
console.log('✅ Subscribed — you\'ll only hear from us when it matters.\n');
|
|
5138
|
+
} catch { console.log('⚠️ Could not subscribe (no internet?). Continuing...\n'); }
|
|
5139
|
+
} else { console.log(' Skipped.\n'); }
|
|
5140
|
+
|
|
5141
|
+
// ── Step 5: Write editor configs ──────────────────────────────────────────
|
|
5104
5142
|
for (const editor of editorsToSetup) {
|
|
5105
5143
|
const configFile = EDITOR_FILES[editor] ?? '.mcp.json';
|
|
5106
5144
|
const configPath = resolve(cwd, configFile);
|
|
@@ -5109,7 +5147,7 @@ if (process.argv[2] === 'setup') {
|
|
|
5109
5147
|
console.log(`✅ Written: ${configFile}`);
|
|
5110
5148
|
}
|
|
5111
5149
|
|
|
5112
|
-
// ── Step
|
|
5150
|
+
// ── Step 6: CLAUDE.md (always — idempotent) ───────────────────────────────
|
|
5113
5151
|
const mdResult = await writeClaudeMd(cwd, instance.id);
|
|
5114
5152
|
const mdLabel = mdResult === 'updated' ? '✅ Updated' : mdResult === 'appended' ? '✅ Appended to' : '✅ Written';
|
|
5115
5153
|
console.log(`${mdLabel}: CLAUDE.md`);
|
|
@@ -5145,6 +5183,30 @@ if (!JWT) {
|
|
|
5145
5183
|
);
|
|
5146
5184
|
}
|
|
5147
5185
|
|
|
5186
|
+
// ── Update nudge (non-blocking, fire-and-forget) ─────────────────────────────
|
|
5187
|
+
// Check npm registry once per process start; if outdated, log to stderr so
|
|
5188
|
+
// the editor's MCP log shows an actionable one-liner. Skipped if opted out.
|
|
5189
|
+
if (!process.env.CACHLY_NO_UPDATE_CHECK) {
|
|
5190
|
+
(async () => {
|
|
5191
|
+
try {
|
|
5192
|
+
const res = await fetch(
|
|
5193
|
+
`https://registry.npmjs.org/@cachly-dev/mcp-server/latest`,
|
|
5194
|
+
{ signal: AbortSignal.timeout(4000) },
|
|
5195
|
+
);
|
|
5196
|
+
if (res.ok) {
|
|
5197
|
+
const data = await res.json() as { version: string };
|
|
5198
|
+
const latest = data?.version ?? '';
|
|
5199
|
+
if (latest && latest !== CURRENT_VERSION) {
|
|
5200
|
+
process.stderr.write(
|
|
5201
|
+
`\n⚡ cachly update available: ${CURRENT_VERSION} → ${latest}\n` +
|
|
5202
|
+
` Run: npx @cachly-dev/mcp-server@latest setup\n\n`,
|
|
5203
|
+
);
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
} catch { /* ignore – network unavailable or timeout */ }
|
|
5207
|
+
})();
|
|
5208
|
+
}
|
|
5209
|
+
|
|
5148
5210
|
const transport = new StdioServerTransport();
|
|
5149
5211
|
await server.connect(transport);
|
|
5150
5212
|
|