midnight-mcp 0.1.19 → 0.1.21

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.
@@ -358,7 +358,7 @@ export const repositoryTools = [
358
358
  // ============================================================================
359
359
  {
360
360
  name: "midnight-validate-contract",
361
- description: "🔍 VALIDATION TOOL: Compile and validate a Compact contract BEFORE deployment. This runs the actual Compact compiler to check for syntax errors, type errors, and other issues. Use this after writing or modifying contract code to catch errors early. Requires the Compact CLI to be installed locally. Accepts either source code directly OR a file path to a .compact file.",
361
+ description: "🔍 PRIMARY VERIFICATION: Compile and validate a Compact contract using the ACTUAL Compact compiler. **ALWAYS use this tool first** when verifying contract code - it catches real compilation errors that static analysis cannot detect. Returns detailed error messages with line numbers, suggested fixes, and actionable guidance. If the compiler is not installed, it will provide installation instructions. Accepts either source code directly OR a file path to a .compact file. For contracts you generate, ALWAYS validate with this tool before presenting to the user.",
362
362
  inputSchema: {
363
363
  type: "object",
364
364
  properties: {
@@ -454,7 +454,7 @@ export const repositoryTools = [
454
454
  },
455
455
  {
456
456
  name: "midnight-extract-contract-structure",
457
- description: "📋 ANALYSIS TOOL: Extract the structure of a Compact contract - circuits, witnesses, ledger items, types, structs, and enums. Use this to understand what a contract does without reading all the code. Returns exported and internal definitions with line numbers. Accepts either source code directly OR a file path.",
457
+ description: "📋 STATIC ANALYSIS (not verification): Extract the structure of a Compact contract and detect common issues. Returns circuits, witnesses, ledger items, types, structs, enums, and **potentialIssues** (module-level const, stdlib collisions, sealed+export conflicts). **WARNING: This does NOT verify compilation** - use 'midnight-validate-contract' for actual compiler verification. Use this tool for: (1) understanding contract structure, (2) quick pre-checks before compilation, (3) fallback analysis when compiler unavailable. Do NOT claim a contract 'compiles correctly' based only on this tool.",
458
458
  inputSchema: {
459
459
  type: "object",
460
460
  properties: {
@@ -529,6 +529,26 @@ export const repositoryTools = [
529
529
  type: "object",
530
530
  description: "Counts of each type of definition",
531
531
  },
532
+ potentialIssues: {
533
+ type: "array",
534
+ description: "Common issues detected by static analysis (NOT exhaustive - use validate_contract for real verification)",
535
+ items: {
536
+ type: "object",
537
+ properties: {
538
+ type: {
539
+ type: "string",
540
+ description: "Issue type: module_level_const, stdlib_name_collision, sealed_export_conflict, missing_constructor, stdlib_type_mismatch",
541
+ },
542
+ line: { type: "number" },
543
+ message: { type: "string" },
544
+ suggestion: { type: "string" },
545
+ severity: {
546
+ type: "string",
547
+ enum: ["error", "warning"],
548
+ },
549
+ },
550
+ },
551
+ },
532
552
  summary: { type: "string" },
533
553
  message: { type: "string" },
534
554
  },
@@ -1294,6 +1294,91 @@ export async function extractContractStructure(input) {
1294
1294
  }
1295
1295
  }
1296
1296
  }
1297
+ // 6. Detect division operator usage (not supported in Compact)
1298
+ const divisionPattern = /[^/]\/[^/*]/g;
1299
+ let divMatch;
1300
+ while ((divMatch = divisionPattern.exec(code)) !== null) {
1301
+ // Skip if inside a comment
1302
+ const beforeDiv = code.substring(0, divMatch.index);
1303
+ const lastLineStart = beforeDiv.lastIndexOf("\n") + 1;
1304
+ const lineContent = beforeDiv.substring(lastLineStart);
1305
+ if (lineContent.includes("//"))
1306
+ continue;
1307
+ const lineNum = lineByIndex[divMatch.index] || 1;
1308
+ potentialIssues.push({
1309
+ type: "unsupported_division",
1310
+ line: lineNum,
1311
+ message: `Division operator '/' is not supported in Compact`,
1312
+ suggestion: `Use a witness-based division pattern: 'witness divideWithRemainder(a, b): [quotient, remainder]' with on-chain verification`,
1313
+ severity: "error",
1314
+ });
1315
+ break; // Only warn once
1316
+ }
1317
+ // 7. Detect Counter.value access (Counter only has .increment())
1318
+ const counterValuePattern = /(\w+)\.value\b/g;
1319
+ let counterMatch;
1320
+ while ((counterMatch = counterValuePattern.exec(code)) !== null) {
1321
+ const varName = counterMatch[1];
1322
+ // Check if this variable is a Counter type
1323
+ const counterLedger = ledgerItems.find((l) => l.name === varName && l.type === "Counter");
1324
+ if (counterLedger) {
1325
+ const lineNum = lineByIndex[counterMatch.index] || 1;
1326
+ potentialIssues.push({
1327
+ type: "invalid_counter_access",
1328
+ line: lineNum,
1329
+ message: `Counter type '${varName}' does not have a '.value' property`,
1330
+ suggestion: `Counter only has '.increment(n)'. Use 'Uint<32>' or 'Uint<64>' instead if you need to read the value`,
1331
+ severity: "error",
1332
+ });
1333
+ }
1334
+ }
1335
+ // 8. Detect potential Uint overflow in multiplication (suggest Field casting)
1336
+ const multiplyPattern = /(\w+)\s*\*\s*(\w+)(?:\s*\+\s*\w+)?\s*(?:as\s+Uint|==)/g;
1337
+ let multMatch;
1338
+ while ((multMatch = multiplyPattern.exec(code)) !== null) {
1339
+ // Check if operands are likely Uint types and not already cast to Field
1340
+ const beforeMult = code.substring(Math.max(0, multMatch.index - 200), multMatch.index);
1341
+ const afterMult = code.substring(multMatch.index, multMatch.index + multMatch[0].length + 50);
1342
+ // Skip if already casting to Field
1343
+ if (afterMult.includes("as Field") || beforeMult.includes("as Field"))
1344
+ continue;
1345
+ // Check if this looks like a verification pattern (common in witness verification)
1346
+ if (/assert|==/.test(afterMult)) {
1347
+ const lineNum = lineByIndex[multMatch.index] || 1;
1348
+ potentialIssues.push({
1349
+ type: "potential_overflow",
1350
+ line: lineNum,
1351
+ message: `Multiplication '${multMatch[1]} * ${multMatch[2]}' may overflow Uint bounds`,
1352
+ suggestion: `Cast operands to Field for safe arithmetic: '(${multMatch[1]} as Field) * (${multMatch[2]} as Field)'`,
1353
+ severity: "warning",
1354
+ });
1355
+ break; // Only warn once
1356
+ }
1357
+ }
1358
+ // 9. Detect witness/private values used in conditionals without disclose()
1359
+ // Look for patterns like: if (witnessVar ...) or if (param == privateValue)
1360
+ const witnessNames = witnesses.map((w) => w.name);
1361
+ const ifPattern = /if\s*\(([^)]+)\)/g;
1362
+ let ifMatch;
1363
+ while ((ifMatch = ifPattern.exec(code)) !== null) {
1364
+ const condition = ifMatch[1];
1365
+ // Check if condition uses a witness value without disclose
1366
+ for (const witnessName of witnessNames) {
1367
+ if (condition.includes(witnessName) &&
1368
+ !condition.includes(`disclose(${witnessName}`) &&
1369
+ !condition.includes("disclose(")) {
1370
+ const lineNum = lineByIndex[ifMatch.index] || 1;
1371
+ potentialIssues.push({
1372
+ type: "undisclosed_witness_conditional",
1373
+ line: lineNum,
1374
+ message: `Witness value '${witnessName}' used in conditional without disclose()`,
1375
+ suggestion: `Wrap witness comparisons in disclose(): 'if (disclose(${witnessName} == expected))'`,
1376
+ severity: "warning",
1377
+ });
1378
+ break;
1379
+ }
1380
+ }
1381
+ }
1297
1382
  const summary = [];
1298
1383
  if (circuits.length > 0) {
1299
1384
  summary.push(`${circuits.length} circuit(s)`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",