@yamo/mcp-server 1.3.0 → 1.3.2

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 CHANGED
@@ -1,4 +1,4 @@
1
- # 🤖 YAMO Chain MCP Server [![npm version](https://badge.fury.io/js/@yamo%2Fmcp-server.svg)](https://www.npmjs.com/package/@yamo/mcp-server)
1
+ # 🤖 YAMO Chain MCP Server [![npm version](https://img.shields.io/npm/v/@yamo/mcp-server?style=flat-square)](https://www.npmjs.com/package/@yamo/mcp-server)
2
2
 
3
3
  This MCP Server acts as a bridge, allowing LLMs to interact with the YAMO Blockchain. It is now powered by `@yamo/core` for robust IPFS handling.
4
4
 
package/dist/index.js CHANGED
@@ -47,6 +47,14 @@ const crypto_1 = __importDefault(require("crypto"));
47
47
  const path_1 = __importDefault(require("path"));
48
48
  const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '../package.json'), 'utf8'));
49
49
  dotenv.config();
50
+ // Validation helper for bytes32 hashes (Part 3: Security Fixes)
51
+ function validateBytes32(value, fieldName) {
52
+ if (!value.match(/^0x[a-fA-F0-9]{64}$/)) {
53
+ throw new Error(`${fieldName} must be a valid bytes32 hash (0x + 64 hex chars). ` +
54
+ `Received: ${value.substring(0, 20)}...` +
55
+ `\nDo NOT include algorithm prefixes like "sha256:"`);
56
+ }
57
+ }
50
58
  const SUBMIT_BLOCK_TOOL = {
51
59
  name: "yamo_submit_block",
52
60
  description: `Submits a YAMO block to the YAMORegistry smart contract.
@@ -227,22 +235,31 @@ class YamoMcpServer {
227
235
  try {
228
236
  if (name === "yamo_submit_block") {
229
237
  const { blockId, previousBlock, contentHash, consensusType, ledger, content, files, encryptionKey } = args;
230
- // Process files - auto-read if they're file paths
238
+ // Process files - auto-read if they're file paths (with security fix)
231
239
  let processedFiles = files;
232
240
  if (files && Array.isArray(files)) {
233
241
  processedFiles = files.map((file) => {
234
242
  // Check if content is a file path that exists
235
243
  if (typeof file.content === 'string' && fs_1.default.existsSync(file.content)) {
244
+ // Security: Resolve to absolute path and restrict to cwd (Part 3: Security Fixes)
245
+ const filePath = path_1.default.resolve(file.content);
246
+ const allowedDir = process.cwd();
247
+ if (!filePath.startsWith(allowedDir)) {
248
+ throw new Error(`File path outside allowed directory: ${file.content}`);
249
+ }
236
250
  console.error(`[DEBUG] Auto-reading file from path: ${file.content}`);
237
251
  return {
238
252
  name: file.name,
239
- content: fs_1.default.readFileSync(file.content, 'utf8')
253
+ content: fs_1.default.readFileSync(filePath, 'utf8')
240
254
  };
241
255
  }
242
256
  // Otherwise use content as-is
243
257
  return file;
244
258
  });
245
259
  }
260
+ // Input validation (Part 3: Security Fixes)
261
+ validateBytes32(contentHash, "contentHash");
262
+ validateBytes32(previousBlock, "previousBlock");
246
263
  let ipfsCID = undefined;
247
264
  if (content) {
248
265
  ipfsCID = await this.ipfs.upload({
@@ -251,13 +268,19 @@ class YamoMcpServer {
251
268
  encryptionKey
252
269
  });
253
270
  }
254
- const txHash = await this.chain.submitBlock(blockId, previousBlock, contentHash, consensusType, ledger, ipfsCID);
271
+ const tx = await this.chain.submitBlock(blockId, previousBlock, contentHash, consensusType, ledger, ipfsCID);
272
+ const receipt = await tx.wait();
255
273
  return {
256
274
  content: [{ type: "text", text: JSON.stringify({
257
275
  success: true,
258
276
  blockId,
259
- transactionHash: txHash,
260
- ipfsCID: ipfsCID || null
277
+ transactionHash: tx.hash,
278
+ blockNumber: receipt.blockNumber,
279
+ gasUsed: receipt.gasUsed.toString(),
280
+ effectiveGasPrice: receipt.effectiveGasPrice?.toString(),
281
+ ipfsCID: ipfsCID || null,
282
+ contractAddress: this.chain.getContractAddress(),
283
+ timestamp: new Date().toISOString()
261
284
  }, null, 2) }],
262
285
  };
263
286
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yamo/mcp-server",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "YAMO Protocol v0.4 - Model Context Protocol server for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",
@@ -17,7 +17,9 @@
17
17
  "build": "tsc",
18
18
  "prepublishOnly": "npm run build",
19
19
  "start": "node dist/index.js",
20
- "dev": "ts-node src/index.ts"
20
+ "dev": "ts-node src/index.ts",
21
+ "test": "node --test test/**/*.test.js",
22
+ "test:security": "node --test test/security.test.js"
21
23
  },
22
24
  "keywords": [
23
25
  "yamo",