@leashmarket/mcp 0.1.0

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 ADDED
@@ -0,0 +1,157 @@
1
+ # @leashmarket/mcp
2
+
3
+ Standalone Leash MCP server. Lets any AI agent in any MCP host
4
+ (Cursor, Claude Desktop, Cline, Continue, ChatGPT-MCP, …) sign
5
+ on-chain Solana transactions, pay x402 paywalls, and check its
6
+ treasury balance — without a browser in the loop.
7
+
8
+ ## Install
9
+
10
+ ```jsonc
11
+ // In Cursor → Settings → MCP, or your MCP host's equivalent:
12
+ {
13
+ "mcpServers": {
14
+ "leash": {
15
+ "command": "npx",
16
+ "args": ["-y", "@leashmarket/mcp"],
17
+ },
18
+ },
19
+ }
20
+ ```
21
+
22
+ Most MCP hosts support an `env` map on each server — use it to override
23
+ the default public RPC (slow / rate-limited). Swap in your own URL:
24
+
25
+ ```jsonc
26
+ {
27
+ "mcpServers": {
28
+ "leash": {
29
+ "command": "npx",
30
+ "args": ["-y", "@leashmarket/mcp"],
31
+ "env": {
32
+ "LEASH_RPC_URL": "https://devnet.helius-rpc.com/?api-key=YOUR_KEY",
33
+ // optional — match mainnet if your agent + links are on mainnet:
34
+ // "LEASH_NETWORK": "solana-mainnet",
35
+ // "LEASH_RPC_URL": "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY",
36
+ },
37
+ },
38
+ },
39
+ }
40
+ ```
41
+
42
+ You can set any other overrides the same way (`LEASH_AGENT_MINT`,
43
+ `LEASH_EXECUTIVE_KEY`, `LEASH_API_URL`, `LEASH_EXPLORER_URL`, …).
44
+ Alternatively, put `rpc_url` in `~/.config/leash/agent.json` — env wins
45
+ over the file when both are set.
46
+
47
+ ## Configure
48
+
49
+ The server looks at, in order:
50
+
51
+ 1. `~/.config/leash/agent.json` (chmod 600). Same posture as
52
+ `gcloud`/`gh`/`aws`.
53
+ 2. Environment variables (override the file when set):
54
+
55
+ | env | required | example |
56
+ | --------------------- | ------------------------ | --------------------------------------------- |
57
+ | `LEASH_AGENT_MINT` | yes | `Agnt7XQ...` |
58
+ | `LEASH_EXECUTIVE_KEY` | yes | `5Jz...` (base58) or `[12,34,...]` (JSON arr) |
59
+ | `LEASH_NETWORK` | no | `solana-mainnet` (default) / `solana-devnet` |
60
+ | `LEASH_API_URL` | no | `https://api.leash.market` (default) |
61
+ | `LEASH_RPC_URL` | **strongly recommended** | bring your own — see below |
62
+ | `LEASH_EXPLORER_URL` | no | `https://explorer.leash.market` (default) |
63
+ | `LEASH_API_KEY` | no | legacy bearer for `/v1/payment-links` |
64
+ | `LEASH_PER_CALL_USDC` | no | per-call spend cap (default `1`) |
65
+ | `LEASH_PER_DAY_USDC` | no | per-day spend cap (default `10`) |
66
+
67
+ > **Bring your own RPC.** The default endpoints
68
+ > (`api.devnet.solana.com`, `api.mainnet-beta.solana.com`) are public,
69
+ > rate-limited, and slow. Each `leash_pay_payment_link` makes 3-5
70
+ > RPC calls — on a public endpoint that's a 4-8s settlement, sometimes
71
+ > a 429. Set `LEASH_RPC_URL` (or `rpc_url` in `agent.json`) to a
72
+ > Helius / Triton / QuickNode / Alchemy / self-hosted endpoint and
73
+ > settlement drops under one second.
74
+
75
+ The server **starts without** an agent configured — `tools/list`
76
+ still works, but every tool short-circuits with a `no_agent` JSON
77
+ blob asking the LLM to onboard the user. (The frictionless
78
+ `leash_register_agent` tool ships in the next release.)
79
+
80
+ `agent.json` example:
81
+
82
+ ```jsonc
83
+ {
84
+ "version": 1,
85
+ "agent_mint": "Agnt7XQ...",
86
+ "executive_keypair": "5Jz...", // base58 OR a 64-element JSON array
87
+ "network": "solana-devnet",
88
+ "rpc_url": "https://devnet.helius-rpc.com/?api-key=YOUR_KEY",
89
+ "explorer_url": "https://explorer.leash.market",
90
+ "created_at": "2026-04-30T...",
91
+ }
92
+ ```
93
+
94
+ ## Tools (v0.1 — 14 canonical)
95
+
96
+ | Tool | What it does |
97
+ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | `leash_register_agent` | Two-step onboarding (call this tool TWICE). Step 1: collect agent name + description + image_url + EIP-8004 `services[]` from the user, persist them alongside a generated/imported executive keypair, return `funding_required`. Step 2: after the user funds the executive with SOL, mint MPL Core agent, set unlimited USDC delegation, record on the API, and HOT-SWAP the in-memory MCP host so subsequent tool calls work without a restart. |
99
+ | `leash_get_identity` | Self-introspection — what agent am I, on which network, what's my treasury PDA. |
100
+ | `leash_check_treasury_balance` | Read SOL + USDC/USDG/USDT balances on the agent treasury PDA. |
101
+ | `leash_pay_payment_link` | Probe an x402 link, sign + settle the SPL transfer locally, return the receipt. |
102
+ | `leash_create_payment_link` | Mint an x402 paywall the user can share. Requires `LEASH_API_KEY` until X-Leash-Sig auth lands. |
103
+ | `leash_withdraw_treasury` | Owner-driven withdrawal of SOL or an SPL stable to any wallet (mpl-core::Execute). |
104
+ | `leash_set_spend_limit` | Owner-driven update of the SPL `Approve` delegation that lets the executive spend stables from the treasury. `mode: 'unlimited' \| 'revoke' \| 'amount'` — tighten, pause, or restore the cap. |
105
+ | `leash_get_spend_limit` | Read the current SPL delegation + treasury balance for a stable. Reports delegate, remaining cap (atomic + decimal), and balance. |
106
+ | `leash_receipts` | Paginated receipts feed for the active agent. Requires `LEASH_API_KEY` until X-Leash-Sig auth lands. |
107
+ | `leash_get_receipt` | Fetch a single ReceiptV1 by `receipt_hash` — same canonical JSON the explorer renders at `/receipt/{hash}` (full price legs, request URL, decision, tx_sig, prev/current chain). |
108
+ | `leash_transaction_history` | List every earn + spend receipt in the last N days (default 7) plus running USD totals (`total_sent_usd`, `total_received_usd`, `net_usd`). Stables (USDC/USDG/USDT) summed at 1:1. |
109
+ | `leash_daily_transactions` | Bin the same window into per-day buckets `[{ date, sent_usd, received_usd, net_usd, sent_count, received_count }]` plus grand totals — structured P&L view. |
110
+ | `leash_discover` | Search the Leash marketplace for paid services by capability + price. Public read — works without an agent. |
111
+ | `leash_reputation` | Live reputation snapshot for any on-chain agent — settled-call volume, dispute rate, distinct counterparties. Public read. |
112
+
113
+ ## Subcommands (cross-interface portability)
114
+
115
+ The CLI is more than the STDIO server — `leash-mcp` has a small set
116
+ of subcommands so an agent can move freely between hosts:
117
+
118
+ ```bash
119
+ leash-mcp # default — run the STDIO MCP server
120
+ leash-mcp export # print active agent.json to stdout
121
+ leash-mcp export --out a.json # save instead
122
+ leash-mcp import path/to/agent.json # install into ~/.config/leash/
123
+ leash-mcp doctor # config + RPC + API reachability check
124
+ leash-mcp help # full help
125
+ ```
126
+
127
+ Use `export` + `import` to roam: an agent minted from Cursor's MCP
128
+ can be `export`ed, dropped into Claude Desktop, and `import`ed into
129
+ its config — same on-chain identity, same treasury, same reputation.
130
+ Same JSON also pastes cleanly into the chat product's
131
+ _Profile → Agent → Import_ page (forthcoming).
132
+
133
+ ## Try the read path
134
+
135
+ After provisioning an agent with `leash_register_agent` (or `leash agent create`),
136
+ poke balances through the MCP protocol directly:
137
+
138
+ ```bash
139
+ LEASH_AGENT_MINT=<mint> \
140
+ LEASH_EXECUTIVE_KEY=<base58 secret> \
141
+ LEASH_NETWORK=solana-mainnet \
142
+ pnpm --filter @leashmarket/mcp dev:demo-balance
143
+ ```
144
+
145
+ That bypasses STDIO and uses an in-memory transport — fastest way
146
+ to verify the path before recording a real demo.
147
+
148
+ ## Develop
149
+
150
+ ```bash
151
+ pnpm --filter @leashmarket/mcp typecheck
152
+ pnpm --filter @leashmarket/mcp test
153
+ pnpm --filter @leashmarket/mcp build
154
+ ```
155
+
156
+ The compiled `dist/cli.js` is set executable (`chmod +x`) by the
157
+ build script so `npx -y @leashmarket/mcp` works without an extra step.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `@leashmarket/mcp` CLI entry point.
4
+ *
5
+ * Subcommands:
6
+ *
7
+ * leash-mcp Default — run the STDIO MCP server.
8
+ * Hosts (Cursor, Claude Desktop, Cline,
9
+ * Continue, ChatGPT-MCP) wire this up
10
+ * via:
11
+ *
12
+ * {
13
+ * "mcpServers": {
14
+ * "leash": {
15
+ * "command": "npx",
16
+ * "args": ["-y", "@leashmarket/mcp"]
17
+ * }
18
+ * }
19
+ * }
20
+ *
21
+ * leash-mcp export [--out <path>] Print or save the active agent.json
22
+ * so the same identity can be moved
23
+ * into another host (or the chat product
24
+ * via Profile → Agent → Import).
25
+ *
26
+ * leash-mcp import <path> Copy a JSON agent config into the
27
+ * default location (~/.config/leash/agent.json).
28
+ * This is how an agent minted in the
29
+ * chat product (or downloaded from
30
+ * another machine) becomes the local
31
+ * default.
32
+ *
33
+ * leash-mcp doctor Print a quick diagnostic — config
34
+ * path, agent mint, executive pubkey,
35
+ * network, RPC reachability, API
36
+ * reachability. Useful for the demo
37
+ * sanity check.
38
+ *
39
+ * On any boot path we never throw — the goal is the LLM never sees a
40
+ * tool exception. STDIO server logs go to stderr; subcommands print
41
+ * to stdout.
42
+ */
43
+ export {};
44
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG"}
package/dist/cli.js ADDED
@@ -0,0 +1,314 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `@leashmarket/mcp` CLI entry point.
4
+ *
5
+ * Subcommands:
6
+ *
7
+ * leash-mcp Default — run the STDIO MCP server.
8
+ * Hosts (Cursor, Claude Desktop, Cline,
9
+ * Continue, ChatGPT-MCP) wire this up
10
+ * via:
11
+ *
12
+ * {
13
+ * "mcpServers": {
14
+ * "leash": {
15
+ * "command": "npx",
16
+ * "args": ["-y", "@leashmarket/mcp"]
17
+ * }
18
+ * }
19
+ * }
20
+ *
21
+ * leash-mcp export [--out <path>] Print or save the active agent.json
22
+ * so the same identity can be moved
23
+ * into another host (or the chat product
24
+ * via Profile → Agent → Import).
25
+ *
26
+ * leash-mcp import <path> Copy a JSON agent config into the
27
+ * default location (~/.config/leash/agent.json).
28
+ * This is how an agent minted in the
29
+ * chat product (or downloaded from
30
+ * another machine) becomes the local
31
+ * default.
32
+ *
33
+ * leash-mcp doctor Print a quick diagnostic — config
34
+ * path, agent mint, executive pubkey,
35
+ * network, RPC reachability, API
36
+ * reachability. Useful for the demo
37
+ * sanity check.
38
+ *
39
+ * On any boot path we never throw — the goal is the LLM never sees a
40
+ * tool exception. STDIO server logs go to stderr; subcommands print
41
+ * to stdout.
42
+ */
43
+ import { readFileSync, statSync } from 'node:fs';
44
+ import { mkdir, copyFile } from 'node:fs/promises';
45
+ import { dirname } from 'node:path';
46
+ import { defaultConfigPath, loadAgentConfig } from './config.js';
47
+ import { writeAgentConfig } from './config-write.js';
48
+ import { runStdioServer } from './server.js';
49
+ import { loadSigner } from './signer.js';
50
+ async function main() {
51
+ const argv = process.argv.slice(2);
52
+ const cmd = argv[0];
53
+ switch (cmd) {
54
+ case undefined:
55
+ case 'serve':
56
+ case 'run':
57
+ await runStdioServer();
58
+ return;
59
+ case 'export':
60
+ await runExport(argv.slice(1));
61
+ return;
62
+ case 'import':
63
+ await runImport(argv.slice(1));
64
+ return;
65
+ case 'doctor':
66
+ await runDoctor();
67
+ return;
68
+ case '-h':
69
+ case '--help':
70
+ case 'help':
71
+ printHelp();
72
+ return;
73
+ case '-v':
74
+ case '--version':
75
+ printVersion();
76
+ return;
77
+ default:
78
+ process.stderr.write(`unknown command: ${cmd}\n\n`);
79
+ printHelp();
80
+ process.exit(2);
81
+ }
82
+ }
83
+ main().catch((err) => {
84
+ const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);
85
+ process.stderr.write(`[leash-mcp] fatal: ${msg}\n`);
86
+ process.exit(1);
87
+ });
88
+ // ────────────────────────────────────────────────────────────────────────────
89
+ // export
90
+ // ────────────────────────────────────────────────────────────────────────────
91
+ async function runExport(args) {
92
+ const config = loadAgentConfig();
93
+ if (!config) {
94
+ process.stderr.write('no agent configured. Run `leash-mcp` and call `leash_register_agent`, or set LEASH_AGENT_MINT + LEASH_EXECUTIVE_KEY first.\n');
95
+ process.exit(1);
96
+ }
97
+ const file = {
98
+ version: 1,
99
+ agent_mint: config.agentMint,
100
+ executive_keypair: config.executiveSecretBase58,
101
+ network: config.network,
102
+ api_url: config.apiBaseUrl,
103
+ rpc_url: config.rpcUrl,
104
+ ...(config.apiKey ? { api_key: config.apiKey } : {}),
105
+ exported_at: new Date().toISOString(),
106
+ };
107
+ const body = `${JSON.stringify(file, null, 2)}\n`;
108
+ const outFlag = args.indexOf('--out');
109
+ if (outFlag !== -1 && args[outFlag + 1]) {
110
+ const outPath = args[outFlag + 1];
111
+ await mkdir(dirname(outPath), { recursive: true, mode: 0o700 });
112
+ const { writeFile } = await import('node:fs/promises');
113
+ await writeFile(outPath, body, { mode: 0o600 });
114
+ process.stderr.write(`exported to ${outPath} (chmod 600)\n`);
115
+ return;
116
+ }
117
+ process.stdout.write(body);
118
+ }
119
+ // ────────────────────────────────────────────────────────────────────────────
120
+ // import
121
+ // ────────────────────────────────────────────────────────────────────────────
122
+ async function runImport(args) {
123
+ const src = args[0];
124
+ if (!src) {
125
+ process.stderr.write('usage: leash-mcp import <path-to-agent.json>\n');
126
+ process.exit(2);
127
+ }
128
+ let stat;
129
+ try {
130
+ stat = statSync(src);
131
+ }
132
+ catch {
133
+ process.stderr.write(`cannot read ${src}\n`);
134
+ process.exit(1);
135
+ }
136
+ if (!stat.isFile()) {
137
+ process.stderr.write(`${src} is not a regular file\n`);
138
+ process.exit(1);
139
+ }
140
+ let parsed;
141
+ try {
142
+ parsed = JSON.parse(readFileSync(src, 'utf8'));
143
+ }
144
+ catch (err) {
145
+ process.stderr.write(`${src} is not valid JSON: ${err.message}\n`);
146
+ process.exit(1);
147
+ }
148
+ if (!parsed || typeof parsed !== 'object') {
149
+ process.stderr.write(`${src} is not an object\n`);
150
+ process.exit(1);
151
+ }
152
+ const f = parsed;
153
+ const agentMint = typeof f.agent_mint === 'string' ? f.agent_mint : undefined;
154
+ const executiveKey = typeof f.executive_keypair === 'string' ? f.executive_keypair : undefined;
155
+ if (!agentMint || !executiveKey) {
156
+ process.stderr.write('config missing required fields: agent_mint, executive_keypair\n');
157
+ process.exit(1);
158
+ }
159
+ // Validate the executive secret decodes to a real ed25519 keypair
160
+ // before clobbering the on-disk config — otherwise we'd silently
161
+ // brick the user's setup.
162
+ try {
163
+ loadSigner(executiveKey);
164
+ }
165
+ catch (err) {
166
+ process.stderr.write(`executive_keypair invalid: ${err.message}\n`);
167
+ process.exit(1);
168
+ }
169
+ const network = f.network === 'solana-devnet' ? 'solana-devnet' : 'solana-mainnet';
170
+ const apiBaseUrl = typeof f.api_url === 'string' && f.api_url.length > 0 ? f.api_url : 'https://api.leash.market';
171
+ const rpcUrl = typeof f.rpc_url === 'string' && f.rpc_url.length > 0
172
+ ? f.rpc_url
173
+ : network === 'solana-mainnet'
174
+ ? 'https://api.mainnet-beta.solana.com'
175
+ : 'https://api.devnet.solana.com';
176
+ const explorerBaseUrl = typeof f.explorer_url === 'string' && f.explorer_url.length > 0
177
+ ? f.explorer_url
178
+ : 'https://explorer.leash.market';
179
+ const apiKey = typeof f.api_key === 'string' ? f.api_key : null;
180
+ const target = defaultConfigPath();
181
+ await writeAgentConfig({
182
+ config: {
183
+ agentMint,
184
+ executiveSecretBase58: executiveKey,
185
+ network,
186
+ apiBaseUrl,
187
+ rpcUrl,
188
+ explorerBaseUrl,
189
+ apiKey,
190
+ },
191
+ path: target,
192
+ });
193
+ // Also copy as a backup so the user has the original.
194
+ try {
195
+ await mkdir(dirname(`${target}.backup`), { recursive: true, mode: 0o700 });
196
+ await copyFile(src, `${target}.backup`);
197
+ }
198
+ catch {
199
+ /* best-effort backup */
200
+ }
201
+ process.stdout.write(`imported ${agentMint} (network=${network}) → ${target}\n`);
202
+ }
203
+ // ────────────────────────────────────────────────────────────────────────────
204
+ // doctor
205
+ // ────────────────────────────────────────────────────────────────────────────
206
+ async function runDoctor() {
207
+ const path = defaultConfigPath();
208
+ const config = loadAgentConfig();
209
+ const lines = [];
210
+ lines.push(`config_path: ${path}`);
211
+ if (!config) {
212
+ lines.push(`status: no_agent (call \`leash_register_agent\` from any MCP host)`);
213
+ process.stdout.write(`${lines.join('\n')}\n`);
214
+ return;
215
+ }
216
+ let executivePubkey = '<unknown>';
217
+ try {
218
+ executivePubkey = loadSigner(config.executiveSecretBase58).pubkey;
219
+ }
220
+ catch (err) {
221
+ lines.push(`status: error — executive secret invalid: ${err.message}`);
222
+ process.stdout.write(`${lines.join('\n')}\n`);
223
+ return;
224
+ }
225
+ lines.push(`agent_mint: ${config.agentMint}`);
226
+ lines.push(`executive_pubkey: ${executivePubkey}`);
227
+ lines.push(`network: ${config.network}`);
228
+ lines.push(`api_base_url: ${config.apiBaseUrl}`);
229
+ lines.push(`rpc_url: ${config.rpcUrl}`);
230
+ lines.push(`explorer_url: ${config.explorerBaseUrl}`);
231
+ lines.push(`api_key: ${config.apiKey ? `set (${config.apiKey.slice(0, 8)}…)` : 'unset'}`);
232
+ // RPC reachability — best-effort getVersion JSON-RPC ping.
233
+ lines.push(`rpc_check: ${await pingRpc(config.rpcUrl)}`);
234
+ // API reachability — GET /v1/discover (public, cheap).
235
+ lines.push(`api_check: ${await pingApi(config.apiBaseUrl)}`);
236
+ if (isPublicRpc(config.rpcUrl)) {
237
+ lines.push('');
238
+ lines.push('⚠ rpc_url points at the public Solana RPC. Settlement (`leash_pay_payment_link`)');
239
+ lines.push(' makes 3-5 RPC calls and the public endpoint is rate-limited (429s) and slow');
240
+ lines.push(' (4-8s per pay). Set LEASH_RPC_URL or `rpc_url` in agent.json to a Helius /');
241
+ lines.push(' Triton / QuickNode / Alchemy / self-hosted endpoint. See:');
242
+ lines.push(' https://docs.leash.market/agents/mcp#bring-your-own-rpc');
243
+ }
244
+ process.stdout.write(`${lines.join('\n')}\n`);
245
+ }
246
+ /**
247
+ * Returns true when the configured RPC is one of the public Solana
248
+ * defaults baked into `config.ts`. Used by `doctor` to surface a
249
+ * latency warning. Matches host-only — query strings are stripped so
250
+ * `?api-key=…` overrides are correctly recognised as private.
251
+ */
252
+ function isPublicRpc(rpcUrl) {
253
+ try {
254
+ const u = new URL(rpcUrl);
255
+ const host = u.host.toLowerCase();
256
+ return host === 'api.devnet.solana.com' || host === 'api.mainnet-beta.solana.com';
257
+ }
258
+ catch {
259
+ return false;
260
+ }
261
+ }
262
+ async function pingRpc(rpcUrl) {
263
+ try {
264
+ const res = await fetch(rpcUrl, {
265
+ method: 'POST',
266
+ headers: { 'content-type': 'application/json' },
267
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getVersion' }),
268
+ });
269
+ if (!res.ok)
270
+ return `error (HTTP ${res.status})`;
271
+ const json = (await res.json());
272
+ return `ok (solana-core=${json.result?.['solana-core'] ?? 'unknown'})`;
273
+ }
274
+ catch (err) {
275
+ return `error (${err.message})`;
276
+ }
277
+ }
278
+ async function pingApi(apiBaseUrl) {
279
+ try {
280
+ const url = `${apiBaseUrl.replace(/\/+$/, '')}/v1/discover?limit=1`;
281
+ const res = await fetch(url);
282
+ return `ok (HTTP ${res.status})`;
283
+ }
284
+ catch (err) {
285
+ return `error (${err.message})`;
286
+ }
287
+ }
288
+ // ────────────────────────────────────────────────────────────────────────────
289
+ // help / version
290
+ // ────────────────────────────────────────────────────────────────────────────
291
+ function printHelp() {
292
+ process.stdout.write([
293
+ 'usage: leash-mcp [command] [options]',
294
+ '',
295
+ 'commands:',
296
+ ' (default) run the STDIO MCP server (alias: serve, run)',
297
+ ' export print active agent.json to stdout (or --out <path>)',
298
+ ' import <path> install a downloaded agent.json into ~/.config/leash/',
299
+ ' doctor diagnostic — config + RPC + API reachability',
300
+ ' help, -h show this message',
301
+ ' version, -v show installed version',
302
+ '',
303
+ 'environment overrides:',
304
+ ' LEASH_AGENT_MINT, LEASH_EXECUTIVE_KEY, LEASH_NETWORK,',
305
+ ' LEASH_API_URL, LEASH_RPC_URL, LEASH_API_KEY',
306
+ '',
307
+ 'see https://leash.market/docs/mcp for setup details.',
308
+ '',
309
+ ].join('\n'));
310
+ }
311
+ function printVersion() {
312
+ process.stdout.write('@leashmarket/mcp 0.1.0\n');
313
+ }
314
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Persist a freshly-registered agent (or a pending-register block) to
3
+ * `~/.config/leash/agent.json` with `chmod 600` so subsequent
4
+ * `leash-mcp` / `leash` CLI launches pick up the new identity
5
+ * automatically.
6
+ *
7
+ * Lives in its own module (separate from `./config.ts`) because the
8
+ * read path is browser-safe — `loadAgentConfig` only depends on
9
+ * `node:fs` types — while writing requires `node:fs/promises` and
10
+ * `node:os`. Keeping the boundaries clean lets the SDK reuse the
11
+ * read path in non-Node runtimes (Bun, Deno, edge) without dragging
12
+ * in the file-system writer.
13
+ */
14
+ import type { LeashAgentConfig, LeashHostDefaults, PendingRegister } from './config.js';
15
+ /**
16
+ * Write a fully-registered `LeashAgentConfig` to disk. Creates parent
17
+ * directories with mode 0700, writes the file with mode 0600.
18
+ * Idempotent: overwrites in-place. Clears any `pending_register`
19
+ * block left over from the two-step registration flow.
20
+ */
21
+ export declare function writeAgentConfig(args: {
22
+ config: LeashAgentConfig;
23
+ path?: string;
24
+ pretty?: boolean;
25
+ }): Promise<string>;
26
+ /**
27
+ * Persist a pending executive keypair while the user funds it with
28
+ * SOL. Subsequent `leash_register_agent` calls (or a fresh MCP boot)
29
+ * will pick this up via `loadAgentSession().pending`. The block is
30
+ * cleared once `writeAgentConfig` lands the registered config.
31
+ */
32
+ export declare function writePendingRegister(args: {
33
+ pending: PendingRegister;
34
+ defaults: LeashHostDefaults;
35
+ path?: string;
36
+ pretty?: boolean;
37
+ }): Promise<string>;
38
+ //# sourceMappingURL=config-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-write.d.ts","sourceRoot":"","sources":["../src/config-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGxF;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CAclB;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BlB"}