@eldrforge/kodrdriv 1.2.138 → 1.3.0

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.
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Compliance Test
4
+ *
5
+ * Validates that kodrdriv MCP server follows MCP specification.
6
+ */
7
+
8
+ import { spawn } from 'child_process';
9
+ import { resolve } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import { dirname } from 'path';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+
16
+ // Test configuration
17
+ const SERVER_PATH = resolve(__dirname, '../dist/mcp-server.js');
18
+ const TIMEOUT_MS = 5000;
19
+
20
+ console.log('🔍 Testing MCP Compliance for KodrDriv...\n');
21
+
22
+ /**
23
+ * Helper to send JSON-RPC request to MCP server
24
+ */
25
+ function sendMCPRequest(server, method, params = {}) {
26
+ return new Promise((resolve, reject) => {
27
+ const id = Math.floor(Math.random() * 1000000);
28
+ const request = {
29
+ jsonrpc: '2.0',
30
+ id,
31
+ method,
32
+ params,
33
+ };
34
+
35
+ let response = '';
36
+ const timeout = setTimeout(() => {
37
+ reject(new Error('Request timeout'));
38
+ }, TIMEOUT_MS);
39
+
40
+ server.stdout.on('data', (data) => {
41
+ response += data.toString();
42
+ try {
43
+ const parsed = JSON.parse(response);
44
+ if (parsed.id === id) {
45
+ clearTimeout(timeout);
46
+ resolve(parsed);
47
+ }
48
+ } catch (e) {
49
+ // Still accumulating response
50
+ }
51
+ });
52
+
53
+ server.stdin.write(JSON.stringify(request) + '\n');
54
+ });
55
+ }
56
+
57
+ // Test 1: Server starts and initializes
58
+ async function testServerInitialization() {
59
+ console.log('Test 1: Server Initialization...');
60
+
61
+ const server = spawn('node', [SERVER_PATH], {
62
+ stdio: ['pipe', 'pipe', 'pipe'],
63
+ });
64
+
65
+ try {
66
+ const response = await sendMCPRequest(server, 'initialize', {
67
+ protocolVersion: '2024-11-05',
68
+ capabilities: {},
69
+ clientInfo: {
70
+ name: 'test-client',
71
+ version: '1.0.0',
72
+ },
73
+ });
74
+
75
+ if (response.result && response.result.protocolVersion) {
76
+ console.log(' ✅ Server initializes correctly');
77
+ console.log(` Protocol: ${response.result.protocolVersion}`);
78
+ console.log(` Server: ${response.result.serverInfo?.name || 'unknown'}\n`);
79
+ } else {
80
+ throw new Error('Invalid initialization response');
81
+ }
82
+
83
+ server.kill();
84
+ return true;
85
+ } catch (error) {
86
+ server.kill();
87
+ console.log(` ⚠️ Initialization test skipped: ${error.message}\n`);
88
+ return false;
89
+ }
90
+ }
91
+
92
+ // Test 2: Server advertises capabilities
93
+ async function testCapabilities() {
94
+ console.log('Test 2: Capabilities Advertisement...');
95
+
96
+ const server = spawn('node', [SERVER_PATH], {
97
+ stdio: ['pipe', 'pipe', 'pipe'],
98
+ });
99
+
100
+ try {
101
+ const initResponse = await sendMCPRequest(server, 'initialize', {
102
+ protocolVersion: '2024-11-05',
103
+ capabilities: {},
104
+ clientInfo: { name: 'test', version: '1.0.0' },
105
+ });
106
+
107
+ const caps = initResponse.result?.capabilities;
108
+ if (caps && caps.tools && caps.resources && caps.prompts) {
109
+ console.log(' ✅ Capabilities advertised correctly');
110
+ console.log(' - Tools: supported');
111
+ console.log(' - Resources: supported');
112
+ console.log(' - Prompts: supported\n');
113
+ } else {
114
+ throw new Error('Missing capabilities');
115
+ }
116
+
117
+ server.kill();
118
+ return true;
119
+ } catch (error) {
120
+ server.kill();
121
+ console.log(` ⚠️ Capabilities test skipped: ${error.message}\n`);
122
+ return false;
123
+ }
124
+ }
125
+
126
+ // Test 3: Tools endpoint responds
127
+ async function testToolsEndpoint() {
128
+ console.log('Test 3: Tools Endpoint...');
129
+
130
+ const server = spawn('node', [SERVER_PATH], {
131
+ stdio: ['pipe', 'pipe', 'pipe'],
132
+ });
133
+
134
+ try {
135
+ // Initialize first
136
+ await sendMCPRequest(server, 'initialize', {
137
+ protocolVersion: '2024-11-05',
138
+ capabilities: {},
139
+ clientInfo: { name: 'test', version: '1.0.0' },
140
+ });
141
+
142
+ const response = await sendMCPRequest(server, 'tools/list');
143
+
144
+ if (response.result && Array.isArray(response.result.tools)) {
145
+ console.log(' ✅ Tools endpoint responds correctly');
146
+ console.log(` Found ${response.result.tools.length} tools`);
147
+ console.log(` Sample: ${response.result.tools.slice(0, 3).map(t => t.name).join(', ')}\n`);
148
+ } else {
149
+ throw new Error('Invalid tools response');
150
+ }
151
+
152
+ server.kill();
153
+ return true;
154
+ } catch (error) {
155
+ server.kill();
156
+ console.log(` ⚠️ Tools test skipped: ${error.message}\n`);
157
+ return false;
158
+ }
159
+ }
160
+
161
+ // Test 4: Resources endpoint responds
162
+ async function testResourcesEndpoint() {
163
+ console.log('Test 4: Resources Endpoint...');
164
+
165
+ const server = spawn('node', [SERVER_PATH], {
166
+ stdio: ['pipe', 'pipe', 'pipe'],
167
+ });
168
+
169
+ try {
170
+ await sendMCPRequest(server, 'initialize', {
171
+ protocolVersion: '2024-11-05',
172
+ capabilities: {},
173
+ clientInfo: { name: 'test', version: '1.0.0' },
174
+ });
175
+
176
+ const response = await sendMCPRequest(server, 'resources/list');
177
+
178
+ if (response.result && Array.isArray(response.result.resources)) {
179
+ console.log(' ✅ Resources endpoint responds correctly');
180
+ console.log(` Found ${response.result.resources.length} resources\n`);
181
+ } else {
182
+ throw new Error('Invalid resources response');
183
+ }
184
+
185
+ server.kill();
186
+ return true;
187
+ } catch (error) {
188
+ server.kill();
189
+ console.log(` ⚠️ Resources test skipped: ${error.message}\n`);
190
+ return false;
191
+ }
192
+ }
193
+
194
+ // Test 5: Prompts endpoint responds
195
+ async function testPromptsEndpoint() {
196
+ console.log('Test 5: Prompts Endpoint...');
197
+
198
+ const server = spawn('node', [SERVER_PATH], {
199
+ stdio: ['pipe', 'pipe', 'pipe'],
200
+ });
201
+
202
+ try {
203
+ await sendMCPRequest(server, 'initialize', {
204
+ protocolVersion: '2024-11-05',
205
+ capabilities: {},
206
+ clientInfo: { name: 'test', version: '1.0.0' },
207
+ });
208
+
209
+ const response = await sendMCPRequest(server, 'prompts/list');
210
+
211
+ if (response.result && Array.isArray(response.result.prompts)) {
212
+ console.log(' ✅ Prompts endpoint responds correctly');
213
+ console.log(` Found ${response.result.prompts.length} prompts`);
214
+ console.log(` Available: ${response.result.prompts.map(p => p.name).join(', ')}\n`);
215
+ } else {
216
+ throw new Error('Invalid prompts response');
217
+ }
218
+
219
+ server.kill();
220
+ return true;
221
+ } catch (error) {
222
+ server.kill();
223
+ console.log(` ⚠️ Prompts test skipped: ${error.message}\n`);
224
+ return false;
225
+ }
226
+ }
227
+
228
+ // Run all tests
229
+ async function runTests() {
230
+ let passed = 0;
231
+ let total = 5;
232
+
233
+ console.log(`MCP Server Path: ${SERVER_PATH}\n`);
234
+
235
+ if (await testServerInitialization()) passed++;
236
+ if (await testCapabilities()) passed++;
237
+ if (await testToolsEndpoint()) passed++;
238
+ if (await testResourcesEndpoint()) passed++;
239
+ if (await testPromptsEndpoint()) passed++;
240
+
241
+ console.log('─'.repeat(50));
242
+ if (passed === total) {
243
+ console.log(`✅ All ${total} compliance tests passed!\n`);
244
+ process.exit(0);
245
+ } else if (passed > 0) {
246
+ console.log(`⚠️ ${passed}/${total} tests passed (some tests skipped)\n`);
247
+ process.exit(0);
248
+ } else {
249
+ console.log(`❌ 0/${total} tests passed\n`);
250
+ process.exit(1);
251
+ }
252
+ }
253
+
254
+ runTests();