@mrxkun/mcfast-mcp 3.5.3 → 3.5.5
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/package.json +1 -1
- package/src/index.js +58 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrxkun/mcfast-mcp",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.5",
|
|
4
4
|
"description": "Ultra-fast code editing with WASM acceleration, fuzzy patching, multi-layer caching, and 8 unified tools. Optimized for AI code assistants with 80-98% latency reduction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/index.js
CHANGED
|
@@ -203,7 +203,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
203
203
|
// CORE TOOL 1: edit (consolidates apply_fast + edit_file + apply_search_replace)
|
|
204
204
|
{
|
|
205
205
|
name: "edit",
|
|
206
|
-
description: "**PRIMARY TOOL FOR EDITING FILES** - Intelligent auto-switching strategies: (1) Search & Replace (Fastest) - use 'Replace X with Y', (2) Placeholder (Efficient) - use '// ... existing code ...', (3) Mercury AI (Intelligent) - for complex refactoring. Includes Auto-Rollback for syntax errors.",
|
|
206
|
+
description: "**PRIMARY TOOL FOR EDITING FILES** - Intelligent auto-switching strategies: (1) Search & Replace (Fastest) - use 'Replace X with Y', (2) Placeholder (Efficient) - use '// ... existing code ...' placeholders to save tokens.", (3) Mercury AI (Intelligent) - for complex refactoring. Includes Auto-Rollback for syntax errors.",
|
|
207
207
|
inputSchema: {
|
|
208
208
|
type: "object",
|
|
209
209
|
properties: {
|
|
@@ -514,6 +514,17 @@ async function reportAudit(data) {
|
|
|
514
514
|
try {
|
|
515
515
|
// Only report if dashboard logging is enabled
|
|
516
516
|
if (process.env.MCFAST_ENABLE_AUDIT !== 'true') {
|
|
517
|
+
if (VERBOSE) {
|
|
518
|
+
console.error(`${colors.dim}[Audit] Skipped - MCFAST_ENABLE_AUDIT not set to 'true'${colors.reset}`);
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Check if we have a token
|
|
524
|
+
if (!TOKEN) {
|
|
525
|
+
if (VERBOSE) {
|
|
526
|
+
console.error(`${colors.yellow}[Audit] Skipped - No MCFAST_TOKEN provided${colors.reset}`);
|
|
527
|
+
}
|
|
517
528
|
return;
|
|
518
529
|
}
|
|
519
530
|
|
|
@@ -533,33 +544,46 @@ async function reportAudit(data) {
|
|
|
533
544
|
};
|
|
534
545
|
|
|
535
546
|
// Send to dashboard API
|
|
536
|
-
const DASHBOARD_API_URL = process.env.MCFAST_DASHBOARD_URL || 'https://mcfast.vercel.app/api/v1/audit';
|
|
547
|
+
const DASHBOARD_API_URL = process.env.MCFAST_DASHBOARD_URL || 'https://mcfast.vercel.app/api/v1/logs/audit';
|
|
537
548
|
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
549
|
+
if (VERBOSE) {
|
|
550
|
+
console.error(`${colors.dim}[Audit] Sending to: ${DASHBOARD_API_URL}${colors.reset}`);
|
|
551
|
+
console.error(`${colors.dim}[Audit] Tool: ${auditData.tool}, Status: ${auditData.status}${colors.reset}`);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
const response = await fetch(DASHBOARD_API_URL, {
|
|
555
|
+
method: 'POST',
|
|
556
|
+
headers: {
|
|
557
|
+
'Content-Type': 'application/json',
|
|
558
|
+
'Authorization': `Bearer ${TOKEN}`
|
|
559
|
+
},
|
|
560
|
+
body: JSON.stringify(auditData)
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
if (!response.ok) {
|
|
564
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
565
|
+
if (VERBOSE) {
|
|
566
|
+
console.error(`${colors.yellow}[Audit] Failed - HTTP ${response.status}: ${errorText}${colors.reset}`);
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
if (VERBOSE) {
|
|
570
|
+
console.error(`${colors.green}[Audit] Logged successfully ✓${colors.reset}`);
|
|
571
|
+
}
|
|
552
572
|
}
|
|
553
573
|
|
|
554
574
|
// Also log to local file if configured
|
|
555
575
|
if (process.env.MCFAST_AUDIT_FILE) {
|
|
556
576
|
const logLine = JSON.stringify(auditData) + '\n';
|
|
557
|
-
await fs.appendFile(process.env.MCFAST_AUDIT_FILE, logLine).catch(() => {
|
|
577
|
+
await fs.appendFile(process.env.MCFAST_AUDIT_FILE, logLine).catch((err) => {
|
|
578
|
+
if (VERBOSE) {
|
|
579
|
+
console.error(`${colors.yellow}[Audit] Failed to write to file:${colors.reset}`, err.message);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
558
582
|
}
|
|
559
583
|
} catch (error) {
|
|
560
584
|
// Silent fail - audit should never break the tool
|
|
561
585
|
if (VERBOSE) {
|
|
562
|
-
console.error(`${colors.
|
|
586
|
+
console.error(`${colors.yellow}[Audit] Error (non-critical):${colors.reset}`, error.message);
|
|
563
587
|
}
|
|
564
588
|
}
|
|
565
589
|
}
|
|
@@ -1192,6 +1216,7 @@ async function handleReadFileInternal({ path: filePath, start_line, end_line, ma
|
|
|
1192
1216
|
let endLine = end_line ? parseInt(end_line) : -1;
|
|
1193
1217
|
let outputContent;
|
|
1194
1218
|
let totalLines;
|
|
1219
|
+
let lineRangeInfo = '';
|
|
1195
1220
|
|
|
1196
1221
|
if ((stats.size > STREAM_THRESHOLD && (start_line || end_line)) || stats.size > 10 * 1024 * 1024) {
|
|
1197
1222
|
const { Readable } = await import('stream');
|
|
@@ -1590,6 +1615,7 @@ async function handleReadFile({ path: filePath, start_line, end_line }) {
|
|
|
1590
1615
|
let endLine = end_line ? parseInt(end_line) : -1;
|
|
1591
1616
|
let outputContent;
|
|
1592
1617
|
let totalLines;
|
|
1618
|
+
let lineRangeInfo = '';
|
|
1593
1619
|
|
|
1594
1620
|
if ((stats.size > STREAM_THRESHOLD && (start_line || end_line)) || stats.size > 10 * 1024 * 1024) {
|
|
1595
1621
|
const { Readable } = await import('stream');
|
|
@@ -1817,6 +1843,13 @@ async function handleSearchCodeAI({ query, files, contextLines = 2 }) {
|
|
|
1817
1843
|
async function handleGetDefinition({ path: filePath, symbol }) {
|
|
1818
1844
|
if (!filePath || !symbol) throw new Error("Missing path or symbol");
|
|
1819
1845
|
|
|
1846
|
+
// Check if path is a directory
|
|
1847
|
+
const absolutePath = path.resolve(filePath);
|
|
1848
|
+
const stats = await fs.stat(absolutePath);
|
|
1849
|
+
if (!stats.isFile()) {
|
|
1850
|
+
throw new Error(`Path is not a file: ${filePath}`);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1820
1853
|
// Read file content first
|
|
1821
1854
|
const content = await fs.readFile(filePath, 'utf8');
|
|
1822
1855
|
const definitions = await findDefinition(content, filePath, symbol);
|
|
@@ -1837,6 +1870,13 @@ async function handleGetDefinition({ path: filePath, symbol }) {
|
|
|
1837
1870
|
async function handleFindReferences({ path: filePath, symbol }) {
|
|
1838
1871
|
if (!filePath || !symbol) throw new Error("Missing path or symbol");
|
|
1839
1872
|
|
|
1873
|
+
// Check if path is a directory
|
|
1874
|
+
const absolutePath = path.resolve(filePath);
|
|
1875
|
+
const stats = await fs.stat(absolutePath);
|
|
1876
|
+
if (!stats.isFile()) {
|
|
1877
|
+
throw new Error(`Path is not a file: ${filePath}`);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1840
1880
|
const content = await fs.readFile(filePath, 'utf8');
|
|
1841
1881
|
const references = await findReferences(content, filePath, symbol);
|
|
1842
1882
|
|