@toon-protocol/client-mcp 0.31.1 → 0.31.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/dist/index.d.ts CHANGED
@@ -53,6 +53,13 @@ interface StatusResponse {
53
53
  buffered: number;
54
54
  /** Active subscription ids. */
55
55
  subscriptions: string[];
56
+ /**
57
+ * Error from the daemon-managed read proxy, if any. Set only in the
58
+ * btp-direct + relay-`.anyone` case where the daemon starts its own `anon`
59
+ * proxy for reads; a failure here means hidden-service reads are down while
60
+ * direct paid writes are unaffected.
61
+ */
62
+ proxyError?: string;
56
63
  };
57
64
  /** Per-chain settlement status when a named `network` tier is configured. */
58
65
  network?: ChainStatus[];
@@ -406,6 +413,15 @@ interface DaemonConfigFile {
406
413
  mnemonic?: string;
407
414
  mnemonicAccountIndex?: number;
408
415
  keystorePath?: string;
416
+ /**
417
+ * Set when the daemon auto-generated the keystore (#251 first-run onboarding).
418
+ * Such a keystore is encrypted with a default password so the identity reloads
419
+ * across restarts without `TOON_CLIENT_KEYSTORE_PASSWORD`. A user-imported
420
+ * keystore leaves this unset and still requires the env password.
421
+ */
422
+ keystoreAutoPassword?: boolean;
423
+ /** Human-facing onboarding notes written by first-run scaffolding (ignored at runtime). */
424
+ _help?: Record<string, string>;
409
425
  /** BTP WebSocket URL of the apex/connector. */
410
426
  btpUrl?: string;
411
427
  /** Transport: `direct` or a `socks5h://` proxy for `.anyone` hosts. */
@@ -462,6 +478,15 @@ interface ResolvedDaemonConfig {
462
478
  httpPort: number;
463
479
  relayUrl: string;
464
480
  socksProxy?: string;
481
+ /**
482
+ * When true the daemon must start its OWN managed `anon` proxy for free reads
483
+ * — the btp-direct + relay-`.anyone` case the ToonClient does not cover (it
484
+ * only auto-starts a proxy for a `.anyone` btpUrl). `readProxySocksPort` is the
485
+ * loopback port to bind; `socksProxy` already points the relay at it.
486
+ */
487
+ manageReadProxy: boolean;
488
+ /** Loopback SOCKS port for the daemon-managed read proxy (when `manageReadProxy`). */
489
+ readProxySocksPort?: number;
465
490
  destination: string;
466
491
  feePerEvent: bigint;
467
492
  apex?: ApexNegotiationConfig;
@@ -475,6 +500,14 @@ interface ResolvedDaemonConfig {
475
500
  toonClientConfig: ToonClientConfig;
476
501
  network?: string;
477
502
  }
503
+ /**
504
+ * Password used to encrypt an auto-generated keystore (#251 first-run
505
+ * onboarding) when `TOON_CLIENT_KEYSTORE_PASSWORD` is unset. At-rest
506
+ * obfuscation only — its purpose is letting the daemon reload the identity
507
+ * across restarts with no env var. Users wanting a real password re-import the
508
+ * keystore and set the env var.
509
+ */
510
+ declare const DEFAULT_KEYSTORE_PASSWORD = "toon-client-default";
478
511
  /** Default config directory: `~/.toon-client`. Overridable via env. */
479
512
  declare function configDir(): string;
480
513
  /** Default config file path. */
@@ -549,18 +582,33 @@ interface ToonClientLike {
549
582
  message?: string;
550
583
  }>;
551
584
  }
585
+ /** A started managed proxy: just the teardown handle the runner needs. */
586
+ interface ManagedProxyHandle {
587
+ stop(): Promise<void>;
588
+ }
589
+ /** Starts a managed `anon` read proxy on a loopback SOCKS port. */
590
+ type StartReadProxy = (opts: {
591
+ socksPort: number;
592
+ log?: (msg: string) => void;
593
+ }) => Promise<ManagedProxyHandle>;
552
594
  interface ClientRunnerDeps {
553
595
  config: ResolvedDaemonConfig;
554
596
  /** Factory producing the (real or fake) ToonClient. */
555
597
  createClient: () => ToonClientLike;
556
598
  /** Factory producing the relay subscription (defaults to the real one). */
557
599
  createRelay?: () => RelaySubscription;
600
+ /**
601
+ * Starts the daemon-managed read proxy (defaults to the real
602
+ * `startManagedAnonProxy`). Injected so tests avoid the anon download/spawn.
603
+ */
604
+ startReadProxy?: StartReadProxy;
558
605
  logger?: (msg: string) => void;
559
606
  }
560
607
  declare class ClientRunner {
561
608
  private readonly config;
562
609
  private readonly client;
563
610
  private readonly relay;
611
+ private readonly startReadProxy;
564
612
  private readonly log;
565
613
  private readonly startedAt;
566
614
  private bootstrapping;
@@ -568,6 +616,10 @@ declare class ClientRunner {
568
616
  private lastError;
569
617
  /** Channel opened against the default apex destination. */
570
618
  private apexChannelId;
619
+ /** Teardown for a daemon-managed read proxy (btp-direct + relay-`.anyone`). */
620
+ private stopReadProxy;
621
+ /** Error from the read proxy (kept separate from the paid-path `lastError`). */
622
+ private readProxyError;
571
623
  private stopped;
572
624
  constructor(deps: ClientRunnerDeps);
573
625
  /**
@@ -576,6 +628,8 @@ declare class ClientRunner {
576
628
  * returned promise of the underlying work.
577
629
  */
578
630
  start(): void;
631
+ /** Start the daemon-managed `anon` read proxy (best-effort; logs on failure). */
632
+ private bringUpReadProxy;
579
633
  /** The background bootstrap routine (exposed for awaiting in tests). */
580
634
  bootstrap(): Promise<void>;
581
635
  /**
@@ -650,6 +704,49 @@ declare class PublishRejectedError extends Error {
650
704
  constructor(message: string);
651
705
  }
652
706
 
707
+ /**
708
+ * First-run onboarding for `toon-clientd`.
709
+ *
710
+ * A brand-new user (`npx`/plugin install) has no identity and no config file.
711
+ * Before the daemon resolves its config it calls {@link scaffoldFirstRun},
712
+ * which makes a fresh install start with zero manual setup:
713
+ *
714
+ * 1. **Identity** — if no mnemonic source is configured (no
715
+ * `TOON_CLIENT_MNEMONIC`, no `keystorePath`, no `mnemonic`), generate a
716
+ * fresh BIP-39 mnemonic, encrypt it to `~/.toon-client/keystore.json`, and
717
+ * record `keystorePath` (+ `keystoreAutoPassword`) in `config.json`. The
718
+ * keystore is encrypted with `TOON_CLIENT_KEYSTORE_PASSWORD` when set, else
719
+ * a default password so the identity survives restarts with no env var.
720
+ * The mnemonic + derived addresses are printed ONCE for backup.
721
+ * 2. **Transport scaffolding** — ensure `config.json` carries the transport
722
+ * knobs (`btpUrl`/`relayUrl`/`managedAnonProxy`) plus a `_help` block
723
+ * documenting direct-vs-`.anyone` selection, so the user can see what to
724
+ * point at.
725
+ *
726
+ * This is all idempotent: on later runs an identity already exists, so nothing
727
+ * is regenerated and the config is left untouched.
728
+ */
729
+
730
+ /** Default keystore path: `~/.toon-client/keystore.json`. */
731
+ declare function defaultKeystorePath(): string;
732
+ /**
733
+ * True when SOME mnemonic source is already configured: the env var, a keystore
734
+ * path, or an inline mnemonic. When false the daemon would otherwise hard-fail
735
+ * with "No mnemonic configured".
736
+ */
737
+ declare function hasConfiguredIdentity(file: DaemonConfigFile): boolean;
738
+ interface ScaffoldOptions {
739
+ /** Config file path (defaults to `TOON_CLIENT_CONFIG` / `~/.toon-client/config.json`). */
740
+ configPath?: string;
741
+ /** Log sink (defaults to stderr, since stdout may carry MCP/JSON). */
742
+ log?: (msg: string) => void;
743
+ }
744
+ /**
745
+ * Generate + persist an identity and/or scaffold transport config on first run.
746
+ * Safe to call on every startup — it only acts when something is missing.
747
+ */
748
+ declare function scaffoldFirstRun(opts?: ScaffoldOptions): Promise<void>;
749
+
653
750
  /**
654
751
  * Fastify route registration for the `toon-clientd` control plane. Each route
655
752
  * is a thin adapter: parse/validate the request, call the `ClientRunner`, map
@@ -725,4 +822,4 @@ declare const TOOL_DEFINITIONS: ToolDefinition[];
725
822
  */
726
823
  declare function dispatchTool(client: ControlClient, name: string, args: Record<string, unknown>): Promise<ToolResult>;
727
824
 
728
- export { type ApexNegotiationConfig, type ChainStatus, type ChannelInfo, type ChannelsResponse, ClientRunner, type ClientRunnerDeps, ControlApiError, ControlClient, type ControlClientOptions, type DaemonConfigFile, DaemonUnreachableError, type DrainResult, type ErrorResponse, type EventsQuery, type EventsResponse, type MinimalWebSocket, type NostrFilter, NotReadyError, type OpenChannelRequest, PublishRejectedError, type PublishRequest, type PublishResponse, RelaySubscription, type RelaySubscriptionOptions, type ResolvedDaemonConfig, type SettlementChain, type StatusResponse, type SubscribeRequest, type SubscribeResponse, type SwapClaim, type SwapRequest, type SwapResponse, TOOL_DEFINITIONS, type ToolDefinition, type ToolResult, type ToonClientLike, type WebSocketFactory, acquireLock, configDir, defaultConfigPath, dispatchTool, isDaemonRunning, isProcessAlive, readConfigFile, readPid, registerRoutes, releaseLock, resolveConfig, resolveMnemonic, spawnDaemonDetached, waitForReady };
825
+ export { type ApexNegotiationConfig, type ChainStatus, type ChannelInfo, type ChannelsResponse, ClientRunner, type ClientRunnerDeps, ControlApiError, ControlClient, type ControlClientOptions, DEFAULT_KEYSTORE_PASSWORD, type DaemonConfigFile, DaemonUnreachableError, type DrainResult, type ErrorResponse, type EventsQuery, type EventsResponse, type MinimalWebSocket, type NostrFilter, NotReadyError, type OpenChannelRequest, PublishRejectedError, type PublishRequest, type PublishResponse, RelaySubscription, type RelaySubscriptionOptions, type ResolvedDaemonConfig, type SettlementChain, type StatusResponse, type SubscribeRequest, type SubscribeResponse, type SwapClaim, type SwapRequest, type SwapResponse, TOOL_DEFINITIONS, type ToolDefinition, type ToolResult, type ToonClientLike, type WebSocketFactory, acquireLock, configDir, defaultConfigPath, defaultKeystorePath, dispatchTool, hasConfiguredIdentity, isDaemonRunning, isProcessAlive, readConfigFile, readPid, registerRoutes, releaseLock, resolveConfig, resolveMnemonic, scaffoldFirstRun, spawnDaemonDetached, waitForReady };
package/dist/index.js CHANGED
@@ -4,15 +4,19 @@ import {
4
4
  NotReadyError,
5
5
  PublishRejectedError,
6
6
  RelaySubscription,
7
- registerRoutes
8
- } from "./chunk-SECSBCDA.js";
7
+ defaultKeystorePath,
8
+ hasConfiguredIdentity,
9
+ registerRoutes,
10
+ scaffoldFirstRun
11
+ } from "./chunk-PRFPAEGG.js";
9
12
  import {
10
13
  TOOL_DEFINITIONS,
11
14
  dispatchTool
12
- } from "./chunk-JOGMX4IT.js";
15
+ } from "./chunk-I5L5CB4N.js";
13
16
  import {
14
17
  ControlApiError,
15
18
  ControlClient,
19
+ DEFAULT_KEYSTORE_PASSWORD,
16
20
  DaemonUnreachableError,
17
21
  acquireLock,
18
22
  configDir,
@@ -26,7 +30,7 @@ import {
26
30
  resolveMnemonic,
27
31
  spawnDaemonDetached,
28
32
  waitForReady
29
- } from "./chunk-MI2IWKHX.js";
33
+ } from "./chunk-ARFPM2PT.js";
30
34
  import "./chunk-32QD72IL.js";
31
35
  import "./chunk-QTDCFXPF.js";
32
36
  import "./chunk-LR7W2ISE.js";
@@ -37,6 +41,7 @@ export {
37
41
  ClientRunner,
38
42
  ControlApiError,
39
43
  ControlClient,
44
+ DEFAULT_KEYSTORE_PASSWORD,
40
45
  DaemonUnreachableError,
41
46
  NotReadyError,
42
47
  PublishRejectedError,
@@ -45,7 +50,9 @@ export {
45
50
  acquireLock,
46
51
  configDir,
47
52
  defaultConfigPath,
53
+ defaultKeystorePath,
48
54
  dispatchTool,
55
+ hasConfiguredIdentity,
49
56
  isDaemonRunning,
50
57
  isProcessAlive,
51
58
  readConfigFile,
@@ -54,6 +61,7 @@ export {
54
61
  releaseLock,
55
62
  resolveConfig,
56
63
  resolveMnemonic,
64
+ scaffoldFirstRun,
57
65
  spawnDaemonDetached,
58
66
  waitForReady
59
67
  };
package/dist/mcp.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire as __cr } from 'module'; const require = __cr(import.meta
3
3
  import {
4
4
  TOOL_DEFINITIONS,
5
5
  dispatchTool
6
- } from "./chunk-JOGMX4IT.js";
6
+ } from "./chunk-I5L5CB4N.js";
7
7
  import {
8
8
  ControlClient,
9
9
  defaultConfigPath,
@@ -11,7 +11,7 @@ import {
11
11
  readConfigFile,
12
12
  spawnDaemonDetached,
13
13
  waitForReady
14
- } from "./chunk-MI2IWKHX.js";
14
+ } from "./chunk-ARFPM2PT.js";
15
15
  import "./chunk-32QD72IL.js";
16
16
  import "./chunk-QTDCFXPF.js";
17
17
  import "./chunk-LR7W2ISE.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toon-protocol/client-mcp",
3
- "version": "0.31.1",
3
+ "version": "0.31.2",
4
4
  "description": "Always-on local daemon + MCP server letting a Claude agent (Desktop or Code) act as a TOON Protocol client: pay-to-write publishing, free reads, channel/balance management, and mill swaps.",
5
5
  "license": "MIT",
6
6
  "author": "Jonathan Green",
@@ -45,8 +45,8 @@
45
45
  "typescript": "^5.3.0",
46
46
  "vitest": "^1.0.0",
47
47
  "@toon-protocol/client": "0.9.1",
48
- "@toon-protocol/sdk": "0.5.0",
49
- "@toon-protocol/core": "1.4.1"
48
+ "@toon-protocol/core": "1.4.1",
49
+ "@toon-protocol/sdk": "0.5.0"
50
50
  },
51
51
  "engines": {
52
52
  "node": ">=20"