const http = require('http');
const MCP_PORT = 3000;
function sendJsonRpc(method, params) {
return new Promise((resolve, reject) => {
const payload = JSON.stringify({
jsonrpc: "2.0",
method: "tools/call",
params: {
name: method,
arguments: params
},
id: Date.now()
});
const options = {
hostname: '127.0.0.1',
port: MCP_PORT,
path: '/messages',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload)
}
};
const req = http.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
const json = JSON.parse(body);
if (json.error) reject(json.error);
else resolve(json.result);
} catch (e) {
reject(new Error(`Invalid JSON: ${body}`));
}
} else {
reject(new Error(`HTTP Error ${res.statusCode}: ${body}`));
}
});
});
req.on('error', reject);
req.write(payload);
req.end();
});
}
function parseContent(result) {
if (!result || !result.content || !result.content[0] || !result.content[0].text) {
return null;
}
try {
const text = result.content[0].text;
// Text might be a plain string or JSON string depending on tool
if (text.startsWith('[') || text.startsWith('{')) {
return JSON.parse(text);
}
return text;
} catch (e) {
return result.content[0].text;
}
}
async function main() {
try {
console.log("=== Testing MCP Features CRUD ===\n");
// 1. Save Document
console.log("1. Saving document: 'The quick brown fox jumps over the lazy dog.'");
const saveRes = await sendJsonRpc('save_document', {
content: "The quick brown fox jumps over the lazy dog.",
document_name: "test/fox.txt"
});
const saveMsg = parseContent(saveRes);
console.log(" Result:", saveMsg);
// Extract ID from message "Saved document with id 123"
const idMatch = saveMsg.match(/id (\d+)/);
if (!idMatch) throw new Error("Could not parse ID from save response");
const id = parseInt(idMatch[1]);
console.log(" Target ID:", id);
// 1.5 Get Documents Count
console.log("\n1.5 Getting documents count");
const countRes = await sendJsonRpc('get_documents_count', {});
const countMsg = parseContent(countRes);
console.log(" Count:", countMsg);
// 1.8 List Documents (Oldest First)
console.log("\n1.8 Listing documents (limit=3, offset=0)");
const listRes = await sendJsonRpc('list_documents', { limit: 3, offset: 0 });
const listItems = parseContent(listRes);
console.log(" Items returned:", listItems.length);
if (listItems.length > 0) {
console.log(" First item ID:", listItems[0].id);
}
// 1.9 Read Recent Items (Newest First)
console.log("\n1.9 Reading recent items (limit=3)");
const recentRes = await sendJsonRpc('read_recent_items', { limit: 3 });
const recentItems = parseContent(recentRes);
console.log(" Items returned:", recentItems.length);
if (recentItems.length > 0) {
console.log(" First (Newest) item ID:", recentItems[0].id);
}
// 2. Find Documents
console.log("\n2. Finding documents for 'brown fox'");
const findRes = await sendJsonRpc('find_documents', {
content: "brown fox",
limit: 1
});
const foundDocs = parseContent(findRes);
console.log(" Found:", foundDocs.length, "documents");
if (foundDocs.length > 0) {
console.log(" Top match ID:", foundDocs[0].id);
console.log(" Top match content:", foundDocs[0].content);
}
// 3. Get Document
console.log(`\n3. Getting document by ID: ${id}`);
const getDocRes = await sendJsonRpc('get_document', { id: id });
const docContent = parseContent(getDocRes);
console.log(" Content:", docContent);
if (docContent !== "The quick brown fox jumps over the lazy dog.") {
console.error(" MISMATCH! Expected original content.");
}
// 4. Get Vector
console.log(`\n4. Getting vector by ID: ${id}`);
const getVecRes = await sendJsonRpc('get_vector', { id: id });
const vector = parseContent(getVecRes);
console.log(" Vector length:", vector.length);
if (vector.length !== 768) {
console.error(" MISMATCH! Expected 768 dimensions.");
}
// 5. Find by Vector (using the vector we just got)
console.log("\n5. Finding by vector (using retrieved vector)");
const findByVecRes = await sendJsonRpc('find_by_vector', {
vector: vector,
limit: 1
});
const vecDocs = parseContent(findByVecRes);
console.log(" Found:", vecDocs.length, "documents");
if (vecDocs.length > 0 && vecDocs[0].id === id) {
console.log(" Success: Retrieved self via vector search.");
} else {
console.error(" Failure: Did not retrieve self.");
}
// 6. Delete Item
console.log(`\n6. Deleting item ID: ${id}`);
const delRes = await sendJsonRpc('delete_item', { id: id });
console.log(" Result:", parseContent(delRes));
// 7. Verify Deletion
console.log("\n7. Verifying deletion (Get Document)");
try {
await sendJsonRpc('get_document', { id: id });
console.error(" ERROR: Item should be gone, but get_document succeeded.");
} catch (e) {
console.log(" Success: get_document failed as expected:", e.message);
}
console.log("\n=== Test Complete ===");
} catch (error) {
console.error("Test Failed:", error);
}
}
main();