@cmdoss/suipay-mcp 0.2.2-dev.4 → 0.2.2-dev.5

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
@@ -15,7 +15,9 @@ claude mcp add --scope user suipay -- npx -y @cmdoss/suipay-mcp@0.2.2
15
15
  ```
16
16
 
17
17
  No wallet secret belongs in this command or MCP config. There is no
18
- Sign-In With Sui (SIWS) step.
18
+ Sign-In With Sui (SIWS) step. To reuse an existing delegate seed locally,
19
+ set `SUIPAY_MCP_KEY` (64-hex or `suiprivkey1…`) in the MCP env — never in
20
+ the browser.
19
21
 
20
22
  ## First connection
21
23
 
@@ -26,8 +28,11 @@ First connection is a spend-account grant plus an agent-held delegate key.
26
28
  2. Persist that delegate key locally at `~/.suipay/credentials.json`
27
29
  (mode `0600`). The process that holds this key is the only process
28
30
  that can settle.
29
- 3. Point MCP at the gateway (`SUIPAY_GATEWAY_URL`) and the same network
30
- the grant was created on.
31
+ 3. Point MCP at a gateway. Default is Railway **suipay-dev**. Pass
32
+ `suipay_login({ target: "local" })` or start the binary with `--local`
33
+ for the laptop stack. Env/CLI fill the process default until a
34
+ credential is bound; after login, stored `gatewayUrl` wins. Rebind
35
+ with `suipay_login({ target })`.
31
36
  4. Call `pay`. The tool prepares unsigned `spend_account` settlement
32
37
  bytes. If this process holds the grant's key it verifies and settles;
33
38
  otherwise it returns the signing request.
@@ -36,17 +41,20 @@ The agent generates or is handed the delegate key. The key never enters
36
41
  a browser URL, a SuiPay backend, logs, or a callback payload. Only the
37
42
  public address leaves the local process. `suipay_login` mints or reuses
38
43
  the local version-2 key at `~/.suipay/credentials.json` (mode `0600`) and
39
- opens `{SUIPAY_CONSOLE_URL}/connect/agent?delegateAddress=0x…`.
44
+ returns `{SUIPAY_CONSOLE_URL}/connect/agent?port=&delegateAddress=&connectState=&gateway=`
45
+ immediately. The owner signs in the browser; the loopback callback persists
46
+ key + gateway URL. Subsequent sessions reuse the file unless the grant is
47
+ missing, expired, or revoked.
40
48
 
41
49
  ## Tools
42
50
 
43
51
  | Tool | Purpose |
44
52
  | --- | --- |
45
- | `discover` | Search live managed-gateway resources |
53
+ | `discover` | Search live gateway resources. After login: `name`, `path`, `url`, `targetHash`, catalog price, and `affordable` (can this session cover one call — not authorization). `pay({ url })` still settles |
46
54
  | `pay` | Fetch resource, prepare `spend_account` settlement, settle when this process holds the grant key |
47
55
  | `receipts` | List settlement receipts, optionally by challenge ID |
48
56
  | `access_context` | Report current session / delegate / policy state (no secret material) |
49
- | `suipay_login` | Mint or reuse the local delegate key and open the console with the public address only |
57
+ | `suipay_login` | Mint or reuse the local delegate key and return a clickable console URL (does not wait for the wallet). Default target is Railway suipay-dev; pass `target: "local"` for the laptop stack |
50
58
  | `suipay_logout` | Remove local credentials |
51
59
 
52
60
  All tools remain visible before a grant is bound. `pay` and `receipts`
@@ -68,16 +76,49 @@ json: {"prompt":"a cat"}
68
76
  maxAmount: 50000
69
77
  ```
70
78
 
