claude-mem 3.0.2 → 3.0.4
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/.mcp.json +11 -0
- package/claude-mem +0 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +64 -0
- package/dist/commands/compress.d.ts +2 -0
- package/dist/commands/compress.js +59 -0
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.js +372 -0
- package/dist/commands/load-context.d.ts +2 -0
- package/dist/commands/load-context.js +330 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +41 -0
- package/dist/commands/migrate.d.ts +9 -0
- package/dist/commands/migrate.js +174 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +159 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.js +105 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +33 -0
- package/dist/constants.d.ts +516 -0
- package/dist/constants.js +522 -0
- package/dist/error-handler.d.ts +17 -0
- package/dist/error-handler.js +103 -0
- package/dist/mcp-server-cli.d.ts +34 -0
- package/dist/mcp-server-cli.js +158 -0
- package/dist/mcp-server.d.ts +103 -0
- package/dist/mcp-server.js +269 -0
- package/dist/types.d.ts +148 -0
- package/dist/types.js +78 -0
- package/dist/utils/HookDetector.d.ts +64 -0
- package/dist/utils/HookDetector.js +213 -0
- package/dist/utils/PathResolver.d.ts +16 -0
- package/dist/utils/PathResolver.js +55 -0
- package/dist/utils/SettingsManager.d.ts +63 -0
- package/dist/utils/SettingsManager.js +133 -0
- package/dist/utils/TranscriptCompressor.d.ts +111 -0
- package/dist/utils/TranscriptCompressor.js +486 -0
- package/dist/utils/common.d.ts +29 -0
- package/dist/utils/common.js +14 -0
- package/dist/utils/error-utils.d.ts +93 -0
- package/dist/utils/error-utils.js +238 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.js +42 -0
- package/dist/utils/mcp-client-factory.d.ts +51 -0
- package/dist/utils/mcp-client-factory.js +115 -0
- package/dist/utils/mcp-client.d.ts +75 -0
- package/dist/utils/mcp-client.js +120 -0
- package/dist/utils/memory-mcp-client.d.ts +135 -0
- package/dist/utils/memory-mcp-client.js +490 -0
- package/dist/utils/weaviate-mcp-adapter.d.ts +102 -0
- package/dist/utils/weaviate-mcp-adapter.js +587 -0
- package/package.json +3 -2
- package/src/claude-mem.js +0 -859
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 🔒 LOCKED by @docs-agent | Change to 🔑 to allow @docs-agent edits
|
|
4
|
+
*
|
|
5
|
+
* OFFICIAL DOCS: @modelcontextprotocol/sdk v1.0.0
|
|
6
|
+
* Last Verified: 2025-09-01
|
|
7
|
+
*
|
|
8
|
+
* Claude-mem MCP Server CLI Entry Point
|
|
9
|
+
*
|
|
10
|
+
* This module provides the standalone entry point for running the claude-mem MCP server
|
|
11
|
+
* that communicates with Claude Code via stdio transport.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node dist/mcp-server-cli.js
|
|
15
|
+
* claude-mem-server
|
|
16
|
+
*
|
|
17
|
+
* Communication:
|
|
18
|
+
* - Stdin/Stdout: MCP protocol messages with Claude Code
|
|
19
|
+
* - Stderr: Logging and diagnostic output
|
|
20
|
+
*
|
|
21
|
+
* Architecture:
|
|
22
|
+
* This CLI connects the MCP server to Claude Code via stdio transport,
|
|
23
|
+
* enabling Claude Code to access the embedded Weaviate knowledge graph
|
|
24
|
+
* through standard MCP memory tools.
|
|
25
|
+
*
|
|
26
|
+
* Implementation follows official MCP SDK patterns:
|
|
27
|
+
* - StdioServerTransport for stdin/stdout communication (SDK README.md#_snippet_16)
|
|
28
|
+
* - Server initialization before transport connection
|
|
29
|
+
* - Graceful shutdown handlers for SIGINT/SIGTERM
|
|
30
|
+
* - Error handling for uncaught exceptions
|
|
31
|
+
*
|
|
32
|
+
* @see docs/mcp-sdk/stdio-transport.md for transport patterns
|
|
33
|
+
*/
|
|
34
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
35
|
+
import { server, initializeServer, shutdownServer } from './mcp-server.js';
|
|
36
|
+
// =============================================================================
|
|
37
|
+
// MAIN ENTRY POINT
|
|
38
|
+
// =============================================================================
|
|
39
|
+
/**
|
|
40
|
+
* Main function to start the MCP server with stdio transport
|
|
41
|
+
*
|
|
42
|
+
* OFFICIAL PATTERN: Stdio transport connection
|
|
43
|
+
* Source: @modelcontextprotocol/sdk README.md#_snippet_16, #_snippet_25
|
|
44
|
+
*
|
|
45
|
+
* Connection sequence:
|
|
46
|
+
* 1. Initialize backend services (Weaviate adapter)
|
|
47
|
+
* 2. Create StdioServerTransport instance
|
|
48
|
+
* 3. Connect server to transport with await server.connect(transport)
|
|
49
|
+
* 4. Set up shutdown handlers for graceful termination
|
|
50
|
+
*
|
|
51
|
+
* Best Practices:
|
|
52
|
+
* - Initialize backends before transport connection
|
|
53
|
+
* - Use console.error for status messages (stderr)
|
|
54
|
+
* - Exit with code 1 on startup failures
|
|
55
|
+
*/
|
|
56
|
+
async function main() {
|
|
57
|
+
try {
|
|
58
|
+
// Initialize the server and embedded Weaviate adapter
|
|
59
|
+
await initializeServer();
|
|
60
|
+
// PATTERN: StdioServerTransport for CLI-based MCP servers
|
|
61
|
+
// Source: SDK README.md#_snippet_1, #_snippet_16
|
|
62
|
+
// This transport handles stdin/stdout communication automatically
|
|
63
|
+
const transport = new StdioServerTransport();
|
|
64
|
+
// PATTERN: Connect server to transport
|
|
65
|
+
// This starts the message handling loop
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
console.error('Claude-mem MCP server started on stdio');
|
|
68
|
+
console.error('Ready to receive MCP requests from Claude Code');
|
|
69
|
+
// Set up graceful shutdown handlers
|
|
70
|
+
setupShutdownHandlers();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
74
|
+
console.error('Failed to start claude-mem MCP server:', errorMessage);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// =============================================================================
|
|
79
|
+
// SHUTDOWN HANDLING
|
|
80
|
+
// =============================================================================
|
|
81
|
+
/**
|
|
82
|
+
* Set up handlers for graceful shutdown on various signals
|
|
83
|
+
*
|
|
84
|
+
* PATTERN: Graceful shutdown for stdio servers
|
|
85
|
+
* Source: Common Node.js pattern for CLI tools
|
|
86
|
+
*
|
|
87
|
+
* Signal handling:
|
|
88
|
+
* - SIGINT: Ctrl+C from terminal
|
|
89
|
+
* - SIGTERM: Standard termination signal
|
|
90
|
+
* - SIGHUP: Terminal hangup
|
|
91
|
+
*
|
|
92
|
+
* Error handling:
|
|
93
|
+
* - uncaughtException: Catch sync errors
|
|
94
|
+
* - unhandledRejection: Catch async promise rejections
|
|
95
|
+
*
|
|
96
|
+
* Best Practices:
|
|
97
|
+
* - Always clean up resources before exit
|
|
98
|
+
* - Exit with code 0 for graceful shutdown
|
|
99
|
+
* - Exit with code 1 for error conditions
|
|
100
|
+
* - Log shutdown reasons to stderr
|
|
101
|
+
*/
|
|
102
|
+
function setupShutdownHandlers() {
|
|
103
|
+
const handleShutdown = async (signal) => {
|
|
104
|
+
console.error(`\nReceived ${signal}, shutting down gracefully...`);
|
|
105
|
+
try {
|
|
106
|
+
await shutdownServer();
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
111
|
+
console.error(`Error during shutdown: ${errorMessage}`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
// PATTERN: Handle standard termination signals
|
|
116
|
+
process.on('SIGINT', () => handleShutdown('SIGINT')); // Ctrl+C
|
|
117
|
+
process.on('SIGTERM', () => handleShutdown('SIGTERM')); // Kill command
|
|
118
|
+
process.on('SIGHUP', () => handleShutdown('SIGHUP')); // Terminal closed
|
|
119
|
+
// PATTERN: Handle unexpected errors gracefully
|
|
120
|
+
process.on('uncaughtException', async (error) => {
|
|
121
|
+
console.error('Uncaught exception:', error);
|
|
122
|
+
await shutdownServer();
|
|
123
|
+
process.exit(1);
|
|
124
|
+
});
|
|
125
|
+
process.on('unhandledRejection', async (reason) => {
|
|
126
|
+
console.error('Unhandled rejection:', reason);
|
|
127
|
+
await shutdownServer();
|
|
128
|
+
process.exit(1);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// STARTUP
|
|
133
|
+
// =============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* PATTERN: ES Module entry point detection
|
|
136
|
+
* Source: Node.js ES modules best practice
|
|
137
|
+
*
|
|
138
|
+
* In ES modules, we need to:
|
|
139
|
+
* 1. Convert import.meta.url to file path
|
|
140
|
+
* 2. Check if current file is the entry point
|
|
141
|
+
* 3. Handle both TypeScript (.ts) and compiled (.js) extensions
|
|
142
|
+
*
|
|
143
|
+
* This ensures the server only starts when run directly,
|
|
144
|
+
* not when imported as a module.
|
|
145
|
+
*/
|
|
146
|
+
// Run the main function if this file is executed directly
|
|
147
|
+
// In ES modules, we check if process.argv[1] ends with our filename
|
|
148
|
+
import { fileURLToPath } from 'url';
|
|
149
|
+
import { dirname } from 'path';
|
|
150
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
151
|
+
const __dirname = dirname(__filename);
|
|
152
|
+
// Check if this script is being run directly
|
|
153
|
+
if (process.argv[1] === __filename || process.argv[1].endsWith('mcp-server-cli.js')) {
|
|
154
|
+
main().catch((error) => {
|
|
155
|
+
console.error('Startup error:', error);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔒 LOCKED by @docs-agent | Change to 🔑 to allow @docs-agent edits
|
|
3
|
+
*
|
|
4
|
+
* OFFICIAL DOCS: @modelcontextprotocol/sdk v1.0.0
|
|
5
|
+
* Last Verified: 2025-09-01
|
|
6
|
+
*
|
|
7
|
+
* Claude-mem MCP Server Core Implementation
|
|
8
|
+
*
|
|
9
|
+
* This module provides the standalone MCP server that wraps the WeaviateMCPAdapter
|
|
10
|
+
* and exposes it via the Model Context Protocol for Claude Code integration.
|
|
11
|
+
*
|
|
12
|
+
* Key Features:
|
|
13
|
+
* - Implements MCP server using @modelcontextprotocol/sdk/server
|
|
14
|
+
* - Exposes standard MCP memory tools: create_entities, create_relations, search_nodes, etc.
|
|
15
|
+
* - Uses WeaviateMCPAdapter as backend storage engine (embedded Weaviate)
|
|
16
|
+
* - Handles stdio communication with Claude Code
|
|
17
|
+
* - Comprehensive error handling and logging
|
|
18
|
+
* - Zero external dependencies beyond embedded Weaviate
|
|
19
|
+
*
|
|
20
|
+
* Architecture:
|
|
21
|
+
* Claude Code ←→ MCP Server (stdio) ←→ WeaviateMCPAdapter ←→ Embedded Weaviate
|
|
22
|
+
*
|
|
23
|
+
* Implementation follows official MCP SDK patterns:
|
|
24
|
+
* - Low-level Server class for direct request handling (see SDK README.md#_snippet_25)
|
|
25
|
+
* - setRequestHandler with CallToolRequestSchema for tool routing
|
|
26
|
+
* - Proper error handling with isError flag in responses
|
|
27
|
+
* - Console.error for logging (stderr for debugging, stdout for protocol)
|
|
28
|
+
*
|
|
29
|
+
* @see docs/mcp-sdk/server-implementation.md for detailed patterns
|
|
30
|
+
*/
|
|
31
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
32
|
+
import { WeaviateMCPAdapter } from './utils/weaviate-mcp-adapter.js';
|
|
33
|
+
/**
|
|
34
|
+
* Create and configure the MCP server instance
|
|
35
|
+
*
|
|
36
|
+
* OFFICIAL PATTERN: Low-level Server implementation
|
|
37
|
+
* Source: @modelcontextprotocol/sdk README.md#_snippet_25
|
|
38
|
+
*
|
|
39
|
+
* Using the low-level Server class (not McpServer) provides:
|
|
40
|
+
* - Direct control over request handling via setRequestHandler
|
|
41
|
+
* - Custom tool routing logic with CallToolRequestSchema
|
|
42
|
+
* - Fine-grained error handling per tool
|
|
43
|
+
*
|
|
44
|
+
* Server constructor params:
|
|
45
|
+
* - First param: Server metadata (name, version)
|
|
46
|
+
* - Second param: Server options with capabilities declaration
|
|
47
|
+
* - capabilities.tools: {} indicates this server provides tools
|
|
48
|
+
*/
|
|
49
|
+
declare const server: Server<{
|
|
50
|
+
method: string;
|
|
51
|
+
params?: import("zod").objectOutputType<{
|
|
52
|
+
_meta: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
53
|
+
progressToken: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodNumber]>>;
|
|
54
|
+
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
|
55
|
+
progressToken: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodNumber]>>;
|
|
56
|
+
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
|
57
|
+
progressToken: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodNumber]>>;
|
|
58
|
+
}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
59
|
+
}, import("zod").ZodTypeAny, "passthrough"> | undefined;
|
|
60
|
+
}, {
|
|
61
|
+
method: string;
|
|
62
|
+
params?: import("zod").objectOutputType<{
|
|
63
|
+
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
64
|
+
}, import("zod").ZodTypeAny, "passthrough"> | undefined;
|
|
65
|
+
}, import("zod").objectOutputType<{
|
|
66
|
+
_meta: import("zod").ZodOptional<import("zod").ZodObject<{}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{}, import("zod").ZodTypeAny, "passthrough">>>;
|
|
67
|
+
}, import("zod").ZodTypeAny, "passthrough">>;
|
|
68
|
+
/**
|
|
69
|
+
* Create the Weaviate adapter instance
|
|
70
|
+
*/
|
|
71
|
+
declare const adapter: WeaviateMCPAdapter;
|
|
72
|
+
/**
|
|
73
|
+
* Initialize the server and adapter connections
|
|
74
|
+
*
|
|
75
|
+
* PATTERN: Server initialization separate from transport connection
|
|
76
|
+
* Source: SDK patterns show initialization logic before transport.connect()
|
|
77
|
+
*
|
|
78
|
+
* Best Practices:
|
|
79
|
+
* - Initialize backend connections before server.connect(transport)
|
|
80
|
+
* - Use console.error for status messages (won't interfere with stdio)
|
|
81
|
+
* - Throw errors to prevent server startup if initialization fails
|
|
82
|
+
*/
|
|
83
|
+
declare function initializeServer(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Gracefully shutdown the server and adapter connections
|
|
86
|
+
*
|
|
87
|
+
* PATTERN: Graceful shutdown handling
|
|
88
|
+
* Source: SDK examples show cleanup in shutdown handlers
|
|
89
|
+
*
|
|
90
|
+
* Best Practices:
|
|
91
|
+
* - Clean up backend connections when server shuts down
|
|
92
|
+
* - Log but don't throw errors during shutdown (best effort)
|
|
93
|
+
* - Use console.error for shutdown messages
|
|
94
|
+
*/
|
|
95
|
+
declare function shutdownServer(): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Export server and adapter for use by the CLI entry point
|
|
98
|
+
*/
|
|
99
|
+
export { server, adapter, initializeServer, shutdownServer };
|
|
100
|
+
/**
|
|
101
|
+
* Default export provides the configured server instance
|
|
102
|
+
*/
|
|
103
|
+
export default server;
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔒 LOCKED by @docs-agent | Change to 🔑 to allow @docs-agent edits
|
|
3
|
+
*
|
|
4
|
+
* OFFICIAL DOCS: @modelcontextprotocol/sdk v1.0.0
|
|
5
|
+
* Last Verified: 2025-09-01
|
|
6
|
+
*
|
|
7
|
+
* Claude-mem MCP Server Core Implementation
|
|
8
|
+
*
|
|
9
|
+
* This module provides the standalone MCP server that wraps the WeaviateMCPAdapter
|
|
10
|
+
* and exposes it via the Model Context Protocol for Claude Code integration.
|
|
11
|
+
*
|
|
12
|
+
* Key Features:
|
|
13
|
+
* - Implements MCP server using @modelcontextprotocol/sdk/server
|
|
14
|
+
* - Exposes standard MCP memory tools: create_entities, create_relations, search_nodes, etc.
|
|
15
|
+
* - Uses WeaviateMCPAdapter as backend storage engine (embedded Weaviate)
|
|
16
|
+
* - Handles stdio communication with Claude Code
|
|
17
|
+
* - Comprehensive error handling and logging
|
|
18
|
+
* - Zero external dependencies beyond embedded Weaviate
|
|
19
|
+
*
|
|
20
|
+
* Architecture:
|
|
21
|
+
* Claude Code ←→ MCP Server (stdio) ←→ WeaviateMCPAdapter ←→ Embedded Weaviate
|
|
22
|
+
*
|
|
23
|
+
* Implementation follows official MCP SDK patterns:
|
|
24
|
+
* - Low-level Server class for direct request handling (see SDK README.md#_snippet_25)
|
|
25
|
+
* - setRequestHandler with CallToolRequestSchema for tool routing
|
|
26
|
+
* - Proper error handling with isError flag in responses
|
|
27
|
+
* - Console.error for logging (stderr for debugging, stdout for protocol)
|
|
28
|
+
*
|
|
29
|
+
* @see docs/mcp-sdk/server-implementation.md for detailed patterns
|
|
30
|
+
*/
|
|
31
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
32
|
+
import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
33
|
+
import { WeaviateMCPAdapter } from './utils/weaviate-mcp-adapter.js';
|
|
34
|
+
import { WEAVIATE_MESSAGES } from './constants.js';
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// MCP SERVER CONFIGURATION
|
|
37
|
+
// =============================================================================
|
|
38
|
+
/**
|
|
39
|
+
* Create and configure the MCP server instance
|
|
40
|
+
*
|
|
41
|
+
* OFFICIAL PATTERN: Low-level Server implementation
|
|
42
|
+
* Source: @modelcontextprotocol/sdk README.md#_snippet_25
|
|
43
|
+
*
|
|
44
|
+
* Using the low-level Server class (not McpServer) provides:
|
|
45
|
+
* - Direct control over request handling via setRequestHandler
|
|
46
|
+
* - Custom tool routing logic with CallToolRequestSchema
|
|
47
|
+
* - Fine-grained error handling per tool
|
|
48
|
+
*
|
|
49
|
+
* Server constructor params:
|
|
50
|
+
* - First param: Server metadata (name, version)
|
|
51
|
+
* - Second param: Server options with capabilities declaration
|
|
52
|
+
* - capabilities.tools: {} indicates this server provides tools
|
|
53
|
+
*/
|
|
54
|
+
const server = new Server({
|
|
55
|
+
name: 'claude-mem',
|
|
56
|
+
version: '3.0.1',
|
|
57
|
+
}, {
|
|
58
|
+
capabilities: {
|
|
59
|
+
tools: {}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* Create the Weaviate adapter instance
|
|
64
|
+
*/
|
|
65
|
+
const adapter = new WeaviateMCPAdapter();
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// MCP TOOL HANDLERS
|
|
68
|
+
// =============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Register the main tool handler that routes requests to appropriate adapter methods
|
|
71
|
+
*
|
|
72
|
+
* OFFICIAL PATTERN: Tool request handling with CallToolRequestSchema
|
|
73
|
+
* Source: @modelcontextprotocol/sdk types.js - CallToolRequestSchema
|
|
74
|
+
*
|
|
75
|
+
* Best Practices:
|
|
76
|
+
* - Single setRequestHandler for CallToolRequestSchema handles all tools
|
|
77
|
+
* - Switch statement routes to specific tool implementations
|
|
78
|
+
* - Each tool validates its arguments before processing
|
|
79
|
+
* - Return format: { content: [{ type: 'text', text: string }] }
|
|
80
|
+
* - Error format: { content: [...], isError: true } for tool errors
|
|
81
|
+
*
|
|
82
|
+
* The request parameter contains:
|
|
83
|
+
* - params.name: The tool name being called
|
|
84
|
+
* - params.arguments: The tool arguments as a JSON object
|
|
85
|
+
*/
|
|
86
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
87
|
+
const { name, arguments: args } = request.params;
|
|
88
|
+
try {
|
|
89
|
+
// Ensure adapter connection before any operation
|
|
90
|
+
await adapter.connect();
|
|
91
|
+
// Validate that args is defined
|
|
92
|
+
if (!args) {
|
|
93
|
+
throw new Error(`No arguments provided for tool: ${name}`);
|
|
94
|
+
}
|
|
95
|
+
switch (name) {
|
|
96
|
+
case 'create_entities': {
|
|
97
|
+
// PATTERN: Tool argument validation before processing
|
|
98
|
+
// Always validate required parameters exist and have correct type
|
|
99
|
+
if (!args.entities || !Array.isArray(args.entities)) {
|
|
100
|
+
throw new Error('create_entities requires an entities array parameter');
|
|
101
|
+
}
|
|
102
|
+
const entities = args.entities;
|
|
103
|
+
await adapter.createEntities(entities);
|
|
104
|
+
// PATTERN: Standard MCP tool response format
|
|
105
|
+
// Source: SDK examples show content array with type/text objects
|
|
106
|
+
return {
|
|
107
|
+
content: [{
|
|
108
|
+
type: 'text',
|
|
109
|
+
text: `Successfully created ${entities.length} entities in embedded Weaviate`
|
|
110
|
+
}]
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
case 'create_relations': {
|
|
114
|
+
if (!args.relations || !Array.isArray(args.relations)) {
|
|
115
|
+
throw new Error('create_relations requires a relations array parameter');
|
|
116
|
+
}
|
|
117
|
+
const relations = args.relations;
|
|
118
|
+
await adapter.createRelations(relations);
|
|
119
|
+
return {
|
|
120
|
+
content: [{
|
|
121
|
+
type: 'text',
|
|
122
|
+
text: `Successfully created ${relations.length} relations in embedded Weaviate`
|
|
123
|
+
}]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
case 'search_nodes': {
|
|
127
|
+
if (!args.query || typeof args.query !== 'string') {
|
|
128
|
+
throw new Error('search_nodes requires a query string parameter');
|
|
129
|
+
}
|
|
130
|
+
const searchResults = await adapter.searchNodes(args.query);
|
|
131
|
+
return {
|
|
132
|
+
content: [{
|
|
133
|
+
type: 'text',
|
|
134
|
+
text: JSON.stringify(searchResults, null, 2)
|
|
135
|
+
}]
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
case 'open_nodes': {
|
|
139
|
+
if (!args.names || !Array.isArray(args.names)) {
|
|
140
|
+
throw new Error('open_nodes requires a names array parameter');
|
|
141
|
+
}
|
|
142
|
+
const nodes = await adapter.openNodes(args.names);
|
|
143
|
+
return {
|
|
144
|
+
content: [{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: JSON.stringify(nodes, null, 2)
|
|
147
|
+
}]
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
case 'delete_entities': {
|
|
151
|
+
if (!args.entityNames || !Array.isArray(args.entityNames)) {
|
|
152
|
+
throw new Error('delete_entities requires an entityNames array parameter');
|
|
153
|
+
}
|
|
154
|
+
// Note: WeaviateMCPAdapter doesn't implement deleteEntities yet
|
|
155
|
+
// This is a placeholder for future implementation
|
|
156
|
+
throw new Error('delete_entities is not yet implemented in the embedded Weaviate adapter');
|
|
157
|
+
}
|
|
158
|
+
case 'delete_relations': {
|
|
159
|
+
if (!args.relations || !Array.isArray(args.relations)) {
|
|
160
|
+
throw new Error('delete_relations requires a relations array parameter');
|
|
161
|
+
}
|
|
162
|
+
// Note: WeaviateMCPAdapter doesn't implement deleteRelations yet
|
|
163
|
+
// This is a placeholder for future implementation
|
|
164
|
+
throw new Error('delete_relations is not yet implemented in the embedded Weaviate adapter');
|
|
165
|
+
}
|
|
166
|
+
case 'add_observations': {
|
|
167
|
+
if (!args.observations || !Array.isArray(args.observations)) {
|
|
168
|
+
throw new Error('add_observations requires an observations array parameter');
|
|
169
|
+
}
|
|
170
|
+
// Note: WeaviateMCPAdapter doesn't implement addObservations yet
|
|
171
|
+
// This is a placeholder for future implementation
|
|
172
|
+
throw new Error('add_observations is not yet implemented in the embedded Weaviate adapter');
|
|
173
|
+
}
|
|
174
|
+
case 'delete_observations': {
|
|
175
|
+
if (!args.deletions || !Array.isArray(args.deletions)) {
|
|
176
|
+
throw new Error('delete_observations requires a deletions array parameter');
|
|
177
|
+
}
|
|
178
|
+
// Note: WeaviateMCPAdapter doesn't implement deleteObservations yet
|
|
179
|
+
// This is a placeholder for future implementation
|
|
180
|
+
throw new Error('delete_observations is not yet implemented in the embedded Weaviate adapter');
|
|
181
|
+
}
|
|
182
|
+
case 'read_graph': {
|
|
183
|
+
// Note: WeaviateMCPAdapter doesn't implement readGraph yet
|
|
184
|
+
// This is a placeholder for future implementation
|
|
185
|
+
throw new Error('read_graph is not yet implemented in the embedded Weaviate adapter');
|
|
186
|
+
}
|
|
187
|
+
default:
|
|
188
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
193
|
+
// PATTERN: Error logging to stderr
|
|
194
|
+
// Source: MCP SDK convention - stderr for logs, stdout for protocol
|
|
195
|
+
// This allows debugging without interfering with stdio transport
|
|
196
|
+
console.error(`[MCP Server Error] Tool: ${name}, Error: ${errorMessage}`);
|
|
197
|
+
// PATTERN: Error response format with isError flag
|
|
198
|
+
// Source: SDK README.md#_snippet_22 (SQLite example shows isError usage)
|
|
199
|
+
// The isError flag indicates to clients that the tool execution failed
|
|
200
|
+
return {
|
|
201
|
+
content: [{
|
|
202
|
+
type: 'text',
|
|
203
|
+
text: `Error: ${errorMessage}`
|
|
204
|
+
}],
|
|
205
|
+
isError: true
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
// =============================================================================
|
|
210
|
+
// SERVER LIFECYCLE MANAGEMENT
|
|
211
|
+
// =============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Initialize the server and adapter connections
|
|
214
|
+
*
|
|
215
|
+
* PATTERN: Server initialization separate from transport connection
|
|
216
|
+
* Source: SDK patterns show initialization logic before transport.connect()
|
|
217
|
+
*
|
|
218
|
+
* Best Practices:
|
|
219
|
+
* - Initialize backend connections before server.connect(transport)
|
|
220
|
+
* - Use console.error for status messages (won't interfere with stdio)
|
|
221
|
+
* - Throw errors to prevent server startup if initialization fails
|
|
222
|
+
*/
|
|
223
|
+
async function initializeServer() {
|
|
224
|
+
try {
|
|
225
|
+
// Connect to embedded Weaviate before accepting MCP requests
|
|
226
|
+
console.error(WEAVIATE_MESSAGES.SETUP.STARTING_EMBEDDED);
|
|
227
|
+
await adapter.connect();
|
|
228
|
+
console.error(WEAVIATE_MESSAGES.SETUP.EMBEDDED_READY);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
232
|
+
console.error(`Failed to initialize embedded Weaviate: ${errorMessage}`);
|
|
233
|
+
throw error; // Propagate to prevent server startup
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Gracefully shutdown the server and adapter connections
|
|
238
|
+
*
|
|
239
|
+
* PATTERN: Graceful shutdown handling
|
|
240
|
+
* Source: SDK examples show cleanup in shutdown handlers
|
|
241
|
+
*
|
|
242
|
+
* Best Practices:
|
|
243
|
+
* - Clean up backend connections when server shuts down
|
|
244
|
+
* - Log but don't throw errors during shutdown (best effort)
|
|
245
|
+
* - Use console.error for shutdown messages
|
|
246
|
+
*/
|
|
247
|
+
async function shutdownServer() {
|
|
248
|
+
try {
|
|
249
|
+
console.error('Shutting down claude-mem MCP server...');
|
|
250
|
+
await adapter.disconnect();
|
|
251
|
+
console.error(WEAVIATE_MESSAGES.CONNECTION.DISCONNECTED);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
255
|
+
console.error(`Error during shutdown: ${errorMessage}`);
|
|
256
|
+
// Don't throw - best effort shutdown
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// =============================================================================
|
|
260
|
+
// EXPORTS
|
|
261
|
+
// =============================================================================
|
|
262
|
+
/**
|
|
263
|
+
* Export server and adapter for use by the CLI entry point
|
|
264
|
+
*/
|
|
265
|
+
export { server, adapter, initializeServer, shutdownServer };
|
|
266
|
+
/**
|
|
267
|
+
* Default export provides the configured server instance
|
|
268
|
+
*/
|
|
269
|
+
export default server;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export interface HookPayload {
|
|
2
|
+
session_id: string;
|
|
3
|
+
transcript_path: string;
|
|
4
|
+
hook_event_name: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PreCompactPayload extends HookPayload {
|
|
7
|
+
hook_event_name: 'PreCompact';
|
|
8
|
+
trigger: 'manual' | 'auto';
|
|
9
|
+
custom_instructions?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SessionStartPayload extends HookPayload {
|
|
12
|
+
hook_event_name: 'SessionStart';
|
|
13
|
+
source: 'startup' | 'compact' | 'vscode' | 'web';
|
|
14
|
+
}
|
|
15
|
+
export interface UserPromptSubmitPayload extends HookPayload {
|
|
16
|
+
hook_event_name: 'UserPromptSubmit';
|
|
17
|
+
prompt: string;
|
|
18
|
+
cwd: string;
|
|
19
|
+
}
|
|
20
|
+
export interface PreToolUsePayload extends HookPayload {
|
|
21
|
+
hook_event_name: 'PreToolUse';
|
|
22
|
+
tool_name: string;
|
|
23
|
+
tool_input: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export interface PostToolUsePayload extends HookPayload {
|
|
26
|
+
hook_event_name: 'PostToolUse';
|
|
27
|
+
tool_name: string;
|
|
28
|
+
tool_input: Record<string, unknown>;
|
|
29
|
+
tool_response: Record<string, unknown> & {
|
|
30
|
+
success?: boolean;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface NotificationPayload extends HookPayload {
|
|
34
|
+
hook_event_name: 'Notification';
|
|
35
|
+
message: string;
|
|
36
|
+
title?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface StopPayload extends HookPayload {
|
|
39
|
+
hook_event_name: 'Stop';
|
|
40
|
+
stop_hook_active: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface BaseHookResponse {
|
|
43
|
+
continue?: boolean;
|
|
44
|
+
stopReason?: string;
|
|
45
|
+
suppressOutput?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface PreCompactResponse extends BaseHookResponse {
|
|
48
|
+
decision?: 'approve' | 'block';
|
|
49
|
+
reason?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface SessionStartResponse extends BaseHookResponse {
|
|
52
|
+
hookSpecificOutput?: {
|
|
53
|
+
hookEventName: 'SessionStart';
|
|
54
|
+
additionalContext?: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export interface PreToolUseResponse extends BaseHookResponse {
|
|
58
|
+
permissionDecision?: 'allow' | 'deny' | 'ask';
|
|
59
|
+
permissionDecisionReason?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface CompressionResult {
|
|
62
|
+
compressedLines: string[];
|
|
63
|
+
originalTokens: number;
|
|
64
|
+
compressedTokens: number;
|
|
65
|
+
compressionRatio: number;
|
|
66
|
+
memoryNodes: string[];
|
|
67
|
+
}
|
|
68
|
+
export interface MemoryNode {
|
|
69
|
+
id: string;
|
|
70
|
+
type: 'entity' | 'relation';
|
|
71
|
+
content: string;
|
|
72
|
+
timestamp: string;
|
|
73
|
+
metadata?: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
export declare class HookError extends Error {
|
|
76
|
+
hookType: string;
|
|
77
|
+
payload?: HookPayload | undefined;
|
|
78
|
+
code?: string | undefined;
|
|
79
|
+
constructor(message: string, hookType: string, payload?: HookPayload | undefined, code?: string | undefined);
|
|
80
|
+
}
|
|
81
|
+
export declare class CompressionError extends Error {
|
|
82
|
+
transcriptPath: string;
|
|
83
|
+
stage: 'reading' | 'analyzing' | 'compressing' | 'writing';
|
|
84
|
+
constructor(message: string, transcriptPath: string, stage: 'reading' | 'analyzing' | 'compressing' | 'writing');
|
|
85
|
+
}
|
|
86
|
+
export interface Logger {
|
|
87
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
88
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
89
|
+
error(message: string, error?: Error, meta?: Record<string, unknown>): void;
|
|
90
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
91
|
+
}
|
|
92
|
+
export declare class FileLogger implements Logger {
|
|
93
|
+
private logFile;
|
|
94
|
+
private enableDebug;
|
|
95
|
+
constructor(logFile: string, enableDebug?: boolean);
|
|
96
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
97
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
98
|
+
error(message: string, error?: Error, meta?: Record<string, unknown>): void;
|
|
99
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
100
|
+
private log;
|
|
101
|
+
}
|
|
102
|
+
export declare function validateHookPayload(payload: unknown, expectedType: string): HookPayload;
|
|
103
|
+
export declare function createSuccessResponse(additionalData?: Record<string, unknown>): BaseHookResponse;
|
|
104
|
+
export declare function createErrorResponse(reason: string, additionalData?: Record<string, unknown>): BaseHookResponse;
|
|
105
|
+
/**
|
|
106
|
+
* Main settings interface for claude-mem configuration
|
|
107
|
+
*/
|
|
108
|
+
export interface Settings {
|
|
109
|
+
autoCompress?: boolean;
|
|
110
|
+
projectName?: string;
|
|
111
|
+
installed?: boolean;
|
|
112
|
+
[key: string]: unknown;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Entity structure for MCP operations
|
|
116
|
+
*/
|
|
117
|
+
export interface MCPEntity {
|
|
118
|
+
name: string;
|
|
119
|
+
entityType: string;
|
|
120
|
+
observations: string[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Relation structure for MCP operations
|
|
124
|
+
*/
|
|
125
|
+
export interface MCPRelation {
|
|
126
|
+
from: string;
|
|
127
|
+
to: string;
|
|
128
|
+
relationType: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Search result structure from MCP operations
|
|
132
|
+
*/
|
|
133
|
+
export interface MCPSearchResult {
|
|
134
|
+
entities?: MCPEntity[];
|
|
135
|
+
relations?: MCPRelation[];
|
|
136
|
+
[key: string]: unknown;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Interface for MCP client implementations (memory and Weaviate)
|
|
140
|
+
*/
|
|
141
|
+
export interface IMCPClient {
|
|
142
|
+
connect(): Promise<void>;
|
|
143
|
+
disconnect(): Promise<void>;
|
|
144
|
+
createEntities(entities: MCPEntity[]): Promise<void>;
|
|
145
|
+
createRelations(relations: MCPRelation[]): Promise<void>;
|
|
146
|
+
searchNodes(query: string): Promise<MCPSearchResult>;
|
|
147
|
+
openNodes(names: string[]): Promise<MCPSearchResult>;
|
|
148
|
+
}
|