@rel-time/mcp-server 1.2.11 → 1.2.12

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
@@ -40,7 +40,8 @@ Once paid via Lightning or Stripe (or if you pass an existing `rel_key_...` key)
40
40
 
41
41
  | Tool Name | Requires Key? | What It Does |
42
42
  | :--- | :---: | :--- |
43
- | `reltime_anchor_file` | Yes | Computes the SHA-256 hash of a local file **on your machine** (0 bytes uploaded), supports `biometric: true` for **Biometric Anchors** (TouchID/FaceID/YubiKey), anchors via `POST /v1/anchor`, saves `reltime-stamp-<filename>.svg` and `reltime-doomsday-proof-<filename>.json`, and automatically outputs a clickable **Stamped Copy** (`reltime-stamped-<name>.pdf` or `.png`). |
43
+ | `reltime_anchor_file` | Yes | Computes the SHA-256 hash of a local file **on your machine** (0 bytes uploaded), supports `biometric: true` for **Biometric Anchors** (TouchID/FaceID/YubiKey), anchors via `POST /v1/anchor`, saves `reltime-stamp-<filename>.svg`, `reltime-certificate-<filename>.html`, and `reltime-doomsday-proof-<filename>.json`, and automatically outputs a clickable **Stamped Copy** (`reltime-stamped-<name>.pdf` or `.png`). |
44
+ | `reltime_anchor_folder` | Yes | **Bulk folder anchoring (10 to 5,000+ files in one call):** Hashes all files in a local folder 100% locally, supports `biometric: true` (Passkey) or Anonymous mode, automatically skips already-anchored files (safe to resume), and keeps your directory clean by storing per-file Doomsday Proofs inside `<folder>/_reltime_proofs/` plus a master `reltime-batch-manifest.json`. |
44
45
  | `reltime_audit_trail` | Yes | Fetches the account's chronological anchor ledger (`GET /v1/account/history`), aggregates Bitcoin block settlements, VDF `T_index` ticks, and Corporate Hardware Passkey (`signer_public_key`) signatures, optionally verifies a local file or entire folder bit-for-bit (`verify_local_path`), and spins up a self-contained interactive HTML Audit Report (`reltime-audit-report-*.html`) in your browser. |
45
46
  | `reltime_link_passkey` | **No** | Opens `https://rel-time.com/mcp-passkey` in the system browser so the user can touch TouchID / FaceID / YubiKey once, saving `{ public_key_hex, passkey_signature }` to `~/.reltime/passkey.json` for seamless Biometric Anchors. |
46
47
  | `reltime_stamp_file` | **No** | Overlays the authentic 64-ray Sun-Stamp onto the bottom-right corner of any local PDF or Image (`.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`) 100% locally. |
package/index.js CHANGED
@@ -56,7 +56,7 @@ let LAST_INVOICE_PACK = null;
56
56
 
57
57
  const SERVER_INFO = {
58
58
  name: "rel-time-mcp-server",
59
- version: "1.2.11",
59
+ version: "1.2.12",
60
60
  };
61
61
 
