ccjk 2.4.4 → 2.6.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.
Files changed (55) hide show
  1. package/dist/chunks/api-providers.mjs +73 -1
  2. package/dist/chunks/ccjk-config.mjs +13 -77
  3. package/dist/chunks/ccr.mjs +9 -4
  4. package/dist/chunks/check-updates.mjs +4 -2
  5. package/dist/chunks/claude-code-config-manager.mjs +9 -15
  6. package/dist/chunks/claude-code-incremental-manager.mjs +5 -8
  7. package/dist/chunks/codex.mjs +10 -569
  8. package/dist/chunks/config-switch.mjs +7 -5
  9. package/dist/chunks/config.mjs +573 -0
  10. package/dist/chunks/config2.mjs +454 -0
  11. package/dist/chunks/doctor.mjs +89 -1
  12. package/dist/chunks/features.mjs +13 -10
  13. package/dist/chunks/index.mjs +10 -1164
  14. package/dist/chunks/index2.mjs +10 -2
  15. package/dist/chunks/init.mjs +14 -11
  16. package/dist/chunks/json-config.mjs +59 -0
  17. package/dist/chunks/mcp-server.mjs +776 -0
  18. package/dist/chunks/mcp.mjs +10 -8
  19. package/dist/chunks/menu.mjs +5 -5
  20. package/dist/chunks/package.mjs +1 -1
  21. package/dist/chunks/permissions.mjs +428 -0
  22. package/dist/chunks/prompts.mjs +2 -1
  23. package/dist/chunks/providers.mjs +261 -0
  24. package/dist/chunks/session.mjs +484 -41
  25. package/dist/chunks/skills.mjs +553 -0
  26. package/dist/chunks/stats.mjs +411 -0
  27. package/dist/chunks/uninstall.mjs +4 -3
  28. package/dist/chunks/update.mjs +6 -3
  29. package/dist/chunks/workflows2.mjs +140 -0
  30. package/dist/cli.mjs +290 -10
  31. package/dist/i18n/locales/en/hooks.json +47 -0
  32. package/dist/i18n/locales/en/mcp.json +55 -0
  33. package/dist/i18n/locales/en/permissions.json +43 -0
  34. package/dist/i18n/locales/en/registry.json +54 -0
  35. package/dist/i18n/locales/en/sandbox.json +44 -0
  36. package/dist/i18n/locales/en/skills.json +89 -129
  37. package/dist/i18n/locales/en/stats.json +20 -0
  38. package/dist/i18n/locales/zh-CN/hooks.json +47 -0
  39. package/dist/i18n/locales/zh-CN/mcp.json +55 -0
  40. package/dist/i18n/locales/zh-CN/permissions.json +43 -0
  41. package/dist/i18n/locales/zh-CN/registry.json +54 -0
  42. package/dist/i18n/locales/zh-CN/sandbox.json +44 -0
  43. package/dist/i18n/locales/zh-CN/skills.json +88 -128
  44. package/dist/i18n/locales/zh-CN/stats.json +20 -0
  45. package/dist/index.mjs +12 -8
  46. package/dist/shared/ccjk.B-lZxV2u.mjs +1162 -0
  47. package/dist/shared/{ccjk.CURU8gbR.mjs → ccjk.CUdzQluX.mjs} +1 -1
  48. package/dist/shared/{ccjk.ByTIGCUC.mjs → ccjk.Dut3wyoP.mjs} +1 -1
  49. package/dist/shared/ccjk.J8YiPsOw.mjs +259 -0
  50. package/dist/shared/{ccjk.CGTmRqsu.mjs → ccjk.rLRHmcqD.mjs} +5 -134
  51. package/dist/shared/{ccjk.QbS8EAOd.mjs → ccjk.uVUeWAt8.mjs} +2 -1
  52. package/package.json +1 -1
  53. package/templates/common/skills/code-review.md +343 -0
  54. package/templates/common/skills/summarize.md +312 -0
  55. package/templates/common/skills/translate.md +202 -0
