vault backup: 2026-01-08 09:34:22
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Memvid MCP Search Helper
|
||||
*
|
||||
* Usage: node memvid-search.js <memory_file_path> <query> [top_k] [snippet_chars]
|
||||
*
|
||||
* This script calls the Memvid MCP server to perform semantic search.
|
||||
*/
|
||||
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Parse arguments
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length < 2) {
|
||||
console.error('Usage: node memvid-search.js <memory_file_path> <query> [top_k] [snippet_chars]');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const memoryFilePath = args[0];
|
||||
const query = args[1];
|
||||
const topK = parseInt(args[2]) || 3;
|
||||
const snippetChars = parseInt(args[3]) || 500;
|
||||
|
||||
// Validate memory file exists
|
||||
if (!fs.existsSync(memoryFilePath)) {
|
||||
console.error(JSON.stringify({ error: `Memory file not found: ${memoryFilePath}` }));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// MCP configuration (from .claude/mcp.json)
|
||||
const mcpCommand = 'uv';
|
||||
const mcpArgs = [
|
||||
'run',
|
||||
'--directory',
|
||||
'D:\\works\\projects-windows\\memvid-agent-mcp',
|
||||
'memvid_mcp_server.py'
|
||||
];
|
||||
|
||||
const mcpEnv = {
|
||||
...process.env,
|
||||
PYTHONUNBUFFERED: '1',
|
||||
MEMVID_LOG_LEVEL: 'ERROR' // Reduce noise
|
||||
};
|
||||
|
||||
// JSON-RPC communication
|
||||
let messageId = 1;
|
||||
|
||||
function createRequest(method, params = {}) {
|
||||
return {
|
||||
jsonrpc: '2.0',
|
||||
id: messageId++,
|
||||
method,
|
||||
params
|
||||
};
|
||||
}
|
||||
|
||||
function sendRequest(proc, request) {
|
||||
const message = JSON.stringify(request) + '\n';
|
||||
proc.stdin.write(message);
|
||||
}
|
||||
|
||||
// Main execution
|
||||
async function main() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(mcpCommand, mcpArgs, {
|
||||
env: mcpEnv,
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
});
|
||||
|
||||
let outputBuffer = '';
|
||||
let errorBuffer = '';
|
||||
let initialized = false;
|
||||
let searchRequestSent = false;
|
||||
let timeoutId = null;
|
||||
|
||||
function cleanup() {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
proc.kill();
|
||||
}
|
||||
|
||||
proc.stdout.on('data', (data) => {
|
||||
outputBuffer += data.toString();
|
||||
|
||||
// Process complete JSON-RPC messages
|
||||
const lines = outputBuffer.split('\n');
|
||||
outputBuffer = lines.pop() || ''; // Keep incomplete line
|
||||
|
||||
for (const line of lines) {
|
||||
if (!line.trim()) continue;
|
||||
|
||||
try {
|
||||
const response = JSON.parse(line);
|
||||
|
||||
// Handle initialization
|
||||
if (!initialized && response.id === 1) {
|
||||
initialized = true;
|
||||
|
||||
// Send search request
|
||||
const searchRequest = createRequest('tools/call', {
|
||||
name: 'memvid_search',
|
||||
arguments: {
|
||||
file_path: memoryFilePath,
|
||||
query: query,
|
||||
top_k: topK,
|
||||
snippet_chars: snippetChars
|
||||
}
|
||||
});
|
||||
|
||||
sendRequest(proc, searchRequest);
|
||||
searchRequestSent = true;
|
||||
}
|
||||
// Handle search result
|
||||
else if (searchRequestSent && response.result) {
|
||||
console.log(JSON.stringify({
|
||||
success: true,
|
||||
result: response.result
|
||||
}));
|
||||
|
||||
cleanup();
|
||||
setTimeout(() => process.exit(0), 100);
|
||||
resolve();
|
||||
}
|
||||
// Handle errors
|
||||
else if (response.error) {
|
||||
console.error(JSON.stringify({
|
||||
error: response.error.message || 'MCP error'
|
||||
}));
|
||||
|
||||
cleanup();
|
||||
setTimeout(() => process.exit(1), 100);
|
||||
reject(new Error(response.error.message));
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore non-JSON lines (logs, etc.)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
proc.stderr.on('data', (data) => {
|
||||
errorBuffer += data.toString();
|
||||
});
|
||||
|
||||
proc.on('error', (error) => {
|
||||
console.error(JSON.stringify({ error: error.message }));
|
||||
cleanup();
|
||||
reject(error);
|
||||
});
|
||||
|
||||
proc.on('exit', (code) => {
|
||||
if (code !== 0 && code !== null) {
|
||||
console.error(JSON.stringify({
|
||||
error: `MCP server exited with code ${code}`,
|
||||
stderr: errorBuffer
|
||||
}));
|
||||
reject(new Error(`Process exited with code ${code}`));
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize MCP connection
|
||||
const initRequest = createRequest('initialize', {
|
||||
protocolVersion: '2024-11-05',
|
||||
capabilities: {},
|
||||
clientInfo: {
|
||||
name: 'claudian-memvid-helper',
|
||||
version: '1.0.0'
|
||||
}
|
||||
});
|
||||
|
||||
sendRequest(proc, initRequest);
|
||||
|
||||
// Timeout after 10 seconds
|
||||
timeoutId = setTimeout(() => {
|
||||
proc.kill();
|
||||
console.error(JSON.stringify({ error: 'Search timeout' }));
|
||||
reject(new Error('Timeout'));
|
||||
}, 10000);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user