@rel-time/mcp-server 1.2.0 → 1.2.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.
Files changed (2) hide show
  1. package/index.js +91 -10
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -20,18 +20,63 @@ const { exec } = require("child_process");
20
20
  const { PDFDocument } = require("pdf-lib");
21
21
  const sharp = require("sharp");
22
22
 
23
- const API_BASE = (process.env.RELTIME_API_URL || "https://api.rel-time.com/v1").replace(/\/+$/, "");
23
+ const API_BASE = (process.env.RELTIME_API_URL || "https://rel-time.com/api/v1").replace(/\/+$/, "");
24
24
  const WEB_BASE = (process.env.RELTIME_WEB_URL || "https://rel-time.com").replace(/\/+$/, "");
25
25
  let CURRENT_API_KEY = process.env.RELTIME_API_KEY || "";
26
26
 
27
27
  const PASSKEY_CONFIG_DIR = path.join(os.homedir(), ".reltime");
28
28
  const PASSKEY_CONFIG_PATH = path.join(PASSKEY_CONFIG_DIR, "passkey.json");
29
+ const API_KEY_CONFIG_PATH = path.join(PASSKEY_CONFIG_DIR, "api_key.json");
30
+ let LAST_INVOICE_PACK = null;
29
31
 
30
32
  const SERVER_INFO = {
31
33
  name: "rel-time-mcp-server",
32
- version: "1.2.0",
34
+ version: "1.2.2",
33
35
  };
34
36
 
37
+ /**
38
+ * Loads saved API key from ~/.reltime/api_key.json if not provided via env/args.
39
+ */
40
+ function loadSavedApiKey() {
41
+ if (CURRENT_API_KEY && CURRENT_API_KEY.trim()) {
42
+ return CURRENT_API_KEY.trim();
43
+ }
44
+ if (process.env.RELTIME_API_KEY && process.env.RELTIME_API_KEY.trim()) {
45
+ return process.env.RELTIME_API_KEY.trim();
46
+ }
47
+ try {
48
+ if (fs.existsSync(API_KEY_CONFIG_PATH)) {
49
+ const parsed = JSON.parse(fs.readFileSync(API_KEY_CONFIG_PATH, "utf8"));
50
+ if (parsed.api_key && parsed.api_key.trim()) {
51
+ CURRENT_API_KEY = parsed.api_key.trim();
52
+ return CURRENT_API_KEY;
53
+ }
54
+ }
55
+ } catch (e) {
56
+ // Ignore corrupted file
57
+ }
58
+ return "";
59
+ }
60
+
61
+ /**
62
+ * Saves provisioned API key to ~/.reltime/api_key.json with 0600 permissions.
63
+ */
64
+ function saveApiKeyConfig(apiKey, pack) {
65
+ if (!fs.existsSync(PASSKEY_CONFIG_DIR)) {
66
+ fs.mkdirSync(PASSKEY_CONFIG_DIR, { recursive: true, mode: 0o700 });
67
+ }
68
+ const payload = {
69
+ api_key: apiKey.trim(),
70
+ pack: pack || "standard",
71
+ saved_at: new Date().toISOString(),
72
+ };
73
+ fs.writeFileSync(API_KEY_CONFIG_PATH, JSON.stringify(payload, null, 2), {
74
+ encoding: "utf8",
75
+ mode: 0o600,
76
+ });
77
+ return payload;
78
+ }
79
+
35
80
  /**
36
81
  * Loads linked Passkey credentials from env vars or ~/.reltime/passkey.json.
37
82
  */
