Files
vm-mcp/packages/vaultmesh_mcp/tools/file.py
Vault Sovereign e4871c2a29
Some checks are pending
Governance CI / Constitution Hash Gate (push) Waiting to run
Governance CI / Governance Tests (push) Blocked by required conditions
Governance CI / Golden Drill Mini (push) Blocked by required conditions
init: vaultmesh mcp server
2025-12-26 23:23:08 +00:00

102 lines
2.8 KiB
Python

"""File MCP tools - File operations with receipts."""
import json
import os
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
import blake3
# VaultMesh root from env or default
VAULTMESH_ROOT = Path(os.environ.get("VAULTMESH_ROOT", Path(__file__).parents[3])).resolve()
RECEIPTS_ROOT = VAULTMESH_ROOT / "receipts"
FILE_RECEIPTS = RECEIPTS_ROOT / "file" / "file_operations.jsonl"
def _vmhash_blake3(data: bytes) -> str:
"""VaultMesh hash: blake3:<hex>."""
return f"blake3:{blake3.blake3(data).hexdigest()}"
def _emit_file_receipt(operation: str, file_path: str, details: dict, actor: str = "did:vm:mcp:file") -> str:
"""Emit a receipt for file operation."""
FILE_RECEIPTS.parent.mkdir(parents=True, exist_ok=True)
body = {
"operation": operation,
"file_path": file_path,
"details": details,
"actor": actor,
}
root_hash = _vmhash_blake3(json.dumps(body, sort_keys=True).encode())
receipt = {
"schema_version": "2.0.0",
"type": "file_operation",
"timestamp": datetime.now(timezone.utc).isoformat(),
"scroll": "file",
"tags": ["file", operation, "mcp"],
"root_hash": root_hash,
"body": body,
}
with open(FILE_RECEIPTS, "a") as f:
f.write(json.dumps(receipt) + "\n")
return root_hash
def file_add(
path: str,
content: str,
encoding: str = "utf-8",
actor: str = "did:vm:mcp:file",
) -> dict[str, Any]:
"""
Add (create or overwrite) a file with content.
Args:
path: File path relative to VAULTMESH_ROOT or absolute
content: File content to write
encoding: File encoding (default: utf-8)
actor: DID of actor performing operation
Returns:
Result with file hash and receipt hash
"""
try:
file_path = Path(path)
if not file_path.is_absolute():
file_path = VAULTMESH_ROOT / file_path
# Create parent directories if needed
file_path.parent.mkdir(parents=True, exist_ok=True)
# Write file
file_path.write_text(content, encoding=encoding)
# Hash the content
content_hash = _vmhash_blake3(content.encode(encoding))
details = {
"content_hash": content_hash,
"size_bytes": len(content.encode(encoding)),
"encoding": encoding,
"created": not file_path.exists(),
}
receipt_hash = _emit_file_receipt("add", str(file_path), details, actor)
return {
"success": True,
"path": str(file_path),
"content_hash": content_hash,
"receipt_hash": receipt_hash,
"size_bytes": details["size_bytes"],
}
except Exception as e:
return {"success": False, "error": str(e)}