indelible-mcp 5.5.0 → 5.5.1

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/package.json +1 -1
  2. package/src/index.js +116 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indelible-mcp",
3
- "version": "5.5.0",
3
+ "version": "5.5.1",
4
4
  "description": "Blockchain-backed memory and code storage for Claude Code. Save AI conversations and source code permanently on BSV.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -7924,6 +7924,97 @@ var init_agent_recipes = __esm({
7924
7924
  }
7925
7925
  });
7926
7926
 
7927
+ // mcp-server/lib/agent-register.js
7928
+ var agent_register_exports = {};
7929
+ __export(agent_register_exports, {
7930
+ mintSession: () => mintSession,
7931
+ publicAgentRecord: () => publicAgentRecord,
7932
+ registerAgentWithServer: () => registerAgentWithServer
7933
+ });
7934
+ async function mintSession(apiUrl, address) {
7935
+ const wif = await getWif();
7936
+ if (!wif) return { ok: false, reason: "wallet_locked", detail: "no key available to prove ownership" };
7937
+ try {
7938
+ const { PrivateKey: PrivateKey16 } = await import("@bsv/sdk");
7939
+ const priv = PrivateKey16.fromWif(wif);
7940
+ const own = priv.toPublicKey().toAddress();
7941
+ if (address && address !== own) {
7942
+ return { ok: false, reason: "address_key_mismatch", detail: `this box's key proves ${own}, not ${address}` };
7943
+ }
7944
+ const ch = await fetch(`${apiUrl}/api/auth/wif/challenge?address=${own}`, { signal: AbortSignal.timeout(15e3) }).then((r2) => r2.json());
7945
+ if (!ch?.nonce) return { ok: false, reason: "no_challenge", detail: JSON.stringify(ch).slice(0, 160) };
7946
+ const sig = Buffer.from(priv.sign(Array.from(Buffer.from(`indelible-auth:${ch.nonce}`, "utf8"))).toDER()).toString("hex");
7947
+ const r = await fetch(`${apiUrl}/api/auth/wif`, {
7948
+ method: "POST",
7949
+ headers: { "Content-Type": "application/json" },
7950
+ body: JSON.stringify({ address: own, signature: sig, nonce: ch.nonce, publicKey: priv.toPublicKey().toString() }),
7951
+ signal: AbortSignal.timeout(15e3)
7952
+ });
7953
+ const j = await r.json().catch(() => ({}));
7954
+ if (!j?.token) return { ok: false, reason: `login_${r.status}`, detail: JSON.stringify(j).slice(0, 160) };
7955
+ return { ok: true, token: j.token };
7956
+ } catch (e) {
7957
+ return { ok: false, reason: "network", detail: String(e.message || e).slice(0, 160) };
7958
+ }
7959
+ }
7960
+ function publicAgentRecord(born, extra = {}) {
7961
+ const rec = {
7962
+ name: String(born?.name || "").toLowerCase(),
7963
+ domain: born?.domain,
7964
+ address: born?.address,
7965
+ identity_key_hex: born?.identity_key_hex || born?.identityKey
7966
+ };
7967
+ if (extra.role || born?.role) rec.role = String(extra.role || born.role).slice(0, 200);
7968
+ if (extra.display_name || born?.display_name) rec.display_name = String(extra.display_name || born.display_name).slice(0, 64);
7969
+ return rec;
7970
+ }
7971
+ async function registerAgentWithServer(born, { apiUrl, apiKey, token, anchorAddress, tenantId, masterPubkey, role, displayName } = {}) {
7972
+ let cfg2 = {};
7973
+ try {
7974
+ cfg2 = await loadConfig();
7975
+ } catch {
7976
+ }
7977
+ const base2 = (process.env.INDELIBLE_API_URL || apiUrl || cfg2.api_url || "").replace(/\/$/, "");
7978
+ const anchor = anchorAddress || cfg2.address;
7979
+ if (!base2) return { ok: false, reason: "no_api_url", detail: "no server configured for this box" };
7980
+ if (!anchor) return { ok: false, reason: "no_address", detail: "no wallet address on this box" };
7981
+ let auth = token;
7982
+ if (!auth) {
7983
+ const s = await mintSession(base2, anchor);
7984
+ if (!s.ok) return { ok: false, reason: `session_${s.reason}`, detail: s.detail };
7985
+ auth = s.token;
7986
+ }
7987
+ const agent = publicAgentRecord(born, { role, display_name: displayName });
7988
+ if (!agent.name || !agent.domain || !agent.identity_key_hex || !agent.address) {
7989
+ return { ok: false, reason: "incomplete_record", detail: "birth result lacked name/domain/identity key/address" };
7990
+ }
7991
+ const body = { anchor_address: anchor, tenant_id: tenantId, master_pubkey: masterPubkey, agent };
7992
+ try {
7993
+ const r = await fetch(`${base2}/api/sanctuary/agent`, {
7994
+ method: "POST",
7995
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${auth}` },
7996
+ body: JSON.stringify(body),
7997
+ signal: AbortSignal.timeout(15e3)
7998
+ });
7999
+ if (r.ok) return { ok: true, status: r.status };
8000
+ const detail = await r.text().catch(() => "");
8001
+ let reason = `http_${r.status}`;
8002
+ try {
8003
+ const j = JSON.parse(detail);
8004
+ reason = j.error || reason;
8005
+ } catch {
8006
+ }
8007
+ return { ok: false, status: r.status, reason, detail: detail.slice(0, 300) };
8008
+ } catch (e) {
8009
+ return { ok: false, reason: "network", detail: String(e.message || e).slice(0, 200) };
8010
+ }
8011
+ }
8012
+ var init_agent_register = __esm({
8013
+ "mcp-server/lib/agent-register.js"() {
8014
+ init_config_customer();
8015
+ }
8016
+ });
8017
+
7927
8018
  // cli-sandbox/src/index.js
7928
8019
  init_config_customer();
7929
8020
  init_api_client();
@@ -11888,6 +11979,10 @@ async function provisionCustomAgentForCustomer({ address, wallet, scope = "", ag
11888
11979
  const persona = await writePersona(scope, canonical, agent);
11889
11980
  return {
11890
11981
  tenant_id: root.tenant_id,
11982
+ // PUBLIC master pubkey — the server's MASTER_MISMATCH gate needs it to confirm
11983
+ // this agent came from the wallet that sealed the crew (added 2026-08-09 so the
11984
+ // box can register what it births; the master PRIVATE key never leaves).
11985
+ master_pubkey: root.master_pubkey,
11891
11986
  name: canonical,
11892
11987
  domain: agent.domain,
11893
11988
  identity_key_hex: identity.identity_key_hex,
@@ -13575,7 +13670,7 @@ Commands:
13575
13670
  }
13576
13671
  function printHelp() {
13577
13672
  console.log(`
13578
- Indelible MCP \u2014 Blockchain memory for Claude Code (v5.5.0)
13673
+ Indelible MCP \u2014 Blockchain memory for Claude Code (v5.5.1)
13579
13674
 
13580
13675
  Setup:
13581
13676
  indelible-mcp setup --wif=KEY --pin=PIN Import and encrypt your private key
@@ -13895,7 +13990,7 @@ function readStdin() {
13895
13990
  }
13896
13991
  var SERVER_INFO = {
13897
13992
  name: "indelible",
13898
- version: "5.5.0",
13993
+ version: "5.5.1",
13899
13994
  description: "Blockchain-backed memory and code storage for Claude Code"
13900
13995
  };
13901
13996
  var TOOLS = [
@@ -14476,7 +14571,25 @@ async function handleMcpRequest(request) {
14476
14571
  scope,
14477
14572
  agent: agentArgs
14478
14573
  });
14479
- result = born;
14574
+ let registration = null;
14575
+ try {
14576
+ const { registerAgentWithServer: registerAgentWithServer2 } = await Promise.resolve().then(() => (init_agent_register(), agent_register_exports));
14577
+ registration = await registerAgentWithServer2(born, {
14578
+ anchorAddress: cfg2.address,
14579
+ tenantId: born.tenant_id,
14580
+ masterPubkey: born.master_pubkey
14581
+ });
14582
+ } catch (e) {
14583
+ registration = { ok: false, reason: "register_threw", detail: String(e.message || e).slice(0, 200) };
14584
+ }
14585
+ result = {
14586
+ ...born,
14587
+ registered_with_server: registration?.ok === true,
14588
+ ...registration?.ok ? {} : {
14589
+ registration_note: `born on this box, but NOT registered with your Sanctuary (${registration?.reason || "unknown"}) \u2014 it can run locally; the Counter will not list it until registration succeeds`,
14590
+ registration_detail: registration?.detail || null
14591
+ }
14592
+ };
14480
14593
  break;
14481
14594
  }
14482
14595
  case "run_custom_agent": {