import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function runTests() {
console.log('Starting MCP-Mac Tool Verification...');
// Path to the compiled server
const serverPath = path.resolve(__dirname, '../dist/index.js');
console.log(`Connecting to server at: ${serverPath}`);
const transport = new StdioClientTransport({
command: 'node',
args: [serverPath],
});
const client = new Client(
{
name: 'mcp-mac-tester',
version: '0.0.1',
},
{
capabilities: {},
}
);
await client.connect(transport);
console.log('Connected to MCP Server.\n');
// Helper to call a tool
async function testTool(name: string, args: any = {}) {
console.log(`>>> Testing tool: ${name}`);
console.log(` Args: ${JSON.stringify(args)}`);
try {
const result = await client.callTool({
name,
arguments: args,
});
// The SDK might return the result directly or wrapped.
// Based on types, result is CallToolResult.
console.log(' Result:');
if (result.content && Array.isArray(result.content)) {
result.content.forEach((item: any) => {
if (item.type === 'text') {
console.log(item.text.split('\n').map((line: string) => ` ${line}`).join('\n'));
} else {
console.log(` [${item.type}] data...`);
}
});
} else {
console.log(' (Empty or unexpected format)');
}
console.log(' [SUCCESS]\n');
} catch (error: any) {
console.error(` [ERROR]: ${error.message}\n`);
}
}
// --- FINDER ---
await testTool('finder_get_current_folder');
// finder_get_selection requires manual selection, skipping or expecting empty
await testTool('finder_get_selection');
// --- MAIL ---
await testTool('mail_get_accounts');
await testTool('mail_get_inbox_count');
await testTool('mail_get_total_inbox_count');
// Create a safe draft
await testTool('mail_create_message', {
to: 'test@example.com',
subject: 'MCP Test Draft',
body: 'This is a test draft created by MCP-Mac.'
});
// --- CONTACTS ---
// Search for a common name
await testTool('contacts_search_people', { search_term: 'Apple' });
// Try to get info for "Apple" (likely to fail or find Apple Computer)
await testTool('contacts_get_person_info', { person_name: 'Apple' });
// --- REMINDERS ---
await testTool('reminders_get_lists');
await testTool('reminders_create_reminder', {
title: 'MCP Test Reminder',
notes: 'Created by automated test script'
});
await testTool('reminders_get_incomplete_reminders', { limit: 5 });
// --- NOTES ---
await testTool('notes_get_folders');
await testTool('notes_create_note', {
title: 'MCP Test Note',
content: 'This is a test note created by MCP-Mac.'
});
await testTool('notes_get_recent_notes', { limit: 3 });
// --- TEXTEDIT ---
await testTool('textedit_create_document', {
content: 'Hello from MCP-Mac Test Script!'
});
await testTool('textedit_get_documents');
// --- CALENDAR ---
await testTool('calendar_get_calendars');
const today = new Date().toISOString().split('T')[0];
await testTool('calendar_create_event', {
title: 'MCP Test Event',
start_datetime: `${today} 12:00`,
end_datetime: `${today} 13:00`,
notes: 'Automated test event'
});
await testTool('calendar_get_today_events');
// --- WORKFLOW ---
// This depends on a contact existing. We'll try "Apple" again.
await testTool('workflow_contact_to_textedit', {
name: 'Apple',
title: 'Apple Contact Info'
});
// --- DISCOVERY ---
// Basic discovery of Calculator app (safe, simple)
await testTool('discover_apps', {
app_name: 'Calculator',
method: 'basic',
destination: path.resolve(__dirname, '../docs/discovery.test')
});
console.log('Test sequence complete. Closing connection...');
await client.close();
}
runTests().catch(console.error);