71
- `pay` uses the buyer SDK internally. A delivered image is returned as an MCP
72
- image block, not as a base64 wall in the JSON summary.
79
+ `pay` uses SDK `createPayer` internally. When this process settles, a binary
80
+ body is written once under `~/.suipay/deliveries/` and named first in the
81
+ JSON as `savedTo` (absolute path) and `savedToUrl` (`file://`). Hosted `/mcp`
82
+ is prepare-only and does not write a buyer file. Any MIME — image, audio,
83
+ pdf, octet-stream. JSON stays compact (no base64 wall). An MCP `image` block
84
+ is an extra display hint when the type is `image/*`; hosts such as Claude
85
+ Code's TUI may not render it. Always quote `savedTo` when present. If
86
+ `savedTo` is null, quote `saveError` and do not call `pay` again.
87
+
88
+ ## Targets
89
+
90
+ Default is Railway **suipay-dev**. `--local` / `target: "local"` is laptop-only.
91
+
92
+ | Target | Console | Gateway | How |
93
+ | --- | --- | --- | --- |
94
+ | `dev` (default) | `https://suipay-dev.up.railway.app` | `https://gateway-dev-ba84.up.railway.app` | no flag, or `--dev` |
95
+ | `local` | `http://localhost:3000` | `http://127.0.0.1:4340` | `--local` / `-local`, or `suipay_login({ target: "local" })` |
96
+
97
+ ```bash
98
+ # Railway suipay-dev (default)
99
+ npx @cmdoss/suipay-mcp@0.2.2
100
+
101
+ # Laptop stack
102
+ npx @cmdoss/suipay-mcp@0.2.2 --local
103
+ ```
104
+
105
+ `SUIPAY_MCP_TARGET=local|dev` selects the same preset. Explicit
106
+ `SUIPAY_GATEWAY_URL` / `SUIPAY_CONSOLE_URL` fill the process default when no
107
+ credential is bound yet. After a successful login, `credentials.json`
108
+ `gatewayUrl` is the bound gateway: `pay` / `discover` / `suipay_login` without
109
+ `target` stay on that binding so a leftover env cannot silently retarget spend.
110
+ Rebind with `suipay_login({ target: "dev" | "local" })` (same key, new consent
111
+ if that stack has no live grant).
73
112
 
74
113
  ## Client environment
75
114
 
76
115
  ```bash
116
+ # Optional. Unset = Railway suipay-dev. --local uses localhost:3000 / 127.0.0.1:4340.
77
117
  SUIPAY_GATEWAY_URL=https://gateway.example
78
118
  SUIPAY_CONSOLE_URL=https://console.example
79
119
  SUIPAY_RPC_URL=https://your-testnet-rpc.example
80
120
  SUIPAY_NETWORK=testnet
121
+ SUIPAY_MCP_TARGET=dev
81
122
  ```
82
123
 
83
124
  Optional:
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "../chunk-XAM2YQC6.js";
5
- import "../chunk-KDOGSB5I.js";
4
+ } from "../chunk-P54ZYBPN.js";
5
+ import "../chunk-THLDEMGS.js";
6
6
 
7
7
  // src/bin/suipay.ts
8
8
  main().catch((err) => {
@@ -0,0 +1,46 @@
1
+ import {
2
+ createServer,
3
+ loadLocalSigner,
4
+ loadLocalSigningKeyRecord,
5
+ loadMcpConfig,
6
+ loadPaymentProfile
7
+ } from "./chunk-THLDEMGS.js";
8
+
9
+ // src/index.ts
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ function loadBootProfile(load = loadPaymentProfile) {
12
+ try {
13
+ return { profile: load(), unreadable: false };
14
+ } catch {
15
+ return { profile: null, unreadable: true };
16
+ }
17
+ }
18
+ async function main() {
19
+ const argv = process.argv.slice(2);
20
+ const cfg = loadMcpConfig(process.env, argv);
21
+ const target = cfg.target ?? "dev";
22
+ const server = createServer(cfg);
23
+ await server.connect(new StdioServerTransport());
24
+ try {
25
+ const boundGateway = loadLocalSigningKeyRecord()?.gatewayUrl ?? cfg.gatewayUrl;
26
+ const local = loadLocalSigner();
27
+ if (local) {
28
+ console.error(
29
+ `[suipay-mcp] ${target} ${boundGateway} \xB7 delegate ${local.address} \xB7 stdio ready`
30
+ );
31
+ } else {
32
+ console.error(
33
+ `[suipay-mcp] ${target} ${boundGateway} \xB7 not connected \xB7 run suipay_login \xB7 stdio ready`
34
+ );
35
+ }
36
+ } catch {
37
+ console.error(
38
+ `[suipay-mcp] ${target} ${cfg.gatewayUrl} \xB7 credentials unreadable: run suipay_login or suipay_logout force=true \xB7 stdio ready`
39
+ );
40
+ }
41
+ }
42
+
43
+ export {
44
+ loadBootProfile,
45
+ main
46
+ };