62
62
  /**
@@ -1527,6 +1527,18 @@ function generateAuditReportHtml(audit) {
1527
1527
  </html>`;
1528
1528
  }
1529
1529
 
1530
+ function formatBytes(bytes) {
1531
+ if (bytes === undefined || bytes === null || Number.isNaN(Number(bytes))) {
1532
+ return "Zero-Knowledge (32-Byte Digest)";
1533
+ }
1534
+ const b = Number(bytes);
1535
+ if (b === 0) return "0 Bytes";
1536
+ const k = 1024;
1537
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
1538
+ const i = Math.min(sizes.length - 1, Math.floor(Math.log(b) / Math.log(k)));
1539
+ return `${parseFloat((b / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
1540
+ }
1541
+
1530
1542
  function inferMimeTypeFromFileName(fileName) {
1531
1543
  if (!fileName || fileName === "Zero-Knowledge Hash Payload") {
1532
1544
  return "application/octet-stream (Zero-Knowledge)";
@@ -2111,6 +2123,49 @@ const TOOLS = [
2111
2123
  required: ["file_path"],
2112
2124
  },
2113
2125
  },
2126
+ {
2127
+ name: "reltime_anchor_folder",
2128
+ description:
2129
+ "Bulk zero-knowledge folder anchoring (10 to 5,000+ files in a single call): Hashes all files in a local folder 100% locally (0 file bytes uploaded), supports Biometric (Passkey) or Anonymous anchoring, skips any files that are already anchored (safe to resume), and keeps the user's folder clean by storing per-file Doomsday Proofs inside a single `_reltime_proofs/` subfolder plus a master `reltime-batch-manifest.json`.",
2130
+ inputSchema: {
2131
+ type: "object",
2132
+ properties: {
2133
+ folder_path: {
2134
+ type: "string",
2135
+ description: "Absolute path to the local directory to hash and anchor.",
2136
+ },
2137
+ recursive: {
2138
+ type: "boolean",
2139
+ description: "If true, recursively anchors files in subdirectories. Defaults to false (top-level files only).",
2140
+ },
2141
+ biometric: {
2142
+ type: "boolean",
2143
+ description:
2144
+ "If true, performs Biometric Anchors using your linked hardware Passkey (`~/.reltime/passkey.json`) across the entire folder without repeated TouchID prompts.",
2145
+ },
2146
+ anchor_mode: {
2147
+ type: "string",
2148
+ enum: ["standard", "temporal"],
2149
+ description: "Use 'standard' (default) or 'temporal' (VDF T_index sequential ordering for Superhighway & Autonomous Agents).",
2150
+ },
2151
+ artifact_mode: {
2152
+ type: "string",
2153
+ enum: ["proofs_subfolder", "manifest_only", "full"],
2154
+ description:
2155
+ "Controls local output files so bulk runs never clutter the folder: 'proofs_subfolder' (default) writes JSON proofs into `<folder>/_reltime_proofs/` + `reltime-batch-manifest.json`; 'manifest_only' writes only `reltime-batch-manifest.json`; 'full' also writes SVG Sun-Stamps and HTML certificates.",
2156
+ },
2157
+ concurrency: {
2158
+ type: "number",
2159
+ description: "Number of concurrent anchor requests (default: 5, max: 10).",
2160
+ },
2161
+ api_key: {
2162
+ type: "string",
2163
+ description: "Optional override for RELTIME_API_KEY.",
2164
+ },
2165
+ },
2166
+ required: ["folder_path"],
2167
+ },
2168
+ },
2114
2169
  {
2115
2170
  name: "reltime_link_passkey",
2116
2171
  description:
@@ -2450,12 +2505,27 @@ async function executeTool(name, args = {}) {
2450
2505
  const verifyUrl = `https://rel-time.com/verify?t=${lookupHash}`;
2451
2506
  const stampEndpointUrl = `${API_BASE}/stamp/${lookupHash}`;
2452
2507
 
2453
- const svgContent = data.visual_fingerprint || (await (await fetch(stampEndpointUrl)).text());
2508
+ let svgContent = data.visual_fingerprint || "";
2509
+ const needsSvg = args.save_sun_stamp_svg !== false || args.save_stamped_copy !== false;
2510
+ if (!svgContent && needsSvg) {
2511
+ try {
2512
+ const stampRes = await fetch(stampEndpointUrl);
2513
+ if (stampRes.ok) {
2514
+ svgContent = await stampRes.text();
2515
+ }
2516
+ } catch (e) {
2517
+ // Ignore SVG fetch error if offline/rate-limited
2518
+ }
2519
+ }
2454
2520
 
2455
2521
  let savedSvgPath = null;
2456
- if (args.save_sun_stamp_svg !== false) {
2457
- savedSvgPath = path.join(path.dirname(filePath), `reltime-stamp-${path.basename(filePath)}.svg`);
2458
- fs.writeFileSync(savedSvgPath, svgContent, "utf8");
2522
+ if (args.save_sun_stamp_svg !== false && svgContent) {
2523
+ try {
2524
+ savedSvgPath = path.join(path.dirname(filePath), `reltime-stamp-${path.basename(filePath)}.svg`);
2525
+ fs.writeFileSync(savedSvgPath, svgContent, "utf8");
2526
+ } catch (e) {
2527
+ savedSvgPath = null;
2528
+ }
2459
2529
  }
2460
2530
 
2461
2531
  // Save initial Doomsday Proof JSON alongside the file
@@ -2489,40 +2559,48 @@ async function executeTool(name, args = {}) {
2489
2559
 
2490
2560
  // 3. Automatically generate Stamped Copy (.PDF or .PNG) for PDFs and Images
2491
2561
  let stampedCopyResult = null;
2492
- if (args.save_stamped_copy !== false) {
2493
- stampedCopyResult = await stampLocalFileOptionA(filePath, svgContent, null, clientHash);
2562
+ if (args.save_stamped_copy !== false && svgContent) {
2563
+ try {
2564
+ stampedCopyResult = await stampLocalFileOptionA(filePath, svgContent, null, clientHash);
2565
+ } catch (e) {
2566
+ stampedCopyResult = { status: "skipped", error: e.message };
2567
+ }
2494
2568
  }
2495
2569
 
2496
2570
  // 4. Generate 4-Plate Sovereign Cryptographic Provenance Certificate HTML
2497
2571
  let savedCertificateHtmlPath = null;
2498
2572
  if (args.save_certificate_html !== false) {
2499
- const certHtml = generateProvenanceCertificateHtml({
2500
- fileName: path.basename(filePath),
2501
- fileSize: formatBytes(fileBuffer.length),
2502
- mimeType: inferMimeTypeFromFileName(path.basename(filePath)),
2503
- originalFileHash,
2504
- attestedHash: clientHash,
2505
- signerPublicKey: passkeyCreds ? passkeyCreds.public_key_hex : null,
2506
- anchorMode: data.anchor_mode || anchorMode,
2507
- tIndex,
2508
- vdfTicks: data.vdf_ticks || data.solar_ticks || 0,
2509
- status: data.status || "pending_finality",
2510
- blockHeight: data.settlement?.bitcoin_block_height || null,
2511
- blockTimeUtc: data.settlement?.bitcoin_block_time
2512
- ? new Date(data.settlement.bitcoin_block_time * 1000).toISOString().replace("T", " ").slice(0, 19) + " UTC"
2513
- : null,
2514
- merkleProofCount: Array.isArray(data.settlement?.merkle_proof_path)
2515
- ? data.settlement.merkle_proof_path.length
2516
- : null,
2517
- txid: data.settlement?.bitcoin_txid || null,
2518
- });
2519
- savedCertificateHtmlPath = path.join(
2520
- path.dirname(filePath),
2521
- `reltime-certificate-${path.basename(filePath)}.html`
2522
- );
2523
- fs.writeFileSync(savedCertificateHtmlPath, certHtml, "utf8");
2524
- if (args.open_certificate_in_browser) {
2525
- openSystemBrowser(savedCertificateHtmlPath);
2573
+ try {
2574
+ const certHtml = generateProvenanceCertificateHtml({
2575
+ fileName: path.basename(filePath),
2576
+ fileSize: formatBytes(fileBuffer.length),
2577
+ mimeType: inferMimeTypeFromFileName(path.basename(filePath)),
2578
+ originalFileHash,
2579
+ attestedHash: clientHash,
2580
+ signerPublicKey: passkeyCreds ? passkeyCreds.public_key_hex : null,
2581
+ anchorMode: data.anchor_mode || anchorMode,
2582
+ tIndex,
2583
+ vdfTicks: data.vdf_ticks || data.solar_ticks || 0,
2584
+ status: data.status || "pending_finality",
2585
+ blockHeight: data.settlement?.bitcoin_block_height || null,
2586
+ blockTimeUtc: data.settlement?.bitcoin_block_time
2587
+ ? new Date(data.settlement.bitcoin_block_time * 1000).toISOString().replace("T", " ").slice(0, 19) + " UTC"
2588
+ : null,
2589
+ merkleProofCount: Array.isArray(data.settlement?.merkle_proof_path)
2590
+ ? data.settlement.merkle_proof_path.length
2591
+ : null,
2592
+ txid: data.settlement?.bitcoin_txid || null,
2593
+ });
2594
+ savedCertificateHtmlPath = path.join(
2595
+ path.dirname(filePath),
2596
+ `reltime-certificate-${path.basename(filePath)}.html`
2597
+ );
2598
+ fs.writeFileSync(savedCertificateHtmlPath, certHtml, "utf8");
2599
+ if (args.open_certificate_in_browser) {
2600
+ openSystemBrowser(savedCertificateHtmlPath);
2601
+ }
2602
+ } catch (e) {
2603
+ savedCertificateHtmlPath = null;
2526
2604
  }
2527
2605
  }
2528
2606
 
@@ -2548,6 +2626,203 @@ async function executeTool(name, args = {}) {
2548
2626
  };
2549
2627
  }
2550
2628
 
2629
+ if (name === "reltime_anchor_folder") {
2630
+ if (!key) {
2631
+ return buildPackSelectionPrompt(
2632
+ "Before anchoring a folder of files, a Rel-Time API key is required. Ask the user which pack they want to provision first:"
2633
+ );
2634
+ }
2635
+ const folderPath = resolveLocalFilePath(args.folder_path);
2636
+ if (!fs.existsSync(folderPath) || !fs.statSync(folderPath).isDirectory()) {
2637
+ throw new Error(`Directory not found at path: ${folderPath}`);
2638
+ }
2639
+
2640
+ const recursive = Boolean(args.recursive);
2641
+ const anchorMode = args.anchor_mode || "standard";
2642
+ const artifactMode = args.artifact_mode || "proofs_subfolder";
2643
+ const concurrency = Math.max(1, Math.min(10, Number(args.concurrency) || 5));
2644
+
2645
+ let passkeyCreds = null;
2646
+ if (args.biometric) {
2647
+ passkeyCreds = loadSavedPasskey();
2648
+ if (!passkeyCreds) {
2649
+ passkeyCreds = await launchBrowserPasskeyBridge();
2650
+ }
2651
+ }
2652
+
2653
+ const isReltimeGeneratedFile = (fname) => {
2654
+ const lower = fname.toLowerCase();
2655
+ return (
2656
+ fname.startsWith(".") ||
2657
+ lower.startsWith("reltime-stamp-") ||
2658
+ lower.startsWith("reltime-doomsday-proof-") ||
2659
+ lower.startsWith("reltime-certificate-") ||
2660
+ lower.startsWith("reltime-stamped-") ||
2661
+ lower.startsWith("reltime-audit-report-") ||
2662
+ lower === "reltime-batch-manifest.json"
2663
+ );
2664
+ };
2665
+
2666
+ const targetFiles = [];
2667
+ const walkDir = (dir) => {
2668
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
2669
+ for (const entry of entries) {
2670
+ if (entry.name.startsWith(".") || entry.name === "_reltime_proofs" || entry.name === "node_modules") {
2671
+ continue;
2672
+ }
2673
+ const fullPath = path.join(dir, entry.name);
2674
+ if (entry.isDirectory()) {
2675
+ if (recursive) walkDir(fullPath);
2676
+ } else if (entry.isFile() && !isReltimeGeneratedFile(entry.name)) {
2677
+ targetFiles.push(fullPath);
2678
+ }
2679
+ }
2680
+ };
2681
+ walkDir(folderPath);
2682
+
2683
+ const proofsDir = path.join(folderPath, "_reltime_proofs");
2684
+ if (artifactMode === "proofs_subfolder" && !fs.existsSync(proofsDir)) {
2685
+ fs.mkdirSync(proofsDir, { recursive: true });
2686
+ }
2687
+
2688
+ const manifestPath = path.join(folderPath, "reltime-batch-manifest.json");
2689
+ let existingManifest = { anchored_files: {} };
2690
+ if (fs.existsSync(manifestPath)) {
2691
+ try {
2692
+ existingManifest = JSON.parse(fs.readFileSync(manifestPath, "utf8")) || { anchored_files: {} };
2693
+ if (!existingManifest.anchored_files) existingManifest.anchored_files = {};
2694
+ } catch (e) {
2695
+ existingManifest = { anchored_files: {} };
2696
+ }
2697
+ }
2698
+
2699
+ const results = [];
2700
+ const skipped = [];
2701
+ const errors = [];
2702
+ let outOfCredits = false;
2703
+
2704
+ const toProcess = [];
2705
+ for (const fPath of targetFiles) {
2706
+ const relPath = path.relative(folderPath, fPath);
2707
+ const baseName = path.basename(fPath);
2708
+ const sidecarProof = path.join(path.dirname(fPath), `reltime-doomsday-proof-${baseName}.json`);
2709
+ const subfolderProof = path.join(proofsDir, `reltime-doomsday-proof-${relPath.replace(/[\\/]/g, "__")}.json`);
2710
+ if (existingManifest.anchored_files[relPath] || fs.existsSync(sidecarProof) || fs.existsSync(subfolderProof)) {
2711
+ skipped.push(relPath);
2712
+ } else {
2713
+ toProcess.push({ fPath, relPath, baseName, subfolderProof });
2714
+ }
2715
+ }
2716
+
2717
+ let cursor = 0;
2718
+ const worker = async () => {
2719
+ while (cursor < toProcess.length && !outOfCredits) {
2720
+ const idx = cursor++;
2721
+ const item = toProcess[idx];
2722
+ if (!item) break;
2723
+ try {
2724
+ const buf = fs.readFileSync(item.fPath);
2725
+ const originalFileHash = crypto.createHash("sha256").update(buf).digest("hex");
2726
+ const clientHash =
2727
+ args.biometric && passkeyCreds
2728
+ ? crypto.createHash("sha256").update(`${originalFileHash}${passkeyCreds.public_key_hex}`, "utf8").digest("hex")
2729
+ : originalFileHash;
2730
+
2731
+ const reqBody = {
2732
+ client_hash: clientHash,
2733
+ anchor_mode: anchorMode,
2734
+ };
2735
+ if (args.biometric && passkeyCreds) {
2736
+ reqBody.original_file_hash = originalFileHash;
2737
+ reqBody.passkey_signature = passkeyCreds.passkey_signature;
2738
+ }
2739
+
2740
+ const res = await fetch(`${API_BASE}/anchor`, {
2741
+ method: "POST",
2742
+ headers: {
2743
+ "Content-Type": "application/json",
2744
+ Authorization: `Bearer ${key}`,
2745
+ },
2746
+ body: JSON.stringify(reqBody),
2747
+ });
2748
+
2749
+ if (res.status === 402) {
2750
+ outOfCredits = true;
2751
+ errors.push({ file: item.relPath, error: "Insufficient Hash Credits (HTTP 402)" });
2752
+ break;
2753
+ }
2754
+
2755
+ const data = await res.json();
2756
+ if (!res.ok) {
2757
+ errors.push({ file: item.relPath, error: `HTTP ${res.status}: ${JSON.stringify(data)}` });
2758
+ continue;
2759
+ }
2760
+
2761
+ const tIndex = data.t_index || data.thermodynamic_proof;
2762
+ const lookupHash = (data.anchor_mode || anchorMode) === "temporal" ? tIndex : clientHash;
2763
+ const verifyUrl = `https://rel-time.com/verify?t=${lookupHash}`;
2764
+ const proofRecord = {
2765
+ protocol: "Rel-Time Sovereign Provenance Protocol",
2766
+ file_name: item.baseName,
2767
+ relative_path: item.relPath,
2768
+ identity_mode: args.biometric ? "BIOMETRIC_PASSKEY" : "ANONYMOUS",
2769
+ original_file_sha256_hash: originalFileHash,
2770
+ anchored_client_hash: clientHash,
2771
+ signer_public_key: passkeyCreds ? passkeyCreds.public_key_hex : null,
2772
+ t_index: tIndex,
2773
+ vdf_ticks: data.vdf_ticks || data.solar_ticks,
2774
+ anchor_mode: data.anchor_mode || anchorMode,
2775
+ status: data.status || "pending_finality",
2776
+ verify_url: verifyUrl,
2777
+ };
2778
+
2779
+ if (artifactMode === "proofs_subfolder") {
2780
+ fs.writeFileSync(item.subfolderProof, JSON.stringify(proofRecord, null, 2), "utf8");
2781
+ } else if (artifactMode === "full") {
2782
+ const sidecarPath = path.join(path.dirname(item.fPath), `reltime-doomsday-proof-${item.baseName}.json`);
2783
+ fs.writeFileSync(sidecarPath, JSON.stringify(proofRecord, null, 2), "utf8");
2784
+ }
2785
+
2786
+ existingManifest.anchored_files[item.relPath] = proofRecord;
2787
+ results.push(proofRecord);
2788
+ } catch (err) {
2789
+ errors.push({ file: item.relPath, error: err.message });
2790
+ }
2791
+ }
2792
+ };
2793
+
2794
+ const workers = Array.from({ length: Math.min(concurrency, Math.max(1, toProcess.length)) }, () => worker());
2795
+ await Promise.all(workers);
2796
+
2797
+ const manifestPayload = {
2798
+ protocol: "Rel-Time Sovereign Provenance Protocol — Batch Folder Manifest",
2799
+ folder_path: folderPath,
2800
+ updated_at: new Date().toISOString(),
2801
+ identity_mode: args.biometric ? "BIOMETRIC_PASSKEY" : "ANONYMOUS",
2802
+ signer_public_key: passkeyCreds ? passkeyCreds.public_key_hex : null,
2803
+ total_anchored_in_manifest: Object.keys(existingManifest.anchored_files).length,
2804
+ anchored_files: existingManifest.anchored_files,
2805
+ };
2806
+ fs.writeFileSync(manifestPath, JSON.stringify(manifestPayload, null, 2), "utf8");
2807
+
2808
+ return {
2809
+ status: outOfCredits ? "stopped_insufficient_credits" : "completed",
2810
+ folder_path: folderPath,
2811
+ total_files_found: targetFiles.length,
2812
+ newly_anchored_count: results.length,
2813
+ skipped_already_anchored_count: skipped.length,
2814
+ error_count: errors.length,
2815
+ identity_mode: args.biometric ? "BIOMETRIC_PASSKEY" : "ANONYMOUS",
2816
+ signer_public_key: passkeyCreds ? passkeyCreds.public_key_hex : null,
2817
+ artifact_mode: artifactMode,
2818
+ manifest_path: manifestPath,
2819
+ proofs_subfolder: artifactMode === "proofs_subfolder" ? proofsDir : null,
2820
+ errors: errors.slice(0, 20),
2821
+ next_step:
2822
+ "You can now run `reltime_audit_trail` with `verify_local_path` set to this folder to generate the full interactive HTML Cryptographic Audit Report.",
2823
+ };
2824
+ }
2825
+
2551
2826
  if (name === "reltime_stamp_file") {
2552
2827
  const filePath = resolveLocalFilePath(args.file_path);
2553
2828
  if (!fs.existsSync(filePath)) {
@@ -2813,7 +3088,7 @@ async function executeTool(name, args = {}) {
2813
3088
  };
2814
3089
  }
2815
3090
 
2816
- const maxEntries = Math.min(500, Math.max(1, Number(args.limit) || 100));
3091
+ const maxEntries = Math.min(5000, Math.max(1, Number(args.limit) || 2000));
2817
3092
  const pageSize = Math.min(100, maxEntries);
2818
3093
  const pagesToFetch = Math.ceil(maxEntries / pageSize);
2819
3094
  let rawHistory = [];
@@ -2959,7 +3234,10 @@ async function executeTool(name, args = {}) {
2959
3234
  item.startsWith("reltime-stamp-") ||
2960
3235
  item.startsWith("reltime-doomsday-proof-") ||
2961
3236
  item.startsWith("reltime-proof-") ||
2962
- item.startsWith("reltime-audit-report-")
3237
+ item.startsWith("reltime-certificate-") ||
3238
+ item.startsWith("reltime-audit-report-") ||
3239
+ item === "reltime-batch-manifest.json" ||
3240
+ item === "_reltime_proofs"
2963
3241
  ) {
2964
3242
  continue;
2965
3243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rel-time/mcp-server",
3
- "version": "1.2.11",
3
+ "version": "1.2.12",
4
4
  "mcpName": "io.github.relsun369-dev/rel-time",
5
5
  "description": "Official Model Context Protocol (MCP) server for Rel-Time (rel-time.com) — Zero-Knowledge Bitcoin & VDF Provenance, Local File Hashing, and Sun-Stamp Generation for Claude, Cursor, Windsurf, and Antigravity.",
6
6
  "main": "index.js",
package/server.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.relsun369-dev/rel-time",
4
4
  "title": "Rel-Time Protocol (Bitcoin & VDF Provenance)",
5
5
  "description": "Zero-knowledge Bitcoin Mainnet & VDF timestamping, Passkey signing, Sun-Stamps, and tamper audits.",
@@ -8,13 +8,13 @@
8
8
  "url": "https://github.com/relsun369-dev/reltime-mcp",
9
9
  "source": "github"
10
10
  },
11
- "version": "1.2.11",
11
+ "version": "1.2.12",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "registryBaseUrl": "https://registry.npmjs.org",
16
16
  "identifier": "@rel-time/mcp-server",
17
- "version": "1.2.11",
17
+ "version": "1.2.12",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  }