@@ -0,0 +1,776 @@
1
+ import { createServer } from 'node:http';
2
+ import process__default from 'node:process';
3
+
4
+ const MCP_TOOLS = [
5
+ {
6
+ name: "ccjk_chat",
7
+ description: "Send a message to Claude via CCJK and get a response. Supports custom provider and model selection.",
8
+ inputSchema: {
9
+ type: "object",
10
+ properties: {
11
+ message: {
12
+ type: "string",
13
+ description: "The message to send to Claude"
14
+ },
15
+ provider: {
16
+ type: "string",
17
+ description: 'Optional API provider name (e.g., "302ai", "openai", "anthropic")'
18
+ },
19
+ model: {
20
+ type: "string",
21
+ description: 'Optional model name (e.g., "claude-3-5-sonnet-20241022", "gpt-4")'
22
+ },
23
+ systemPrompt: {
24
+ type: "string",
25
+ description: "Optional system prompt to guide the AI response"
26
+ }
27
+ },
28
+ required: ["message"]
29
+ }
30
+ },
31
+ {
32
+ name: "ccjk_providers",
33
+ description: "List all available API providers configured in CCJK",
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: {}
37
+ }
38
+ },
39
+ {
40
+ name: "ccjk_stats",
41
+ description: "Get usage statistics from CCJK (requires CCusage tool)",
42
+ inputSchema: {
43
+ type: "object",
44
+ properties: {
45
+ period: {
46
+ type: "string",
47
+ description: "Time period for statistics (7d, 30d, all)",
48
+ enum: ["7d", "30d", "all"]
49
+ }
50
+ }
51
+ }
52
+ },
53
+ {
54
+ name: "ccjk_workflows",
55
+ description: "List available workflows in CCJK",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ category: {
60
+ type: "string",
61
+ description: "Filter by workflow category (git, sixStep, common-tools, etc.)"
62
+ }
63
+ }
64
+ }
65
+ },
66
+ {
67
+ name: "ccjk_mcp_services",
68
+ description: "List configured MCP services in Claude Code",
69
+ inputSchema: {
70
+ type: "object",
71
+ properties: {
72
+ detailed: {
73
+ type: "boolean",
74
+ description: "Include detailed configuration information"
75
+ }
76
+ }
77
+ }
78
+ },
79
+ {
80
+ name: "ccjk_config",
81
+ description: "Get or set CCJK configuration values",
82
+ inputSchema: {
83
+ type: "object",
84
+ properties: {
85
+ action: {
86
+ type: "string",
87
+ description: "Action to perform (get, set, list)",
88
+ enum: ["get", "set", "list"]
89
+ },
90
+ key: {
91
+ type: "string",
92
+ description: "Configuration key (for get/set actions)"
93
+ },
94
+ value: {
95
+ type: "string",
96
+ description: "Configuration value (for set action)"
97
+ }
98
+ },
99
+ required: ["action"]
100
+ }
101
+ },
102
+ {
103
+ name: "ccjk_init",
104
+ description: "Initialize or update Claude Code configuration via CCJK",
105
+ inputSchema: {
106
+ type: "object",
107
+ properties: {
108
+ mode: {
109
+ type: "string",
110
+ description: "Initialization mode (full, workflows-only, api-only)",
111
+ enum: ["full", "workflows-only", "api-only"]
112
+ },
113
+ force: {
114
+ type: "boolean",
115
+ description: "Force overwrite existing configuration"
116
+ }
117
+ }
118
+ }
119
+ },
120
+ {
121
+ name: "ccjk_doctor",
122
+ description: "Run CCJK health check and diagnostics",
123
+ inputSchema: {
124
+ type: "object",
125
+ properties: {
126
+ verbose: {
127
+ type: "boolean",
128
+ description: "Show detailed diagnostic information"
129
+ }
130
+ }
131
+ }
132
+ }
133
+ ];
134
+ function getToolByName(name) {
135
+ return MCP_TOOLS.find((tool) => tool.name === name);
136
+ }
137
+ function validateToolInput(tool, input) {
138
+ const errors = [];
139
+ if (tool.inputSchema.required) {
140
+ for (const field of tool.inputSchema.required) {
141
+ if (!(field in input)) {
142
+ errors.push(`Missing required field: ${field}`);
143
+ }
144
+ }
145
+ }
146
+ for (const [key, value] of Object.entries(input)) {
147
+ const schema = tool.inputSchema.properties[key];
148
+ if (!schema) {
149
+ errors.push(`Unknown field: ${key}`);
150
+ continue;
151
+ }
152
+ if (schema.type === "string" && typeof value !== "string") {
153
+ errors.push(`Field ${key} must be a string`);
154
+ } else if (schema.type === "boolean" && typeof value !== "boolean") {
155
+ errors.push(`Field ${key} must be a boolean`);
156
+ } else if (schema.type === "number" && typeof value !== "number") {
157
+ errors.push(`Field ${key} must be a number`);
158
+ }
159
+ if (schema.enum && !schema.enum.includes(value)) {
160
+ errors.push(`Field ${key} must be one of: ${schema.enum.join(", ")}`);
161
+ }
162
+ }
163
+ return {
164
+ valid: errors.length === 0,
165
+ errors: errors.length > 0 ? errors : void 0
166
+ };
167
+ }
168
+
169
+ class MCPHandler {
170
+ /**
171
+ * Handle a tool call from MCP client
172
+ */
173
+ async handleToolCall(toolName, args) {
174
+ const tool = getToolByName(toolName);
175
+ if (!tool) {
176
+ return {
177
+ success: false,
178
+ error: `Unknown tool: ${toolName}`
179
+ };
180
+ }
181
+ const validation = validateToolInput(tool, args);
182
+ if (!validation.valid) {
183
+ return {
184
+ success: false,
185
+ error: `Invalid input: ${validation.errors?.join(", ")}`
186
+ };
187
+ }
188
+ try {
189
+ switch (toolName) {
190
+ case "ccjk_chat":
191
+ return await this.handleChat(args);
192
+ case "ccjk_providers":
193
+ return await this.handleProviders(args);
194
+ case "ccjk_stats":
195
+ return await this.handleStats(args);
196
+ case "ccjk_workflows":
197
+ return await this.handleWorkflows(args);
198
+ case "ccjk_mcp_services":
199
+ return await this.handleMcpServices(args);
200
+ case "ccjk_config":
201
+ return await this.handleConfig(args);
202
+ case "ccjk_init":
203
+ return await this.handleInit(args);
204
+ case "ccjk_doctor":
205
+ return await this.handleDoctor(args);
206
+ default:
207
+ return {
208
+ success: false,
209
+ error: `Tool not implemented: ${toolName}`
210
+ };
211
+ }
212
+ } catch (error) {
213
+ return {
214
+ success: false,
215
+ error: error instanceof Error ? error.message : String(error)
216
+ };
217
+ }
218
+ }
219
+ /**
220
+ * Handle ccjk_chat tool
221
+ */
222
+ async handleChat(args) {
223
+ const { message, provider, model } = args;
224
+ return {
225
+ success: true,
226
+ data: {
227
+ response: `[CCJK MCP] Received message: "${message}"`,
228
+ provider: provider || "default",
229
+ model: model || "default",
230
+ note: "This is a placeholder. Actual Claude API integration pending."
231
+ }
232
+ };
233
+ }
234
+ /**
235
+ * Handle ccjk_providers tool
236
+ */
237
+ async handleProviders(_args) {
238
+ try {
239
+ const { readMcpConfig } = await import('./config.mjs').then(function (n) { return n.C; });
240
+ const config = readMcpConfig();
241
+ const providers = [];
242
+ if (config?.mcpServers) {
243
+ for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
244
+ providers.push({
245
+ name,
246
+ command: serverConfig.command,
247
+ args: serverConfig.args,
248
+ env: serverConfig.env
249
+ });
250
+ }
251
+ }
252
+ return {
253
+ success: true,
254
+ data: {
255
+ providers,
256
+ count: providers.length
257
+ }
258
+ };
259
+ } catch (error) {
260
+ return {
261
+ success: false,
262
+ error: `Failed to read providers: ${error instanceof Error ? error.message : String(error)}`
263
+ };
264
+ }
265
+ }
266
+ /**
267
+ * Handle ccjk_stats tool
268
+ */
269
+ async handleStats(args) {
270
+ const { period = "all" } = args;
271
+ try {
272
+ const { x } = await import('tinyexec');
273
+ const result = await x("ccusage", ["--json", "--period", period]);
274
+ if (result.exitCode !== 0) {
275
+ return {
276
+ success: false,
277
+ error: "CCusage tool not available or failed"
278
+ };
279
+ }
280
+ const stats = JSON.parse(result.stdout);
281
+ return {
282
+ success: true,
283
+ data: stats
284
+ };
285
+ } catch (error) {
286
+ return {
287
+ success: false,
288
+ error: `Failed to get stats: ${error instanceof Error ? error.message : String(error)}`
289
+ };
290
+ }
291
+ }
292
+ /**
293
+ * Handle ccjk_workflows tool
294
+ */
295
+ async handleWorkflows(args) {
296
+ const { category } = args;
297
+ try {
298
+ const { getWorkflowConfigs } = await import('./workflows2.mjs');
299
+ let workflows = getWorkflowConfigs();
300
+ if (category) {
301
+ workflows = workflows.filter((w) => w.category === category);
302
+ }
303
+ return {
304
+ success: true,
305
+ data: {
306
+ workflows: workflows.map((w) => ({
307
+ id: w.id,
308
+ name: w.name,
309
+ category: w.category,
310
+ description: w.description
311
+ })),
312
+ count: workflows.length
313
+ }
314
+ };
315
+ } catch (error) {
316
+ return {
317
+ success: false,
318
+ error: `Failed to list workflows: ${error instanceof Error ? error.message : String(error)}`
319
+ };
320
+ }
321
+ }
322
+ /**
323
+ * Handle ccjk_mcp_services tool
324
+ */
325
+ async handleMcpServices(args) {
326
+ const { detailed = false } = args;
327
+ try {
328
+ const { readMcpConfig } = await import('./config.mjs').then(function (n) { return n.C; });
329
+ const config = await readMcpConfig();
330
+ const services = config?.mcpServers || {};
331
+ const serviceList = Object.entries(services).map(([name, config2]) => {
332
+ if (detailed) {
333
+ return { name, config: config2 };
334
+ }
335
+ return { name };
336
+ });
337
+ return {
338
+ success: true,
339
+ data: {
340
+ services: serviceList,
341
+ count: serviceList.length
342
+ }
343
+ };
344
+ } catch (error) {
345
+ return {
346
+ success: false,
347
+ error: `Failed to list MCP services: ${error instanceof Error ? error.message : String(error)}`
348
+ };
349
+ }
350
+ }
351
+ /**
352
+ * Handle ccjk_config tool
353
+ */
354
+ async handleConfig(args) {
355
+ const { action, key, value } = args;
356
+ try {
357
+ const { readZcfConfig, updateZcfConfig } = await import('./ccjk-config.mjs');
358
+ if (action === "list") {
359
+ const config = await readZcfConfig();
360
+ return {
361
+ success: true,
362
+ data: config || {}
363
+ };
364
+ }
365
+ if (action === "get") {
366
+ if (!key) {
367
+ return {
368
+ success: false,
369
+ error: "Key is required for get action"
370
+ };
371
+ }
372
+ const config = await readZcfConfig();
373
+ return {
374
+ success: true,
375
+ data: {
376
+ key,
377
+ value: config?.[key]
378
+ }
379
+ };
380
+ }
381
+ if (action === "set") {
382
+ if (!key || value === void 0) {
383
+ return {
384
+ success: false,
385
+ error: "Key and value are required for set action"
386
+ };
387
+ }
388
+ await updateZcfConfig({ [key]: value });
389
+ return {
390
+ success: true,
391
+ data: {
392
+ key,
393
+ value,
394
+ message: "Configuration updated"
395
+ }
396
+ };
397
+ }
398
+ return {
399
+ success: false,
400
+ error: `Unknown action: ${action}`
401
+ };
402
+ } catch (error) {
403
+ return {
404
+ success: false,
405
+ error: `Failed to handle config: ${error instanceof Error ? error.message : String(error)}`
406
+ };
407
+ }
408
+ }
409
+ /**
410
+ * Handle ccjk_init tool
411
+ */
412
+ async handleInit(args) {
413
+ const { mode = "full", force = false } = args;
414
+ try {
415
+ const { init } = await import('./init.mjs').then(function (n) { return n.H; });
416
+ const options = {
417
+ force,
418
+ skipPrompt: true
419
+ };
420
+ if (mode === "workflows-only") {
421
+ options.configAction = "skip";
422
+ options.apiType = "skip";
423
+ } else if (mode === "api-only") {
424
+ options.workflows = false;
425
+ }
426
+ await init(options);
427
+ return {
428
+ success: true,
429
+ data: {
430
+ message: `Initialization completed in ${mode} mode`
431
+ }
432
+ };
433
+ } catch (error) {
434
+ return {
435
+ success: false,
436
+ error: `Initialization failed: ${error instanceof Error ? error.message : String(error)}`
437
+ };
438
+ }
439
+ }
440
+ /**
441
+ * Handle ccjk_doctor tool
442
+ */
443
+ async handleDoctor(args) {
444
+ const { verbose = false } = args;
445
+ try {
446
+ const { doctor } = await import('./doctor.mjs');
447
+ const originalLog = console.log;
448
+ const output = [];
449
+ console.log = (...args2) => {
450
+ output.push(args2.join(" "));
451
+ };
452
+ await doctor();
453
+ console.log = originalLog;
454
+ return {
455
+ success: true,
456
+ data: {
457
+ output: output.join("\n"),
458
+ verbose
459
+ }
460
+ };
461
+ } catch (error) {
462
+ return {
463
+ success: false,
464
+ error: `Doctor check failed: ${error instanceof Error ? error.message : String(error)}`
465
+ };
466
+ }
467
+ }
468
+ }
469
+
470
+ class MCPServer {
471
+ handler;
472
+ httpServer;
473
+ options;
474
+ serverInfo;
475
+ initialized = false;
476
+ constructor(options = {}) {
477
+ this.options = {
478
+ transport: options.transport || "stdio",
479
+ port: options.port || 3e3,
480
+ host: options.host || "localhost",
481
+ debug: options.debug || false
482
+ };
483
+ this.handler = new MCPHandler();
484
+ this.serverInfo = {
485
+ name: "ccjk-mcp-server",
486
+ version: "1.0.0",
487
+ protocolVersion: "2024-11-05",
488
+ capabilities: {
489
+ tools: true,
490
+ prompts: false,
491
+ resources: false
492
+ }
493
+ };
494
+ }
495
+ /**
496
+ * Start the MCP server
497
+ */
498
+ async start() {
499
+ if (this.options.transport === "stdio") {
500
+ await this.startStdio();
501
+ } else {
502
+ await this.startHttp();
503
+ }
504
+ }
505
+ /**
506
+ * Stop the MCP server
507
+ */
508
+ async stop() {
509
+ if (this.httpServer) {
510
+ return new Promise((resolve, reject) => {
511
+ this.httpServer.close((err) => {
512
+ if (err)
513
+ reject(err);
514
+ else resolve();
515
+ });
516
+ });
517
+ }
518
+ }
519
+ /**
520
+ * Start stdio transport mode
521
+ */
522
+ async startStdio() {
523
+ this.log("Starting MCP server in stdio mode...");
524
+ process__default.stdin.setEncoding("utf8");
525
+ let buffer = "";
526
+ process__default.stdin.on("data", (chunk) => {
527
+ buffer += chunk;
528
+ const lines = buffer.split("\n");
529
+ buffer = lines.pop() || "";
530
+ for (const line of lines) {
531
+ if (line.trim()) {
532
+ this.handleStdioMessage(line).catch((error) => {
533
+ this.logError("Error handling stdio message:", error);
534
+ });
535
+ }
536
+ }
537
+ });
538
+ process__default.stdin.on("end", () => {
539
+ this.log("Stdin closed, shutting down...");
540
+ process__default.exit(0);
541
+ });
542
+ this.log("MCP server ready (stdio mode)");
543
+ }
544
+ /**
545
+ * Start HTTP transport mode
546
+ */
547
+ async startHttp() {
548
+ this.log(`Starting MCP server in HTTP mode on ${this.options.host}:${this.options.port}...`);
549
+ this.httpServer = createServer(async (req, res) => {
550
+ res.setHeader("Access-Control-Allow-Origin", "*");
551
+ res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
552
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
553
+ if (req.method === "OPTIONS") {
554
+ res.writeHead(200);
555
+ res.end();
556
+ return;
557
+ }
558
+ if (req.method !== "POST") {
559
+ res.writeHead(405, { "Content-Type": "application/json" });
560
+ res.end(JSON.stringify({ error: "Method not allowed" }));
561
+ return;
562
+ }
563
+ let body = "";
564
+ req.on("data", (chunk) => body += chunk);
565
+ req.on("end", async () => {
566
+ try {
567
+ const request = JSON.parse(body);
568
+ const response = await this.handleRequest(request);
569
+ res.writeHead(200, { "Content-Type": "application/json" });
570
+ res.end(JSON.stringify(response));
571
+ } catch (error) {
572
+ res.writeHead(400, { "Content-Type": "application/json" });
573
+ res.end(JSON.stringify({
574
+ jsonrpc: "2.0",
575
+ error: {
576
+ code: -32700,
577
+ message: "Parse error",
578
+ data: error instanceof Error ? error.message : String(error)
579
+ }
580
+ }));
581
+ }
582
+ });
583
+ });
584
+ return new Promise((resolve, reject) => {
585
+ this.httpServer.listen(this.options.port, this.options.host, () => {
586
+ this.log(`MCP server listening on http://${this.options.host}:${this.options.port}`);
587
+ resolve();
588
+ });
589
+ this.httpServer.on("error", reject);
590
+ });
591
+ }
592
+ /**
593
+ * Handle stdio message
594
+ */
595
+ async handleStdioMessage(message) {
596
+ try {
597
+ const request = JSON.parse(message);
598
+ const response = await this.handleRequest(request);
599
+ process__default.stdout.write(`${JSON.stringify(response)}
600
+ `);
601
+ } catch (error) {
602
+ const errorResponse = {
603
+ jsonrpc: "2.0",
604
+ error: {
605
+ code: -32700,
606
+ message: "Parse error",
607
+ data: error instanceof Error ? error.message : String(error)
608
+ }
609
+ };
610
+ process__default.stdout.write(`${JSON.stringify(errorResponse)}
611
+ `);
612
+ }
613
+ }
614
+ /**
615
+ * Handle MCP request
616
+ */
617
+ async handleRequest(request) {
618
+ this.log(`Received request: ${request.method}`);
619
+ try {
620
+ switch (request.method) {
621
+ case "initialize":
622
+ return this.handleInitialize(request);
623
+ case "tools/list":
624
+ return this.handleToolsList(request);
625
+ case "tools/call":
626
+ return await this.handleToolsCall(request);
627
+ case "ping":
628
+ return this.handlePing(request);
629
+ default:
630
+ return {
631
+ jsonrpc: "2.0",
632
+ id: request.id,
633
+ error: {
634
+ code: -32601,
635
+ message: `Method not found: ${request.method}`
636
+ }
637
+ };
638
+ }
639
+ } catch (error) {
640
+ return {
641
+ jsonrpc: "2.0",
642
+ id: request.id,
643
+ error: {
644
+ code: -32603,
645
+ message: "Internal error",
646
+ data: error instanceof Error ? error.message : String(error)
647
+ }
648
+ };
649
+ }
650
+ }
651
+ /**
652
+ * Handle initialize request
653
+ */
654
+ handleInitialize(request) {
655
+ this.initialized = true;
656
+ this.log("Server initialized");
657
+ return {
658
+ jsonrpc: "2.0",
659
+ id: request.id,
660
+ result: {
661
+ protocolVersion: this.serverInfo.protocolVersion,
662
+ capabilities: this.serverInfo.capabilities,
663
+ serverInfo: {
664
+ name: this.serverInfo.name,
665
+ version: this.serverInfo.version
666
+ }
667
+ }
668
+ };
669
+ }
670
+ /**
671
+ * Handle tools/list request
672
+ */
673
+ handleToolsList(request) {
674
+ if (!this.initialized) {
675
+ return {
676
+ jsonrpc: "2.0",
677
+ id: request.id,
678
+ error: {
679
+ code: -32002,
680
+ message: "Server not initialized"
681
+ }
682
+ };
683
+ }
684
+ return {
685
+ jsonrpc: "2.0",
686
+ id: request.id,
687
+ result: {
688
+ tools: MCP_TOOLS
689
+ }
690
+ };
691
+ }
692
+ /**
693
+ * Handle tools/call request
694
+ */
695
+ async handleToolsCall(request) {
696
+ if (!this.initialized) {
697
+ return {
698
+ jsonrpc: "2.0",
699
+ id: request.id,
700
+ error: {
701
+ code: -32002,
702
+ message: "Server not initialized"
703
+ }
704
+ };
705
+ }
706
+ const { name, arguments: args } = request.params || {};
707
+ if (!name) {
708
+ return {
709
+ jsonrpc: "2.0",
710
+ id: request.id,
711
+ error: {
712
+ code: -32602,
713
+ message: "Invalid params: missing tool name"
714
+ }
715
+ };
716
+ }
717
+ this.log(`Calling tool: ${name}`);
718
+ const result = await this.handler.handleToolCall(name, args || {});
719
+ if (!result.success) {
720
+ return {
721
+ jsonrpc: "2.0",
722
+ id: request.id,
723
+ error: {
724
+ code: -32e3,
725
+ message: result.error || "Tool execution failed"
726
+ }
727
+ };
728
+ }
729
+ return {
730
+ jsonrpc: "2.0",
731
+ id: request.id,
732
+ result: {
733
+ content: [
734
+ {
735
+ type: "text",
736
+ text: JSON.stringify(result.data, null, 2)
737
+ }
738
+ ]
739
+ }
740
+ };
741
+ }
742
+ /**
743
+ * Handle ping request
744
+ */
745
+ handlePing(request) {
746
+ return {
747
+ jsonrpc: "2.0",
748
+ id: request.id,
749
+ result: {
750
+ status: "ok",
751
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
752
+ }
753
+ };
754
+ }
755
+ /**
756
+ * Log message (only in debug mode)
757
+ */
758
+ log(...args) {
759
+ if (this.options.debug) {
760
+ console.error("[MCP Server]", ...args);
761
+ }
762
+ }
763
+ /**
764
+ * Log error (always)
765
+ */
766
+ logError(...args) {
767
+ console.error("[MCP Server Error]", ...args);
768
+ }
769
+ }
770
+ async function startMCPServer(options = {}) {
771
+ const server = new MCPServer(options);
772
+ await server.start();
773
+ return server;
774
+ }
775
+
776
+ export { MCPServer, startMCPServer };