claude-sessions-mcp 0.4.0 → 0.4.1-beta.1

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/index.ts
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
- import { Effect } from "effect";
6
+ import { Cause, Effect } from "effect";
7
7
  import { z } from "zod";
8
8
  import * as session from "@claude-sessions/core";
9
9
 
@@ -11,15 +11,41 @@ import * as session from "@claude-sessions/core";
11
11
  import { spawn } from "child_process";
12
12
  import { dirname, resolve } from "path";
13
13
  import { fileURLToPath } from "url";
14
- import { existsSync } from "fs";
14
+ import { existsSync, readFileSync } from "fs";
15
15
  var __dirname = dirname(fileURLToPath(import.meta.url));
16
- async function startWebServer(port = 5173, openBrowser = true) {
16
+ function getWebPackageTag(version) {
17
+ if (version.includes("-beta")) return "beta";
18
+ if (version.includes("-alpha")) return "alpha";
19
+ return "latest";
20
+ }
21
+ function getCurrentVersion() {
22
+ const packageJsonPath = resolve(__dirname, "../package.json");
23
+ try {
24
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
25
+ return packageJson.version || "0.0.0";
26
+ } catch {
27
+ return "0.0.0";
28
+ }
29
+ }
30
+ async function startWebServer(options = {}) {
31
+ const { port = 5173, openBrowser = true, editor, home, project } = options;
17
32
  const localCliPath = resolve(__dirname, "../../web/dist/cli.js");
18
33
  const useLocal = existsSync(localCliPath);
19
- const child = useLocal ? spawn("node", [localCliPath, "--port", String(port)], {
34
+ const cliArgs = ["--port", String(port)];
35
+ if (editor) {
36
+ cliArgs.push("--editor", editor);
37
+ }
38
+ if (home) {
39
+ cliArgs.push("--home", home);
40
+ }
41
+ if (project) {
42
+ cliArgs.push("--project", project);
43
+ }
44
+ const webPackageTag = getWebPackageTag(getCurrentVersion());
45
+ const child = useLocal ? spawn("node", [localCliPath, ...cliArgs], {
20
46
  stdio: ["ignore", "pipe", "pipe"],
21
47
  env: { ...process.env }
22
- }) : spawn("npx", ["@claude-sessions/web", "--port", String(port)], {
48
+ }) : spawn("npx", [`@claude-sessions/web@${webPackageTag}`, ...cliArgs], {
23
49
  stdio: ["ignore", "pipe", "pipe"],
24
50
  env: { ...process.env }
25
51
  });
@@ -62,12 +88,22 @@ async function stopWebServer(server2) {
62
88
  }
63
89
 
64
90
  // src/index.ts
91
+ async function runEffect(effect) {
92
+ return Effect.runPromise(
93
+ effect.pipe(
94
+ Effect.catchAllCause((cause) => {
95
+ const prettyError = Cause.pretty(cause);
96
+ return Effect.die(new Error(prettyError));
97
+ })
98
+ )
99
+ );
100
+ }
65
101
  var server = new McpServer({
66
102
  name: "claude-sessions-mcp",
67
103
  version: "0.4.0"
68
104
  });
69
105
  server.tool("list_projects", "List all Claude Code projects with session counts", {}, async () => {
70
- const result = await Effect.runPromise(session.listProjects);
106
+ const result = await runEffect(session.listProjects);
71
107
  return {
72
108
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
73
109
  };
@@ -79,7 +115,7 @@ server.tool(
79
115
  project_name: z.string().describe("Project folder name (e.g., '-Users-young-works-myproject')")
80
116
  },
81
117
  async ({ project_name }) => {
82
- const result = await Effect.runPromise(session.listSessions(project_name));
118
+ const result = await runEffect(session.listSessions(project_name));
83
119
  return {
84
120
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
85
121
  };
@@ -94,9 +130,7 @@ server.tool(
94
130
  new_title: z.string().describe("New title to add as prefix")
95
131
  },
96
132
  async ({ project_name, session_id, new_title }) => {
97
- const result = await Effect.runPromise(
98
- session.renameSession(project_name, session_id, new_title)
99
- );
133
+ const result = await runEffect(session.renameSession(project_name, session_id, new_title));
100
134
  return {
101
135
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
102
136
  };
@@ -110,7 +144,7 @@ server.tool(
110
144
  session_id: z.string().describe("Session ID to delete")
111
145
  },
112
146
  async ({ project_name, session_id }) => {
113
- const result = await Effect.runPromise(session.deleteSession(project_name, session_id));
147
+ const result = await runEffect(session.deleteSession(project_name, session_id));
114
148
  return {
115
149
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
116
150
  };
@@ -125,9 +159,7 @@ server.tool(
125
159
  message_uuid: z.string().describe("UUID of the message to delete")
126
160
  },
127
161
  async ({ project_name, session_id, message_uuid }) => {
128
- const result = await Effect.runPromise(
129
- session.deleteMessage(project_name, session_id, message_uuid)
130
- );
162
+ const result = await runEffect(session.deleteMessage(project_name, session_id, message_uuid));
131
163
  return {
132
164
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
133
165
  };
@@ -140,7 +172,7 @@ server.tool(
140
172
  project_name: z.string().optional().describe("Optional: filter by project name")
141
173
  },
142
174
  async ({ project_name }) => {
143
- const result = await Effect.runPromise(session.previewCleanup(project_name));
175
+ const result = await runEffect(session.previewCleanup(project_name));
144
176
  return {
145
177
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
146
178
  };
@@ -156,7 +188,7 @@ server.tool(
156
188
  clear_orphan_agents: z.boolean().default(true).describe("Clear orphan agent files whose session no longer exists (default: true)")
157
189
  },
158
190
  async ({ project_name, clear_empty, clear_invalid, clear_orphan_agents }) => {
159
- const result = await Effect.runPromise(
191
+ const result = await runEffect(
160
192
  session.clearSessions({
161
193
  projectName: project_name,
162
194
  clearEmpty: clear_empty,
@@ -177,7 +209,77 @@ server.tool(
177
209
  session_id: z.string().describe("Session ID")
178
210
  },
179
211
  async ({ project_name, session_id }) => {
180
- const result = await Effect.runPromise(session.getSessionFiles(project_name, session_id));
212
+ const result = await runEffect(session.getSessionFiles(project_name, session_id));
213
+ return {
214
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
215
+ };
216
+ }
217
+ );
218
+ server.tool(
219
+ "analyze_session",
220
+ "Analyze a session to get statistics, tool usage, patterns, and optimization insights",
221
+ {
222
+ project_name: z.string().describe("Project folder name"),
223
+ session_id: z.string().describe("Session ID")
224
+ },
225
+ async ({ project_name, session_id }) => {
226
+ const result = await runEffect(session.analyzeSession(project_name, session_id));
227
+ return {
228
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
229
+ };
230
+ }
231
+ );
232
+ server.tool(
233
+ "summarize_session",
234
+ "Summarize a session into compact user/assistant conversation format with timestamps",
235
+ {
236
+ project_name: z.string().describe("Project folder name"),
237
+ session_id: z.string().describe("Session ID"),
238
+ limit: z.number().default(50).describe("Maximum number of messages to include (default: 50)"),
239
+ max_length: z.number().default(100).describe("Maximum length for each message content (default: 100)")
240
+ },
241
+ async ({ project_name, session_id, limit, max_length }) => {
242
+ const result = await runEffect(
243
+ session.summarizeSession(project_name, session_id, {
244
+ limit,
245
+ maxLength: max_length
246
+ })
247
+ );
248
+ return {
249
+ content: [{ type: "text", text: result.formatted }]
250
+ };
251
+ }
252
+ );
253
+ server.tool(
254
+ "compress_session",
255
+ "Compress a session by removing redundant snapshots and truncating long tool outputs",
256
+ {
257
+ project_name: z.string().describe("Project folder name"),
258
+ session_id: z.string().describe("Session ID"),
259
+ keep_snapshots: z.enum(["first_last", "all", "none"]).default("first_last").describe("Which snapshots to keep: first_last (default), all, or none"),
260
+ max_tool_output_length: z.number().default(0).describe("Truncate tool outputs longer than this (0 = no limit)")
261
+ },
262
+ async ({ project_name, session_id, keep_snapshots, max_tool_output_length }) => {
263
+ const result = await runEffect(
264
+ session.compressSession(project_name, session_id, {
265
+ keepSnapshots: keep_snapshots,
266
+ maxToolOutputLength: max_tool_output_length
267
+ })
268
+ );
269
+ return {
270
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
271
+ };
272
+ }
273
+ );
274
+ server.tool(
275
+ "extract_project_knowledge",
276
+ "Extract patterns, hot files, workflows, and decisions from project sessions",
277
+ {
278
+ project_name: z.string().describe("Project folder name"),
279
+ session_ids: z.array(z.string()).optional().describe("Optional: specific session IDs to analyze (default: all sessions)")
280
+ },
281
+ async ({ project_name, session_ids }) => {
282
+ const result = await runEffect(session.extractProjectKnowledge(project_name, session_ids));
181
283
  return {
182
284
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
183
285
  };
@@ -194,9 +296,7 @@ server.tool(
194
296
  )
195
297
  },
196
298
  async ({ project_name, session_id, message_uuid }) => {
197
- const result = await Effect.runPromise(
198
- session.splitSession(project_name, session_id, message_uuid)
199
- );
299
+ const result = await runEffect(session.splitSession(project_name, session_id, message_uuid));
200
300
  return {
201
301
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
202
302
  };
@@ -209,9 +309,12 @@ server.tool(
209
309
  {
210
310
  port: z.number().default(5173).describe("Port to run the web server on (default: 5173)"),
211
311
  open_browser: z.boolean().default(true).describe("Whether to open browser automatically (default: true)"),
212
- restart: z.boolean().default(false).describe("Restart the server if already running (default: false)")
312
+ restart: z.boolean().default(false).describe("Restart the server if already running (default: false)"),
313
+ editor: z.string().optional().describe("Editor command to open files (default: code)"),
314
+ home: z.string().optional().describe("Home directory for ~ expansion (default: system homedir)"),
315
+ project: z.string().optional().describe("Current project name for priority sorting in project list")
213
316
  },
214
- async ({ port, open_browser, restart }) => {
317
+ async ({ port, open_browser, restart, editor, home, project }) => {
215
318
  try {
216
319
  if (webServerInstance) {
217
320
  if (restart) {
@@ -236,7 +339,13 @@ server.tool(
236
339
  };
237
340
  }
238
341
  }
239
- webServerInstance = await startWebServer(port, open_browser);
342
+ webServerInstance = await startWebServer({
343
+ port,
344
+ openBrowser: open_browser,
345
+ editor,
346
+ home,
347
+ project
348
+ });
240
349
  return {
241
350
  content: [
242
351
  {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * claude-sessions-mcp\n * MCP server for managing Claude Code conversation sessions\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Effect } from 'effect'\nimport { z } from 'zod'\nimport * as session from '@claude-sessions/core'\nimport { startWebServer, stopWebServer, type WebServer } from './server.js'\n\nconst server = new McpServer({\n name: 'claude-sessions-mcp',\n version: '0.4.0',\n})\n\n// List all projects\nserver.tool('list_projects', 'List all Claude Code projects with session counts', {}, async () => {\n const result = await Effect.runPromise(session.listProjects)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n})\n\n// List sessions in a project\nserver.tool(\n 'list_sessions',\n 'List all sessions in a project',\n {\n project_name: z.string().describe(\"Project folder name (e.g., '-Users-young-works-myproject')\"),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.listSessions(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Rename session\nserver.tool(\n 'rename_session',\n 'Rename a session by adding a title prefix to the first message',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID (filename without .jsonl)'),\n new_title: z.string().describe('New title to add as prefix'),\n },\n async ({ project_name, session_id, new_title }) => {\n const result = await Effect.runPromise(\n session.renameSession(project_name, session_id, new_title)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete session\nserver.tool(\n 'delete_session',\n 'Delete a session (moves to .bak folder for recovery)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to delete'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.deleteSession(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete message\nserver.tool(\n 'delete_message',\n 'Delete a message from a session and repair the parentUuid chain',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n message_uuid: z.string().describe('UUID of the message to delete'),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await Effect.runPromise(\n session.deleteMessage(project_name, session_id, message_uuid)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Preview cleanup\nserver.tool(\n 'preview_cleanup',\n 'Preview sessions that would be cleaned (empty and invalid API key sessions)',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n },\n async ({ project_name }) => {\n const result = await Effect.runPromise(session.previewCleanup(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Clear sessions\nserver.tool(\n 'clear_sessions',\n 'Delete all empty sessions and invalid API key sessions',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n clear_empty: z.boolean().default(true).describe('Clear empty sessions (default: true)'),\n clear_invalid: z\n .boolean()\n .default(true)\n .describe('Clear invalid API key sessions (default: true)'),\n clear_orphan_agents: z\n .boolean()\n .default(true)\n .describe('Clear orphan agent files whose session no longer exists (default: true)'),\n },\n async ({ project_name, clear_empty, clear_invalid, clear_orphan_agents }) => {\n const result = await Effect.runPromise(\n session.clearSessions({\n projectName: project_name,\n clearEmpty: clear_empty,\n clearInvalid: clear_invalid,\n clearOrphanAgents: clear_orphan_agents,\n })\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Get changed files from a session\nserver.tool(\n 'get_session_files',\n 'Get list of all files changed in a session (from file-history-snapshot and tool_use)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n },\n async ({ project_name, session_id }) => {\n const result = await Effect.runPromise(session.getSessionFiles(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Split session\nserver.tool(\n 'split_session',\n 'Split a session at a specific message, creating a new session with messages from that point onwards',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to split'),\n message_uuid: z\n .string()\n .describe(\n 'UUID of the message where the split starts (this message becomes the first message of the new session)'\n ),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await Effect.runPromise(\n session.splitSession(project_name, session_id, message_uuid)\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Start GUI\nlet webServerInstance: WebServer | null = null\n\nserver.tool(\n 'start_gui',\n 'Start the web GUI for session management and open it in browser',\n {\n port: z.number().default(5173).describe('Port to run the web server on (default: 5173)'),\n open_browser: z\n .boolean()\n .default(true)\n .describe('Whether to open browser automatically (default: true)'),\n restart: z\n .boolean()\n .default(false)\n .describe('Restart the server if already running (default: false)'),\n },\n async ({ port, open_browser, restart }) => {\n try {\n if (webServerInstance) {\n if (restart) {\n await stopWebServer(webServerInstance)\n webServerInstance = null\n } else {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI is already running',\n url: `http://localhost:${port}`,\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n\n webServerInstance = await startWebServer(port, open_browser)\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI started successfully',\n url: `http://localhost:${port}`,\n pid: process.pid,\n },\n null,\n 2\n ),\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n error: String(error),\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n)\n\n// Stop GUI\nserver.tool('stop_gui', 'Stop the web GUI server', {}, async () => {\n if (webServerInstance) {\n const port = webServerInstance.port\n // Call shutdown API first for graceful shutdown\n try {\n await fetch(`http://localhost:${port}/api/shutdown`, { method: 'POST' })\n } catch {\n // Server might already be stopping\n }\n // Then kill the process if still running\n await stopWebServer(webServerInstance)\n webServerInstance = null\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI stopped successfully' }, null, 2),\n },\n ],\n }\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI was not running' }, null, 2),\n },\n ],\n }\n})\n\n// Main entry\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch(console.error)\n","/**\n * Web server management for MCP\n * Launches @claude-sessions/web\n */\nimport { spawn, type ChildProcess } from 'node:child_process'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { existsSync } from 'node:fs'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\nexport interface WebServer {\n process: ChildProcess\n port: number\n}\n\nexport async function startWebServer(\n port: number = 5173,\n openBrowser: boolean = true\n): Promise<WebServer> {\n // Try local build first, fallback to npx\n const localCliPath = resolve(__dirname, '../../web/dist/cli.js')\n const useLocal = existsSync(localCliPath)\n\n const child = useLocal\n ? spawn('node', [localCliPath, '--port', String(port)], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env },\n })\n : spawn('npx', ['@claude-sessions/web', '--port', String(port)], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env },\n })\n\n // Wait for server to start\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('Server startup timeout')), 30000)\n\n child.stdout?.on('data', (data: Buffer) => {\n const output = data.toString()\n // SvelteKit adapter-node outputs \"Listening on http://0.0.0.0:PORT\"\n if (\n output.includes('Listening on') ||\n output.includes('localhost') ||\n output.includes('Local:')\n ) {\n clearTimeout(timeout)\n resolve()\n }\n })\n\n child.stderr?.on('data', (data: Buffer) => {\n const output = data.toString()\n // npm/npx progress output goes to stderr\n if (output.includes('Listening on') || output.includes('localhost')) {\n clearTimeout(timeout)\n resolve()\n }\n })\n\n child.on('error', (err) => {\n clearTimeout(timeout)\n reject(err)\n })\n\n child.on('exit', (code) => {\n if (code !== 0) {\n clearTimeout(timeout)\n reject(new Error(`Server exited with code ${code}`))\n }\n })\n })\n\n // Open browser if requested\n if (openBrowser) {\n const url = `http://localhost:${port}`\n const openCmd =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n spawn(openCmd, [url], { stdio: 'ignore', detached: true }).unref()\n }\n\n return { process: child, port }\n}\n\nexport async function stopWebServer(server: WebServer): Promise<void> {\n server.process.kill('SIGTERM')\n}\n"],"mappings":"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","names":["resolve","server"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * claude-sessions-mcp\n * MCP server for managing Claude Code conversation sessions\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Cause, Effect } from 'effect'\nimport { z } from 'zod'\nimport * as session from '@claude-sessions/core'\nimport { startWebServer, stopWebServer, type WebServer } from './server.js'\n\n// Helper to run Effect with detailed error reporting\nasync function runEffect<A>(effect: Effect.Effect<A, unknown, never>): Promise<A> {\n return Effect.runPromise(\n effect.pipe(\n Effect.catchAllCause((cause) => {\n const prettyError = Cause.pretty(cause)\n return Effect.die(new Error(prettyError))\n })\n )\n ) as Promise<A>\n}\n\nconst server = new McpServer({\n name: 'claude-sessions-mcp',\n version: '0.4.0',\n})\n\n// List all projects\nserver.tool('list_projects', 'List all Claude Code projects with session counts', {}, async () => {\n const result = await runEffect(session.listProjects)\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n})\n\n// List sessions in a project\nserver.tool(\n 'list_sessions',\n 'List all sessions in a project',\n {\n project_name: z.string().describe(\"Project folder name (e.g., '-Users-young-works-myproject')\"),\n },\n async ({ project_name }) => {\n const result = await runEffect(session.listSessions(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Rename session\nserver.tool(\n 'rename_session',\n 'Rename a session by adding a title prefix to the first message',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID (filename without .jsonl)'),\n new_title: z.string().describe('New title to add as prefix'),\n },\n async ({ project_name, session_id, new_title }) => {\n const result = await runEffect(session.renameSession(project_name, session_id, new_title))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete session\nserver.tool(\n 'delete_session',\n 'Delete a session (moves to .bak folder for recovery)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to delete'),\n },\n async ({ project_name, session_id }) => {\n const result = await runEffect(session.deleteSession(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Delete message\nserver.tool(\n 'delete_message',\n 'Delete a message from a session and repair the parentUuid chain',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n message_uuid: z.string().describe('UUID of the message to delete'),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await runEffect(session.deleteMessage(project_name, session_id, message_uuid))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Preview cleanup\nserver.tool(\n 'preview_cleanup',\n 'Preview sessions that would be cleaned (empty and invalid API key sessions)',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n },\n async ({ project_name }) => {\n const result = await runEffect(session.previewCleanup(project_name))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Clear sessions\nserver.tool(\n 'clear_sessions',\n 'Delete all empty sessions and invalid API key sessions',\n {\n project_name: z.string().optional().describe('Optional: filter by project name'),\n clear_empty: z.boolean().default(true).describe('Clear empty sessions (default: true)'),\n clear_invalid: z\n .boolean()\n .default(true)\n .describe('Clear invalid API key sessions (default: true)'),\n clear_orphan_agents: z\n .boolean()\n .default(true)\n .describe('Clear orphan agent files whose session no longer exists (default: true)'),\n },\n async ({ project_name, clear_empty, clear_invalid, clear_orphan_agents }) => {\n const result = await runEffect(\n session.clearSessions({\n projectName: project_name,\n clearEmpty: clear_empty,\n clearInvalid: clear_invalid,\n clearOrphanAgents: clear_orphan_agents,\n })\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Get changed files from a session\nserver.tool(\n 'get_session_files',\n 'Get list of all files changed in a session (from file-history-snapshot and tool_use)',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n },\n async ({ project_name, session_id }) => {\n const result = await runEffect(session.getSessionFiles(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Analyze session for optimization insights\nserver.tool(\n 'analyze_session',\n 'Analyze a session to get statistics, tool usage, patterns, and optimization insights',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n },\n async ({ project_name, session_id }) => {\n const result = await runEffect(session.analyzeSession(project_name, session_id))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Summarize session into user/assistant conversation format\nserver.tool(\n 'summarize_session',\n 'Summarize a session into compact user/assistant conversation format with timestamps',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n limit: z.number().default(50).describe('Maximum number of messages to include (default: 50)'),\n max_length: z\n .number()\n .default(100)\n .describe('Maximum length for each message content (default: 100)'),\n },\n async ({ project_name, session_id, limit, max_length }) => {\n const result = await runEffect(\n session.summarizeSession(project_name, session_id, {\n limit,\n maxLength: max_length,\n })\n )\n return {\n content: [{ type: 'text', text: result.formatted }],\n }\n }\n)\n\n// Compress session to reduce file size\nserver.tool(\n 'compress_session',\n 'Compress a session by removing redundant snapshots and truncating long tool outputs',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID'),\n keep_snapshots: z\n .enum(['first_last', 'all', 'none'])\n .default('first_last')\n .describe('Which snapshots to keep: first_last (default), all, or none'),\n max_tool_output_length: z\n .number()\n .default(0)\n .describe('Truncate tool outputs longer than this (0 = no limit)'),\n },\n async ({ project_name, session_id, keep_snapshots, max_tool_output_length }) => {\n const result = await runEffect(\n session.compressSession(project_name, session_id, {\n keepSnapshots: keep_snapshots,\n maxToolOutputLength: max_tool_output_length,\n })\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Extract project knowledge from sessions\nserver.tool(\n 'extract_project_knowledge',\n 'Extract patterns, hot files, workflows, and decisions from project sessions',\n {\n project_name: z.string().describe('Project folder name'),\n session_ids: z\n .array(z.string())\n .optional()\n .describe('Optional: specific session IDs to analyze (default: all sessions)'),\n },\n async ({ project_name, session_ids }) => {\n const result = await runEffect(session.extractProjectKnowledge(project_name, session_ids))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Split session\nserver.tool(\n 'split_session',\n 'Split a session at a specific message, creating a new session with messages from that point onwards',\n {\n project_name: z.string().describe('Project folder name'),\n session_id: z.string().describe('Session ID to split'),\n message_uuid: z\n .string()\n .describe(\n 'UUID of the message where the split starts (this message becomes the first message of the new session)'\n ),\n },\n async ({ project_name, session_id, message_uuid }) => {\n const result = await runEffect(session.splitSession(project_name, session_id, message_uuid))\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n }\n)\n\n// Start GUI\nlet webServerInstance: WebServer | null = null\n\nserver.tool(\n 'start_gui',\n 'Start the web GUI for session management and open it in browser',\n {\n port: z.number().default(5173).describe('Port to run the web server on (default: 5173)'),\n open_browser: z\n .boolean()\n .default(true)\n .describe('Whether to open browser automatically (default: true)'),\n restart: z\n .boolean()\n .default(false)\n .describe('Restart the server if already running (default: false)'),\n editor: z.string().optional().describe('Editor command to open files (default: code)'),\n home: z\n .string()\n .optional()\n .describe('Home directory for ~ expansion (default: system homedir)'),\n project: z\n .string()\n .optional()\n .describe('Current project name for priority sorting in project list'),\n },\n async ({ port, open_browser, restart, editor, home, project }) => {\n try {\n if (webServerInstance) {\n if (restart) {\n await stopWebServer(webServerInstance)\n webServerInstance = null\n } else {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI is already running',\n url: `http://localhost:${port}`,\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n\n webServerInstance = await startWebServer({\n port,\n openBrowser: open_browser,\n editor,\n home,\n project,\n })\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Web GUI started successfully',\n url: `http://localhost:${port}`,\n pid: process.pid,\n },\n null,\n 2\n ),\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: false,\n error: String(error),\n },\n null,\n 2\n ),\n },\n ],\n }\n }\n }\n)\n\n// Stop GUI\nserver.tool('stop_gui', 'Stop the web GUI server', {}, async () => {\n if (webServerInstance) {\n const port = webServerInstance.port\n // Call shutdown API first for graceful shutdown\n try {\n await fetch(`http://localhost:${port}/api/shutdown`, { method: 'POST' })\n } catch {\n // Server might already be stopping\n }\n // Then kill the process if still running\n await stopWebServer(webServerInstance)\n webServerInstance = null\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI stopped successfully' }, null, 2),\n },\n ],\n }\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ success: true, message: 'Web GUI was not running' }, null, 2),\n },\n ],\n }\n})\n\n// Main entry\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch(console.error)\n","/**\n * Web server management for MCP\n * Launches @claude-sessions/web\n */\nimport { spawn, type ChildProcess } from 'node:child_process'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { existsSync, readFileSync } from 'node:fs'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n\n/**\n * Determine the npm tag for @claude-sessions/web based on current MCP package version.\n * Beta MCP should use beta web, alpha MCP should use alpha web.\n */\nexport function getWebPackageTag(version: string): 'latest' | 'beta' | 'alpha' {\n if (version.includes('-beta')) return 'beta'\n if (version.includes('-alpha')) return 'alpha'\n return 'latest'\n}\n\n/**\n * Get the current package version from package.json\n */\nfunction getCurrentVersion(): string {\n const packageJsonPath = resolve(__dirname, '../package.json')\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))\n return packageJson.version || '0.0.0'\n } catch {\n return '0.0.0'\n }\n}\n\nexport interface WebServer {\n process: ChildProcess\n port: number\n}\n\nexport interface WebServerOptions {\n port?: number\n openBrowser?: boolean\n editor?: string\n home?: string\n project?: string\n}\n\nexport async function startWebServer(options: WebServerOptions = {}): Promise<WebServer> {\n const { port = 5173, openBrowser = true, editor, home, project } = options\n\n // Try local build first, fallback to npx\n const localCliPath = resolve(__dirname, '../../web/dist/cli.js')\n const useLocal = existsSync(localCliPath)\n\n // Build CLI arguments\n const cliArgs = ['--port', String(port)]\n if (editor) {\n cliArgs.push('--editor', editor)\n }\n if (home) {\n cliArgs.push('--home', home)\n }\n if (project) {\n cliArgs.push('--project', project)\n }\n\n const webPackageTag = getWebPackageTag(getCurrentVersion())\n const child = useLocal\n ? spawn('node', [localCliPath, ...cliArgs], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env },\n })\n : spawn('npx', [`@claude-sessions/web@${webPackageTag}`, ...cliArgs], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env },\n })\n\n // Wait for server to start\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => reject(new Error('Server startup timeout')), 30000)\n\n child.stdout?.on('data', (data: Buffer) => {\n const output = data.toString()\n // SvelteKit adapter-node outputs \"Listening on http://0.0.0.0:PORT\"\n if (\n output.includes('Listening on') ||\n output.includes('localhost') ||\n output.includes('Local:')\n ) {\n clearTimeout(timeout)\n resolve()\n }\n })\n\n child.stderr?.on('data', (data: Buffer) => {\n const output = data.toString()\n // npm/npx progress output goes to stderr\n if (output.includes('Listening on') || output.includes('localhost')) {\n clearTimeout(timeout)\n resolve()\n }\n })\n\n child.on('error', (err) => {\n clearTimeout(timeout)\n reject(err)\n })\n\n child.on('exit', (code) => {\n if (code !== 0) {\n clearTimeout(timeout)\n reject(new Error(`Server exited with code ${code}`))\n }\n })\n })\n\n // Open browser if requested\n if (openBrowser) {\n const url = `http://localhost:${port}`\n const openCmd =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n spawn(openCmd, [url], { stdio: 'ignore', detached: true }).unref()\n }\n\n return { process: child, port }\n}\n\nexport async function stopWebServer(server: WebServer): Promise<void> {\n server.process.kill('SIGTERM')\n}\n"],"mappings":"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","names":["resolve","server"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-sessions-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-beta.1",
4
4
  "description": "MCP server for managing Claude Code conversation sessions",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,20 +30,23 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@claude-sessions/core": "^0.1.0",
34
- "@modelcontextprotocol/sdk": "^1.0.0",
35
- "effect": "^3.12.0",
36
- "zod": "^3.24.0"
33
+ "@modelcontextprotocol/sdk": "^1.25.2",
34
+ "effect": "^3.19.14",
35
+ "zod": "^4.3.5",
36
+ "@claude-sessions/core": "0.4.1"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/node": "^22.0.0",
39
+ "@types/node": "^25.0.9",
40
40
  "tsup": "^8.3.0",
41
41
  "tsx": "^4.19.0",
42
- "typescript": "^5.7.0"
42
+ "typescript": "^5.7.0",
43
+ "vitest": "^4.0.17"
43
44
  },
44
45
  "scripts": {
45
46
  "build": "tsup",
46
47
  "dev": "tsx watch src/index.ts",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
47
50
  "typecheck": "tsc --noEmit",
48
51
  "lint": "eslint src"
49
52
  }