@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. 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",
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 (TOKEN) {
539
- fetch(DASHBOARD_API_URL, {
540
- method: 'POST',
541
- headers: {
542
- 'Content-Type': 'application/json',
543
- 'Authorization': `Bearer ${TOKEN}`
544
- },
545
- body: JSON.stringify(auditData)
546
- }).catch(err => {
547
- // Silent fail - don't break operations if audit fails
548
- if (VERBOSE) {
549
- console.error(`${colors.dim}Audit log failed (non-critical):${colors.reset}`, err.message);
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.dim}Audit error (non-critical):${colors.reset}`, error.message);
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