@ace-sdk/mcp 1.0.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.
package/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # @ace-sdk/mcp
2
+
3
+ MCP Server for ACE pattern learning - works with any MCP-compatible client.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@ace-sdk/mcp.svg)](https://www.npmjs.com/package/@ace-sdk/mcp)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @ace-sdk/mcp
12
+ ```
13
+
14
+ ## Features
15
+
16
+ - **15 MCP Tools**: Full ACE functionality as MCP tools
17
+ - **Client Agnostic**: Works with Claude Code, Cursor, Cline, VSCode Copilot, or any MCP client
18
+ - **Auto Learning**: Automatic pattern capture from coding sessions
19
+ - **Semantic Search**: Find relevant patterns while coding
20
+
21
+ ## MCP Client Setup
22
+
23
+ Add to your MCP configuration (e.g., `.mcp.json`):
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "ace-pattern-learning": {
29
+ "command": "npx",
30
+ "args": ["@ace-sdk/mcp"],
31
+ "env": {
32
+ "ACE_SERVER_URL": "https://ace-api.code-engine.app",
33
+ "ACE_API_TOKEN": "your-token",
34
+ "ACE_ORG_ID": "your-org",
35
+ "ACE_PROJECT_ID": "your-project"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Available Tools
43
+
44
+ | Tool | Description |
45
+ |------|-------------|
46
+ | `ace_get_playbook` | Fetch learned patterns |
47
+ | `ace_search` | Semantic search for patterns |
48
+ | `ace_learn` | Submit learning from execution |
49
+ | `ace_bootstrap` | Initialize playbook from codebase |
50
+ | `ace_status` | Get playbook statistics |
51
+ | `ace_delta` | Manual pattern management |
52
+ | `ace_cache_clear` | Clear local caches |
53
+
54
+ ## Documentation
55
+
56
+ Full documentation: [packages/mcp/docs](./docs)
57
+
58
+ ## License
59
+
60
+ MIT Š [CE.NET Team](mailto:ace@code-engine.net)
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ACE MCP Server v1.0.0
4
+ *
5
+ * Model Context Protocol server for ACE (Agentic Context Engineering) pattern learning.
6
+ * Uses @ace-sdk/core for HTTP client, caching, and configuration.
7
+ *
8
+ * Server-side intelligence: Reflector + Curator run on ACE server
9
+ * Client responsibility: Send traces, retrieve playbooks
10
+ *
11
+ * Compatible with: Claude Code, Cursor, Cline, any MCP client
12
+ *
13
+ * @package @ace-sdk/mcp
14
+ */
15
+ export declare const VERSION = "1.0.0";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAwBH,eAAO,MAAM,OAAO,UAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,590 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ACE MCP Server v1.0.0
4
+ *
5
+ * Model Context Protocol server for ACE (Agentic Context Engineering) pattern learning.
6
+ * Uses @ace-sdk/core for HTTP client, caching, and configuration.
7
+ *
8
+ * Server-side intelligence: Reflector + Curator run on ACE server
9
+ * Client responsibility: Send traces, retrieve playbooks
10
+ *
11
+ * Compatible with: Claude Code, Cursor, Cline, any MCP client
12
+ *
13
+ * @package @ace-sdk/mcp
14
+ */
15
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
16
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
18
+ import { AceClient, loadConfig, THOROUGHNESS_PRESETS } from '@ace-sdk/core';
19
+ import { tools } from './tools/definitions.js';
20
+ import { InitializationService } from './services/initialization.js';
21
+ import { checkVersionCompatibility, MCP_VERSION } from './utils/version-checker.js';
22
+ // Re-export version
23
+ export const VERSION = MCP_VERSION;
24
+ // Initialize configuration
25
+ const config = loadConfig();
26
+ if (!config.serverUrl || !config.apiToken || !config.projectId) {
27
+ console.error('❌ Failed to load configuration: missing required fields');
28
+ console.error(' Required: serverUrl, apiToken, projectId');
29
+ console.error(' Run "ace-mcp" with ACE_SERVER_URL, ACE_API_TOKEN, ACE_PROJECT_ID environment variables');
30
+ console.error(' Or configure ~/.ace/config.json');
31
+ process.exit(1);
32
+ }
33
+ // Create AceClient from @ace-sdk/core
34
+ const aceClient = new AceClient(config);
35
+ // Create initialization service for bootstrap
36
+ const initializationService = new InitializationService();
37
+ // Check version compatibility (async, non-blocking)
38
+ let versionStatus = null;
39
+ checkVersionCompatibility().then(status => {
40
+ versionStatus = status;
41
+ }).catch(error => {
42
+ console.error('âš ī¸ Version check failed (non-critical):', error.message);
43
+ });
44
+ // Create MCP server (NO SAMPLING - works with all MCP clients!)
45
+ const server = new Server({
46
+ name: 'ace-pattern-learning',
47
+ version: VERSION
48
+ }, {
49
+ capabilities: {
50
+ tools: {} // Just tools, no sampling required
51
+ }
52
+ });
53
+ // Register handlers
54
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
55
+ return { tools };
56
+ });
57
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
58
+ const { name, arguments: args } = request.params;
59
+ try {
60
+ switch (name) {
61
+ // ========================================================================
62
+ // Configuration Tools
63
+ // ========================================================================
64
+ case 'ace_save_config': {
65
+ const { serverUrl, apiToken, projectId } = args;
66
+ console.error('💾 Saving configuration...');
67
+ // Save config to disk
68
+ const fs = await import('fs/promises');
69
+ const os = await import('os');
70
+ const path = await import('path');
71
+ const configDir = path.join(os.homedir(), '.ace');
72
+ const configPath = path.join(configDir, 'config.json');
73
+ await fs.mkdir(configDir, { recursive: true });
74
+ // Read existing config to preserve orgs section
75
+ let existingConfig = {};
76
+ try {
77
+ const existingContent = await fs.readFile(configPath, 'utf8');
78
+ existingConfig = JSON.parse(existingContent);
79
+ }
80
+ catch {
81
+ // File doesn't exist, start fresh
82
+ }
83
+ const newConfig = {
84
+ ...existingConfig,
85
+ serverUrl,
86
+ apiToken,
87
+ projectId
88
+ };
89
+ await fs.writeFile(configPath, JSON.stringify(newConfig, null, 2), 'utf8');
90
+ return {
91
+ content: [{
92
+ type: 'text',
93
+ text: JSON.stringify({
94
+ success: true,
95
+ message: 'Configuration saved to ~/.ace/config.json',
96
+ config: { serverUrl, projectId }
97
+ }, null, 2)
98
+ }]
99
+ };
100
+ }
101
+ case 'ace_get_config': {
102
+ console.error('🔍 Fetching server configuration...');
103
+ const serverConfig = await aceClient.getConfig();
104
+ return {
105
+ content: [{
106
+ type: 'text',
107
+ text: JSON.stringify(serverConfig, null, 2)
108
+ }]
109
+ };
110
+ }
111
+ case 'ace_set_config': {
112
+ const { scope, ...updates } = args;
113
+ if (!scope) {
114
+ return {
115
+ content: [{
116
+ type: 'text',
117
+ text: JSON.stringify({
118
+ error: 'Missing required parameter',
119
+ message: 'The "scope" parameter is required',
120
+ hint: 'Use scope="project" for Claude Code CLI'
121
+ }, null, 2)
122
+ }],
123
+ isError: true
124
+ };
125
+ }
126
+ if (scope !== 'project') {
127
+ return {
128
+ content: [{
129
+ type: 'text',
130
+ text: JSON.stringify({
131
+ error: 'Invalid scope',
132
+ message: 'Claude Code CLI only supports scope="project"',
133
+ hint: 'Org-level config must be set via website dashboard'
134
+ }, null, 2)
135
+ }],
136
+ isError: true
137
+ };
138
+ }
139
+ console.error('âš™ī¸ Updating server configuration...');
140
+ const result = await aceClient.updateConfig(updates, scope);
141
+ return {
142
+ content: [{
143
+ type: 'text',
144
+ text: `Configuration updated successfully:\n${JSON.stringify(result, null, 2)}`
145
+ }]
146
+ };
147
+ }
148
+ case 'ace_reset_config': {
149
+ const { scope } = args;
150
+ if (!scope) {
151
+ return {
152
+ content: [{
153
+ type: 'text',
154
+ text: JSON.stringify({
155
+ error: 'Missing required parameter',
156
+ message: 'The "scope" parameter is required',
157
+ hint: 'Use scope="project" for Claude Code CLI'
158
+ }, null, 2)
159
+ }],
160
+ isError: true
161
+ };
162
+ }
163
+ if (scope !== 'project') {
164
+ return {
165
+ content: [{
166
+ type: 'text',
167
+ text: JSON.stringify({
168
+ error: 'Invalid scope',
169
+ message: 'Claude Code CLI only supports scope="project"',
170
+ hint: 'Org-level config must be set via website dashboard'
171
+ }, null, 2)
172
+ }],
173
+ isError: true
174
+ };
175
+ }
176
+ console.error('🔄 Resetting project configuration to defaults...');
177
+ const result = await aceClient.resetConfig(scope);
178
+ return {
179
+ content: [{
180
+ type: 'text',
181
+ text: `Configuration reset successfully:\n${JSON.stringify(result, null, 2)}`
182
+ }]
183
+ };
184
+ }
185
+ // ========================================================================
186
+ // Playbook Operations
187
+ // ========================================================================
188
+ case 'ace_get_playbook': {
189
+ const { section, min_helpful, include_metadata } = args;
190
+ console.error('📖 Fetching playbook from server...');
191
+ const response = await aceClient.getPlaybook({ include_metadata });
192
+ let playbook = response.playbook;
193
+ // Client-side filtering if requested
194
+ if (section) {
195
+ playbook = {
196
+ strategies_and_hard_rules: section === 'strategies_and_hard_rules' ? playbook.strategies_and_hard_rules : [],
197
+ useful_code_snippets: section === 'useful_code_snippets' ? playbook.useful_code_snippets : [],
198
+ troubleshooting_and_pitfalls: section === 'troubleshooting_and_pitfalls' ? playbook.troubleshooting_and_pitfalls : [],
199
+ apis_to_use: section === 'apis_to_use' ? playbook.apis_to_use : []
200
+ };
201
+ }
202
+ if (min_helpful !== undefined) {
203
+ for (const key of Object.keys(playbook)) {
204
+ playbook[key] = playbook[key].filter((b) => (b.helpful || 0) >= min_helpful);
205
+ }
206
+ }
207
+ const result = { playbook };
208
+ if (response.metadata) {
209
+ result.metadata = response.metadata;
210
+ }
211
+ return {
212
+ content: [{
213
+ type: 'text',
214
+ text: JSON.stringify(result, null, 2)
215
+ }]
216
+ };
217
+ }
218
+ case 'ace_search': {
219
+ const { query, section, threshold, include_metadata } = args;
220
+ console.error(`🔍 Searching for patterns: "${query}"`);
221
+ // Fetch config if threshold not specified
222
+ let searchThreshold = threshold;
223
+ if (!searchThreshold) {
224
+ const serverConfig = await aceClient.getConfig();
225
+ searchThreshold = serverConfig.constitution_threshold || 0.85;
226
+ console.error(`📊 Using dynamic threshold from config: ${searchThreshold}`);
227
+ }
228
+ const response = await aceClient.searchPatterns({
229
+ query,
230
+ section,
231
+ threshold: searchThreshold,
232
+ include_metadata
233
+ });
234
+ const result = {
235
+ query,
236
+ threshold: response.threshold,
237
+ results: response.similar_patterns,
238
+ count: response.count,
239
+ message: `Found ${response.count} patterns matching "${query}"`
240
+ };
241
+ if (response.metadata) {
242
+ result.metadata = response.metadata;
243
+ }
244
+ return {
245
+ content: [{
246
+ type: 'text',
247
+ text: JSON.stringify(result, null, 2)
248
+ }]
249
+ };
250
+ }
251
+ case 'ace_top_patterns': {
252
+ const { section, limit, min_helpful } = args;
253
+ console.error('⭐ Fetching top patterns...');
254
+ const results = await aceClient.getTopPatterns({
255
+ section,
256
+ limit: limit || 10,
257
+ min_helpful: min_helpful || 0
258
+ });
259
+ return {
260
+ content: [{
261
+ type: 'text',
262
+ text: JSON.stringify({
263
+ section: section || 'all',
264
+ results,
265
+ count: results.length,
266
+ message: `Retrieved ${results.length} top-rated patterns`
267
+ }, null, 2)
268
+ }]
269
+ };
270
+ }
271
+ case 'ace_clear': {
272
+ const { confirm } = args;
273
+ if (!confirm) {
274
+ throw new Error('Must set confirm=true to clear playbook');
275
+ }
276
+ console.error('đŸ—‘ī¸ Clearing playbook...');
277
+ await aceClient.clearPlaybook();
278
+ aceClient.invalidateCache();
279
+ return {
280
+ content: [{
281
+ type: 'text',
282
+ text: JSON.stringify({
283
+ success: true,
284
+ message: 'Playbook cleared successfully'
285
+ }, null, 2)
286
+ }]
287
+ };
288
+ }
289
+ case 'ace_batch_get': {
290
+ const { pattern_ids } = args;
291
+ if (!Array.isArray(pattern_ids) || pattern_ids.length === 0) {
292
+ return {
293
+ content: [{
294
+ type: 'text',
295
+ text: 'Error: pattern_ids must be a non-empty array'
296
+ }]
297
+ };
298
+ }
299
+ console.error(`đŸ“Ļ Batch fetching ${pattern_ids.length} patterns...`);
300
+ const result = await aceClient.batchGetPatterns(pattern_ids);
301
+ return {
302
+ content: [{
303
+ type: 'text',
304
+ text: JSON.stringify(result, null, 2)
305
+ }]
306
+ };
307
+ }
308
+ case 'ace_delta': {
309
+ const { operation, bullets } = args;
310
+ console.error(`🔄 Applying delta operation: ${operation}...`);
311
+ for (const bullet of bullets) {
312
+ await aceClient.applyDelta({
313
+ type: operation.toUpperCase(),
314
+ section: bullet.section,
315
+ content: bullet.content,
316
+ bullet_id: bullet.id,
317
+ helpful_delta: bullet.helpful,
318
+ harmful_delta: bullet.harmful,
319
+ evidence: bullet.evidence
320
+ });
321
+ }
322
+ aceClient.invalidateCache();
323
+ return {
324
+ content: [{
325
+ type: 'text',
326
+ text: JSON.stringify({
327
+ success: true,
328
+ operation,
329
+ bullets_affected: bullets.length,
330
+ message: `Successfully applied ${operation} operation to ${bullets.length} bullet(s)`
331
+ }, null, 2)
332
+ }]
333
+ };
334
+ }
335
+ // ========================================================================
336
+ // Learning & Bootstrap
337
+ // ========================================================================
338
+ case 'ace_learn': {
339
+ const { task, trajectory, success, output, error, playbook_used } = args;
340
+ console.error('📤 Sending execution trace to server...');
341
+ // Convert string array to TrajectoryStep array if needed
342
+ const formattedTrajectory = trajectory.map((step, index) => {
343
+ if (typeof step === 'string') {
344
+ return {
345
+ step: index + 1,
346
+ action: step,
347
+ args: {},
348
+ result: 'Completed'
349
+ };
350
+ }
351
+ return step;
352
+ });
353
+ const trace = {
354
+ task,
355
+ trajectory: formattedTrajectory,
356
+ result: { success, output, error },
357
+ playbook_used: playbook_used || [],
358
+ timestamp: new Date().toISOString()
359
+ };
360
+ try {
361
+ const result = await aceClient.storeExecutionTrace(trace);
362
+ aceClient.invalidateCache();
363
+ console.error('✅ Execution trace stored. Server is analyzing...');
364
+ return {
365
+ content: [{
366
+ type: 'text',
367
+ text: JSON.stringify({
368
+ success: true,
369
+ message: 'Execution trace stored successfully. Server-side Reflector and Curator will process asynchronously.',
370
+ task,
371
+ timestamp: trace.timestamp,
372
+ analysis_triggered: result.analysis_performed || false,
373
+ learning_statistics: result.learning_statistics
374
+ }, null, 2)
375
+ }]
376
+ };
377
+ }
378
+ catch (err) {
379
+ console.error('❌ Error storing trace:', err);
380
+ return {
381
+ content: [{
382
+ type: 'text',
383
+ text: JSON.stringify({
384
+ success: false,
385
+ error: err.message || 'Failed to store execution trace'
386
+ }, null, 2)
387
+ }],
388
+ isError: true
389
+ };
390
+ }
391
+ }
392
+ case 'ace_bootstrap': {
393
+ const { mode, thoroughness, repo_path, max_files, commit_limit, days_back, merge_with_existing: _mergeWithExisting } = args;
394
+ const thoroughnessLevel = thoroughness || 'medium';
395
+ const preset = THOROUGHNESS_PRESETS[thoroughnessLevel];
396
+ const effectiveMaxFiles = max_files ?? preset.max_files;
397
+ const effectiveCommitLimit = commit_limit ?? preset.commit_limit;
398
+ const effectiveDaysBack = days_back ?? preset.days_back;
399
+ const analysisMode = mode || 'hybrid';
400
+ const projectPath = repo_path || process.cwd();
401
+ console.error(`🚀 Bootstrapping playbook (mode: ${analysisMode}, thoroughness: ${thoroughnessLevel})...`);
402
+ console.error(` Files: ${effectiveMaxFiles === -1 ? 'unlimited' : effectiveMaxFiles}, Commits: ${effectiveCommitLimit}, Days: ${effectiveDaysBack}`);
403
+ try {
404
+ console.error('📚 Running local codebase analysis...');
405
+ const playbook = await initializationService.initializeFromCodebase(projectPath, {
406
+ mode: analysisMode,
407
+ commitLimit: effectiveCommitLimit,
408
+ daysBack: effectiveDaysBack,
409
+ maxFiles: effectiveMaxFiles
410
+ });
411
+ const allBullets = [
412
+ ...playbook.strategies_and_hard_rules,
413
+ ...playbook.useful_code_snippets,
414
+ ...playbook.troubleshooting_and_pitfalls,
415
+ ...playbook.apis_to_use
416
+ ];
417
+ console.error(`✅ Discovered ${allBullets.length} patterns locally`);
418
+ if (allBullets.length === 0) {
419
+ console.error('âš ī¸ No patterns found - playbook is empty');
420
+ return {
421
+ content: [{
422
+ type: 'text',
423
+ text: JSON.stringify({
424
+ success: true,
425
+ patternsExtracted: 0,
426
+ message: 'No patterns found in codebase. Try working on real tasks to build the playbook through online learning.'
427
+ }, null, 2)
428
+ }]
429
+ };
430
+ }
431
+ // Build code blocks for bootstrap endpoint
432
+ const codeBlocks = [];
433
+ for (const snippet of playbook.useful_code_snippets) {
434
+ if (snippet.evidence && snippet.evidence.length > 0) {
435
+ codeBlocks.push(`File: ${snippet.evidence[0]}\n\n${snippet.content}`);
436
+ }
437
+ else {
438
+ codeBlocks.push(snippet.content);
439
+ }
440
+ }
441
+ for (const pattern of playbook.troubleshooting_and_pitfalls) {
442
+ if (pattern.content.length > 100) {
443
+ codeBlocks.push(pattern.content);
444
+ }
445
+ }
446
+ for (const pattern of playbook.strategies_and_hard_rules) {
447
+ if (pattern.content.length > 100) {
448
+ codeBlocks.push(pattern.content);
449
+ }
450
+ }
451
+ for (const pattern of playbook.apis_to_use) {
452
+ if (pattern.content.length > 100) {
453
+ codeBlocks.push(pattern.content);
454
+ }
455
+ }
456
+ console.error(`📤 Sending ${codeBlocks.length} code blocks to ACE server for bootstrap...`);
457
+ const bootstrapResult = await aceClient.bootstrap({
458
+ mode: analysisMode,
459
+ code_blocks: codeBlocks,
460
+ metadata: {
461
+ blocks_extracted: codeBlocks.length,
462
+ thoroughness: thoroughness || 'medium',
463
+ file_extensions: []
464
+ }
465
+ });
466
+ aceClient.invalidateCache();
467
+ console.error(`✅ Bootstrap complete: ${bootstrapResult.blocks_received} blocks → ${bootstrapResult.patterns_extracted} patterns (${bootstrapResult.compression_percentage}% compression)`);
468
+ return {
469
+ content: [{
470
+ type: 'text',
471
+ text: JSON.stringify({
472
+ success: true,
473
+ mode: analysisMode,
474
+ blocks_sent: bootstrapResult.blocks_received,
475
+ patterns_extracted: bootstrapResult.patterns_extracted,
476
+ compression_percentage: bootstrapResult.compression_percentage,
477
+ breakdown: bootstrapResult.by_section,
478
+ average_confidence: bootstrapResult.average_confidence,
479
+ analysis_time_seconds: bootstrapResult.analysis_time_seconds,
480
+ message: `Bootstrap complete! Sent ${bootstrapResult.blocks_received} code blocks → Server extracted ${bootstrapResult.patterns_extracted} unique patterns (${bootstrapResult.compression_percentage}% compression via semantic deduplication)`,
481
+ next_steps: 'Use /ace-patterns to view the deduplicated playbook.'
482
+ }, null, 2)
483
+ }]
484
+ };
485
+ }
486
+ catch (err) {
487
+ console.error('❌ Error during bootstrap:', err);
488
+ return {
489
+ content: [{
490
+ type: 'text',
491
+ text: JSON.stringify({
492
+ success: false,
493
+ error: err.message || 'Failed to bootstrap playbook',
494
+ stack: err.stack
495
+ }, null, 2)
496
+ }],
497
+ isError: true
498
+ };
499
+ }
500
+ }
501
+ // ========================================================================
502
+ // Utilities
503
+ // ========================================================================
504
+ case 'ace_status': {
505
+ console.error('📊 Fetching status from server...');
506
+ const status = await aceClient.getAnalytics();
507
+ return {
508
+ content: [{
509
+ type: 'text',
510
+ text: JSON.stringify(status, null, 2)
511
+ }]
512
+ };
513
+ }
514
+ case 'ace_version_status': {
515
+ console.error('📊 Checking version compatibility...');
516
+ if (!versionStatus) {
517
+ versionStatus = await checkVersionCompatibility();
518
+ }
519
+ return {
520
+ content: [{
521
+ type: 'text',
522
+ text: JSON.stringify(versionStatus, null, 2)
523
+ }]
524
+ };
525
+ }
526
+ case 'ace_cache_clear': {
527
+ const { cache_type } = args;
528
+ const cacheType = cache_type || 'all';
529
+ console.error(`đŸ—‘ī¸ Clearing ${cacheType} cache...`);
530
+ if (cacheType === 'ram' || cacheType === 'all') {
531
+ aceClient.invalidateCache();
532
+ aceClient.clearConfigCache();
533
+ console.error('✅ RAM cache cleared (playbook + config)');
534
+ }
535
+ if (cacheType === 'sqlite' || cacheType === 'all') {
536
+ const localCache = aceClient.getLocalCache();
537
+ if (localCache) {
538
+ localCache.clear();
539
+ console.error('✅ SQLite cache cleared');
540
+ }
541
+ else {
542
+ console.error('â„šī¸ SQLite cache not available (skipped)');
543
+ }
544
+ }
545
+ return {
546
+ content: [{
547
+ type: 'text',
548
+ text: JSON.stringify({
549
+ success: true,
550
+ cache_type: cacheType,
551
+ message: `${cacheType.toUpperCase()} cache cleared successfully`
552
+ }, null, 2)
553
+ }]
554
+ };
555
+ }
556
+ default:
557
+ throw new Error(`Unknown tool: ${name}`);
558
+ }
559
+ }
560
+ catch (err) {
561
+ console.error(`❌ Error in ${name}:`, err);
562
+ return {
563
+ content: [{
564
+ type: 'text',
565
+ text: JSON.stringify({
566
+ success: false,
567
+ error: err.message || String(err)
568
+ }, null, 2)
569
+ }],
570
+ isError: true
571
+ };
572
+ }
573
+ });
574
+ // Start server
575
+ async function main() {
576
+ const transport = new StdioServerTransport();
577
+ await server.connect(transport);
578
+ console.error(`✅ ACE MCP Server v${VERSION} started`);
579
+ console.error('🔗 Server:', config.serverUrl);
580
+ console.error('📋 Project:', config.projectId);
581
+ if (config.orgs && Object.keys(config.orgs).length > 0) {
582
+ console.error('🌐 Multi-org:', `${Object.keys(config.orgs).length} organization(s) configured`);
583
+ }
584
+ console.error('🌍 Universal MCP compatibility (no sampling required)');
585
+ }
586
+ main().catch((error) => {
587
+ console.error('❌ Fatal error:', error);
588
+ process.exit(1);
589
+ });
590
+ //# sourceMappingURL=index.js.map