#!/usr/bin/env node
/**
* Test direct tool calls to verify cloud persistence
* Simulates multiple tool calls and verifies database updates
*/
require('dotenv').config();
const { spawn } = require('child_process');
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.SUPABASE_SERVICE_ROLE_KEY
);
// Helper to send MCP JSON-RPC request
function sendMCPRequest(server, request) {
return new Promise((resolve, reject) => {
const jsonRequest = JSON.stringify(request) + '\n';
let response = '';
const timeout = setTimeout(() => {
reject(new Error('Request timeout'));
}, 5000);
const onData = (data) => {
response += data.toString();
const lines = response.split('\n');
for (const line of lines) {
if (line.trim()) {
try {
const parsed = JSON.parse(line);
if (parsed.id === request.id) {
clearTimeout(timeout);
server.stdout.off('data', onData);
resolve(parsed);
return;
}
} catch (e) {
// Not complete JSON yet, keep accumulating
}
}
}
};
server.stdout.on('data', onData);
server.stdin.write(jsonRequest);
});
}
async function getConversationState() {
const { data, error } = await supabase
.from('conversations')
.select('*')
.eq('conversation_id', 'test-direct-call')
.single();
if (error && error.code !== 'PGRST116') {
throw error;
}
return data;
}
async function runTests() {
console.log('๐งช Testing Direct Tool Calls with Cloud Persistence\n');
// Start the MCP server
console.log('Step 1: Starting MCP server...');
const server = spawn('node', ['dist/index.js'], {
cwd: '/Users/tarun/workspace/simple-minimal-system/mcp-tool-factory',
stdio: ['pipe', 'pipe', 'pipe']
});
// Wait for server to start
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('โ
Server started\n');
try {
// Initialize MCP connection
console.log('Step 2: Initializing MCP connection...');
const initResponse = await sendMCPRequest(server, {
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2025-06-18',
capabilities: {},
clientInfo: { name: 'test-client', version: '1.0.0' }
}
});
console.log('โ
MCP initialized:', initResponse.result.serverInfo.name, initResponse.result.serverInfo.version);
console.log('');
// Send initialized notification
server.stdin.write(JSON.stringify({
jsonrpc: '2.0',
method: 'notifications/initialized'
}) + '\n');
// Check initial state
console.log('Step 3: Checking initial database state...');
let state = await getConversationState();
const initialIntentCount = state ? state.intent_history.length : 0;
console.log(`โ
Initial intent count: ${initialIntentCount}\n`);
// Test 1: Call greet action
console.log('Step 4: Calling tool with action "greet"...');
const greetResponse = await sendMCPRequest(server, {
jsonrpc: '2.0',
id: 2,
method: 'tools/call',
params: {
name: 'example-tool',
arguments: {
action: 'greet',
conversationId: 'test-direct-call'
}
}
});
console.log('โ
Tool response:', greetResponse.result.content[0].text.substring(0, 100) + '...');
// Wait for persistence
await new Promise(resolve => setTimeout(resolve, 500));
state = await getConversationState();
console.log(`โ
Database updated - Intent count: ${state.intent_history.length}`);
console.log(` Latest intent: ${state.intent_history[state.intent_history.length - 1].action}\n`);
// Test 2: Call echo action
console.log('Step 5: Calling tool with action "echo"...');
const echoResponse = await sendMCPRequest(server, {
jsonrpc: '2.0',
id: 3,
method: 'tools/call',
params: {
name: 'example-tool',
arguments: {
action: 'echo',
conversationId: 'test-direct-call'
}
}
});
console.log('โ
Tool response:', echoResponse.result.content[0].text.substring(0, 100) + '...');
await new Promise(resolve => setTimeout(resolve, 500));
state = await getConversationState();
console.log(`โ
Database updated - Intent count: ${state.intent_history.length}`);
console.log(` Latest intent: ${state.intent_history[state.intent_history.length - 1].action}\n`);
// Test 3: Call what-if action
console.log('Step 6: Calling tool with action "what-if"...');
const whatIfResponse = await sendMCPRequest(server, {
jsonrpc: '2.0',
id: 4,
method: 'tools/call',
params: {
name: 'example-tool',
arguments: {
action: 'what-if',
conversationId: 'test-direct-call'
}
}
});
console.log('โ
Tool response:', whatIfResponse.result.content[0].text.substring(0, 100) + '...');
await new Promise(resolve => setTimeout(resolve, 500));
state = await getConversationState();
console.log(`โ
Database updated - Intent count: ${state.intent_history.length}`);
console.log(` Latest intent: ${state.intent_history[state.intent_history.length - 1].action}\n`);
// Final verification
console.log('Step 7: Final database state verification...');
state = await getConversationState();
console.log('๐ Final Conversation State:');
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
console.log(` Conversation ID: ${state.conversation_id}`);
console.log(` Tool: ${state.identity.toolName} v${state.identity.version}`);
console.log(` Total Intents: ${state.intent_history.length}`);
console.log('');
console.log(' Intent History:');
state.intent_history.forEach((intent, i) => {
const time = new Date(intent.timestamp).toLocaleTimeString();
console.log(` ${i + 1}. [${time}] ${intent.action} - ${intent.alignment}`);
});
console.log('');
console.log(` Updated: ${new Date(state.updated_at).toLocaleString()}`);
console.log('');
// Cleanup
console.log('Step 8: Cleaning up test data...');
await supabase
.from('conversations')
.delete()
.eq('conversation_id', 'test-direct-call');
console.log('โ
Test data cleaned up\n');
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
console.log('โจ All direct tool call tests PASSED!');
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n');
} catch (error) {
console.error('\n๐ฅ Test failed:', error.message);
} finally {
server.kill();
}
}
runTests().catch(console.error);