@cachly-dev/mcp-server 0.5.2 → 0.5.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cachly-dev/mcp-server",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "MCP server – manage cachly.dev instances from any AI assistant (Copilot, Claude, Cursor, Windsurf)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "main": "./dist/index.js",
10
10
  "scripts": {
11
11
  "build": "tsc",
12
+ "postinstall": "node scripts/postinstall.js",
12
13
  "dev": "tsx src/index.ts",
13
14
  "start": "node dist/index.js",
14
15
  "test": "vitest run",
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ // Shown once after: npm install @cachly-dev/mcp-server
3
+
4
+ const c = {
5
+ reset: "\x1b[0m",
6
+ bold: "\x1b[1m",
7
+ violet: "\x1b[35m",
8
+ green: "\x1b[32m",
9
+ cyan: "\x1b[36m",
10
+ dim: "\x1b[2m",
11
+ };
12
+
13
+ const line = `${c.dim}─────────────────────────────────────────────────────${c.reset}`;
14
+
15
+ console.log(`
16
+ ${line}
17
+ ${c.bold}${c.violet}🧠 Cachly Brain MCP Server${c.reset} ${c.dim}v${process.env.npm_package_version ?? ""}${c.reset}
18
+
19
+ ${c.bold}Give your AI assistant persistent memory in 30 seconds:${c.reset}
20
+
21
+ ${c.cyan}1.${c.reset} Get a free Brain instance at ${c.bold}cachly.dev/setup-ai${c.reset}
22
+ ${c.cyan}2.${c.reset} Add to Claude Code / Cursor / Copilot:
23
+ ${c.dim}npx @cachly-dev/mcp-server --key cky_live_... --instance <uuid>${c.reset}
24
+
25
+ ${c.green}✅ Free tier · GDPR · German servers · No credit card${c.reset}
26
+
27
+ ${line}`);
package/src/index.ts CHANGED
@@ -4114,8 +4114,75 @@ const server = new Server(
4114
4114
 
4115
4115
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
4116
4116
 
4117
+ // ── Auto-session management ───────────────────────────────────────────────────
4118
+ // Transparently starts a Brain session on the first tool call of a process
4119
+ // and saves a session_end summary on SIGTERM/exit so users never have to call
4120
+ // session_start/session_end manually.
4121
+
4122
+ let _autoSessionInstanceId: string | null = null;
4123
+ let _autoSessionStarted = false;
4124
+ let _autoSessionToolCount = 0;
4125
+
4126
+ async function autoStartSession(instanceId: string): Promise<void> {
4127
+ if (_autoSessionStarted) return;
4128
+ _autoSessionStarted = true;
4129
+ _autoSessionInstanceId = instanceId;
4130
+ try {
4131
+ await handleTool('session_start', { instance_id: instanceId, focus: 'auto (MCP session)' });
4132
+ } catch { /* non-fatal — session tracking is a best-effort feature */ }
4133
+
4134
+ // Auto-index the project if it hasn't been indexed in the last 24h.
4135
+ // This is the main lever for growing token savings: more indexed code →
4136
+ // more semantic cache hits → fewer LLM calls for repeated questions.
4137
+ if (process.env.CACHLY_AUTO_INDEX !== 'false') {
4138
+ try {
4139
+ const redis = await getConnection(instanceId);
4140
+ const lastIndexed = await redis.get(`cachly:index:last_indexed:${instanceId}`);
4141
+ const staleMs = 24 * 60 * 60 * 1000;
4142
+ const isStale = !lastIndexed || (Date.now() - parseInt(lastIndexed, 10)) > staleMs;
4143
+ if (isStale) {
4144
+ // Mark as indexing now to prevent concurrent re-runs.
4145
+ await redis.set(`cachly:index:last_indexed:${instanceId}`, String(Date.now()), 'EX', 90000);
4146
+ // Run in background — don't block the first tool call.
4147
+ handleTool('index_project', {
4148
+ instance_id: instanceId,
4149
+ dir: process.cwd(),
4150
+ max_files: 150,
4151
+ ttl: 86400 * 7, // cache for 7 days
4152
+ namespace: 'cachly:sem:code',
4153
+ }).catch(() => undefined);
4154
+ }
4155
+ } catch { /* never block the session on indexing errors */ }
4156
+ }
4157
+ }
4158
+
4159
+ async function autoEndSession(): Promise<void> {
4160
+ if (!_autoSessionStarted || !_autoSessionInstanceId) return;
4161
+ _autoSessionStarted = false;
4162
+ try {
4163
+ await handleTool('session_end', {
4164
+ instance_id: _autoSessionInstanceId,
4165
+ summary: `Auto-ended after ${_autoSessionToolCount} tool call(s). Session was started automatically.`,
4166
+ files_changed: [],
4167
+ lessons_learned: 0,
4168
+ });
4169
+ } catch { /* non-fatal */ }
4170
+ }
4171
+
4117
4172
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
4118
4173
  const { name, arguments: args } = request.params;
4174
+
4175
+ // Auto-start brain session on first tool call that has an instance_id.
4176
+ // Skip session management tools to avoid recursion.
4177
+ const sessionTools = new Set(['session_start', 'session_end', 'auto_learn_session']);
4178
+ if (!sessionTools.has(name) && !_autoSessionStarted) {
4179
+ const instanceId = (args as Record<string, unknown>)?.instance_id as string | undefined;
4180
+ if (instanceId) {
4181
+ await autoStartSession(instanceId).catch(() => undefined);
4182
+ }
4183
+ }
4184
+ if (!sessionTools.has(name)) _autoSessionToolCount++;
4185
+
4119
4186
  try {
4120
4187
  const text = await handleTool(name, (args ?? {}) as Record<string, unknown>);
4121
4188
  return { content: [{ type: 'text', text }] };
@@ -4125,8 +4192,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
4125
4192
  }
4126
4193
  });
4127
4194
 
4128
- // Graceful shutdown – close all Redis connections
4195
+ // Graceful shutdown – close all Redis connections + auto-end brain session
4129
4196
  process.on('SIGTERM', async () => {
4197
+ await autoEndSession().catch(() => undefined);
4198
+ for (const [, client] of pool) await client.quit().catch(() => undefined);
4199
+ process.exit(0);
4200
+ });
4201
+
4202
+ process.on('SIGINT', async () => {
4203
+ await autoEndSession().catch(() => undefined);
4130
4204
  for (const [, client] of pool) await client.quit().catch(() => undefined);
4131
4205
  process.exit(0);
4132
4206
  });