@@ -397,7 +442,7 @@ const TOOLS = [
397
442
  {
398
443
  name: "reltime_provision_agent_key",
399
444
  description:
400
- "Self-onboarding & Top-Up for Autonomous AI Agents: Requests a Bitcoin Lightning invoice (`POST /v1/agent/invoice`, $5 for 50 Hash Credits Launch Pack or $50 for 500 Hash Credits) or claims a paid invoice (`POST /v1/agent/claim`) to either provision a brand-new Tier 4 Autonomous Agent API key OR reload an existing key without changing the key.",
445
+ "Self-onboarding & Top-Up for Autonomous AI Agents via Bitcoin Lightning (`POST /v1/agent/invoice` & `POST /v1/agent/claim`). IMPORTANT: Before calling `create_invoice` for a new key, ALWAYS ask the user which pack they want first:\n1. **Agent Launch Pack (`pack: 'launch'`, $5 / 50 Hashes):** Priority 10-Minute Bitcoin Queue · Standard Mode only (Data Integrity + Biometric or Anonymous) · Includes Sun-Stamp, 1-Click Stamped Copy (.PDF/.PNG), and .JSON Doomsday Proof.\n2. **Autonomous Agents (`pack: 'standard'`, $50 / 500 Hashes):** Dynamic 6-Hour Batch Queue · Supports both Temporal Mode (`T_index` sub-second sequencing) and Standard Mode · Reloadable anytime (+500 credits / $50) with zero key rotation.",
401
446
  inputSchema: {
402
447
  type: "object",
403
448
  properties: {
@@ -411,7 +456,7 @@ const TOOLS = [
411
456
  type: "string",
412
457
  enum: ["launch", "standard"],
413
458
  description:
414
- "Optional: 'launch' ($5 for 50 Hash Credits) or 'standard' (default, $50 for 500 Hash Credits).",
459
+ "Which key pack the user selected: 'launch' (Agent Launch Pack — $5 for 50 Hash Credits, 10-Min Queue, Standard Mode only) or 'standard' (Autonomous Agents — $50 for 500 Hash Credits, 6-Hr Queue, Temporal & Standard Modes, reloadable). If omitted on 'create_invoice', the tool returns the two options so you can ask the user which pack they prefer.",
415
460
  },
416
461
  invoice_id: {
417
462
  type: "string",
@@ -434,7 +479,7 @@ const TOOLS = [
434
479
  ];
435
480
 
436
481
  async function executeTool(name, args = {}) {
437
- const key = (args.api_key || CURRENT_API_KEY || "").trim();
482
+ const key = (args.api_key || loadSavedApiKey() || "").trim();
438
483
 
439
484
  if (name === "reltime_link_passkey") {
440
485
  if (args.public_key_hex && args.passkey_signature) {
@@ -467,7 +512,7 @@ async function executeTool(name, args = {}) {
467
512
  }
468
513
  if (!key) {
469
514
  throw new Error(
470
- "Missing RELTIME_API_KEY. Set RELTIME_API_KEY in your MCP config, pass `api_key`, or call `reltime_provision_agent_key` to get an Autonomous Agent key."
515
+ "Missing RELTIME_API_KEY. Please ask the user which API key pack they would like to provision first before calling `reltime_provision_agent_key`:\n1. **Agent Launch Pack (`pack: \"launch\"`, $5 / 50 Hashes):** Priority 10-Min Bitcoin Queue · Standard Mode only (Data Integrity + Biometric or Anonymous)\n2. **Autonomous Agents (`pack: \"standard\"`, $50 / 500 Hashes):** Dynamic 6-Hr Batch Queue · Temporal Mode (T_index sequencing) + Standard Mode · Reloadable anytime"
471
516
  );
472
517
  }
473
518
 
@@ -614,7 +659,9 @@ async function executeTool(name, args = {}) {
614
659
 
615
660
  if (name === "reltime_anchor_hash") {
616
661
  if (!key) {
617
- throw new Error("Missing RELTIME_API_KEY. Set RELTIME_API_KEY in your MCP config or pass `api_key`.");
662
+ throw new Error(
663
+ "Missing RELTIME_API_KEY. Please ask the user which API key pack they would like to provision first before calling `reltime_provision_agent_key`: 1) Agent Launch Pack (`pack: \"launch\"`, $5 / 50 Hashes · 10-Min Queue · Standard Mode only) or 2) Autonomous Agents (`pack: \"standard\"`, $50 / 500 Hashes · 6-Hr Queue · Temporal & Standard Modes)."
664
+ );
618
665
  }
619
666
  const clientHash = (args.client_hash || "").trim().toLowerCase();
620
667
  if (!/^[0-9a-f]{64}$/.test(clientHash)) {
@@ -713,22 +760,54 @@ async function executeTool(name, args = {}) {
713
760
 
714
761
  if (name === "reltime_provision_agent_key") {
715
762
  if (args.action === "create_invoice") {
763
+ if (args.pack !== "launch" && args.pack !== "standard") {
764
+ return {
765
+ status: "pack_selection_required",
766
+ message:
767
+ "Please ask the user which Rel-Time Agent API Key pack they would like to provision before generating the Lightning invoice:",
768
+ available_packs: [
769
+ {
770
+ pack: "launch",
771
+ name: "Agent Launch Pack",
772
+ price_usd: "$5.00",
773
+ credits: 50,
774
+ settlement_queue: "Priority 10-Minute Bitcoin Queue",
775
+ hashing_modes: "Standard Mode only (Data Integrity + Biometric or Anonymous)",
776
+ outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + .JSON Doomsday Proof",
777
+ },
778
+ {
779
+ pack: "standard",
780
+ name: "Autonomous Agents",
781
+ price_usd: "$50.00",
782
+ credits: 500,
783
+ settlement_queue: "Dynamic 6-Hour Batch Queue",
784
+ hashing_modes: "Temporal Mode (T_index sub-second VDF sequencing) + Standard Mode (Biometric or Anonymous)",
785
+ outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + .JSON Doomsday Proof + Reloadable anytime (+500 credits / $50)",
786
+ },
787
+ ],
788
+ next_step:
789
+ "Once the user chooses, call `reltime_provision_agent_key` with `action: 'create_invoice'` and `pack: 'launch'` or `pack: 'standard'`.",
790
+ };
791
+ }
792
+
793
+ LAST_INVOICE_PACK = args.pack;
716
794
  const res = await fetch(`${API_BASE}/agent/invoice`, {
717
795
  method: "POST",
718
796
  headers: { "Content-Type": "application/json" },
719
797
  body: JSON.stringify({
720
798
  accept_terms: true,
721
- pack: args.pack === "launch" ? "launch" : "standard",
799
+ pack: args.pack,
722
800
  }),
723
801
  });
724
802
  return await res.json();
725
803
  } else if (args.action === "claim_invoice") {
726
804
  if (!args.invoice_id) throw new Error("invoice_id is required when action is 'claim_invoice'.");
805
+ const resolvedPack = args.pack || LAST_INVOICE_PACK || undefined;
727
806
  const claimPayload = {
728
807
  invoice_id: args.invoice_id,
729
- pack: args.pack === "launch" ? "launch" : undefined,
808
+ pack: resolvedPack === "launch" ? "launch" : undefined,
730
809
  };
731
- const targetReloadKey = args.api_key || (args.reload_existing ? CURRENT_API_KEY : "");
810
+ const targetReloadKey = args.api_key || (args.reload_existing ? loadSavedApiKey() : "");
732
811
  if (targetReloadKey && targetReloadKey.trim()) {
733
812
  claimPayload.api_key = targetReloadKey.trim();
734
813
  }
@@ -740,6 +819,8 @@ async function executeTool(name, args = {}) {
740
819
  const data = await res.json();
741
820
  if (data.api_key) {
742
821
  CURRENT_API_KEY = data.api_key;
822
+ saveApiKeyConfig(data.api_key, resolvedPack || "standard");
823
+ data.saved_to_config = API_KEY_CONFIG_PATH;
743
824
  }
744
825
  return data;
745
826
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rel-time/mcp-server",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "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.",
5
5
  "main": "index.js",
6
6
  "bin": {