@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.
@@ -0,0 +1,131 @@
1
+ /**
2
+ * STDIO-transport Leash MCP server.
3
+ *
4
+ * Builds an `@modelcontextprotocol/sdk` server, registers each
5
+ * `LeashTool` from `@leashmarket/mcp-core` against the standalone host,
6
+ * and returns the configured `McpServer` ready for the caller to
7
+ * connect to a transport (STDIO, HTTP, in-memory).
8
+ *
9
+ * The chat product wraps the same `LeashTool` set with the Claude
10
+ * Agent SDK's `tool()` helper; this module wraps them with the MCP
11
+ * SDK's `server.registerTool()`. Both call into the same `LeashHost`
12
+ * methods — only the runtime adapter differs.
13
+ *
14
+ * Boot states
15
+ * -----------
16
+ * The server boots in three states, all of which surface working
17
+ * tool schemas to the LLM:
18
+ *
19
+ * 1. **Registered.** `agent.json` has a mint + executive. The
20
+ * placeholder is never installed — the inner host is a real
21
+ * `StdioHost` from the start.
22
+ *
23
+ * 2. **Awaiting funding.** A previous `leash_register_agent` call
24
+ * generated (or imported) an executive keypair but the user
25
+ * hasn't sent it SOL yet. `agent.json` carries a
26
+ * `pending_register` block. Settlement tools return `no_agent`;
27
+ * the next `leash_register_agent` call resumes from the
28
+ * persisted pending block, balance-checks, and mints if funded.
29
+ *
30
+ * 3. **Fresh.** No agent state on disk. Settlement tools return
31
+ * `no_agent`; the first `leash_register_agent` call generates
32
+ * (or imports) a keypair, persists it, and returns
33
+ * `funding_required`.
34
+ *
35
+ * In every state `leash_register_agent` is fully functional, hot-swaps
36
+ * the in-memory host, and persists state to disk so the LLM can
37
+ * recover without restarting the MCP host.
38
+ */
39
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
40
+ import { type CheckTreasuryBalanceArgs, type CreatePaymentLinkArgs, type DailyTransactionsArgs, type DiscoverArgs, type GetIdentityArgs, type GetReceiptArgs, type GetSpendLimitArgs, type LeashHost, type LeashToolResult, type PayArgs, type PaySkillsProviderArgs, type ReceiptsArgs, type RegisterAgentArgs, type ReputationArgs, type SetSpendLimitArgs, type SvmNetwork, type TransactionHistoryArgs, type WithdrawArgs } from '@leashmarket/mcp-core';
41
+ import { type LeashAgentConfig, type LeashHostDefaults, type PendingRegister } from './config.js';
42
+ /**
43
+ * Build the MCP server bound to the given host. Each `LeashTool`
44
+ * gets registered via the SDK's `tool()` overload.
45
+ *
46
+ * `LeashTool.handler` receives `args, ctx`; we close over `host` so
47
+ * the MCP-SDK callback shape (`(args) => …`) lines up.
48
+ */
49
+ export declare function createLeashMcpServer(host: LeashHost): McpServer;
50
+ /**
51
+ * High-level convenience: load on-disk config + env overrides, build
52
+ * a swappable `HostRef`, build the server. The `HostRef` is what
53
+ * lets `leash_register_agent` mutate the in-memory host without
54
+ * tearing down the MCP connection.
55
+ */
56
+ export declare function buildServerFromEnv(opts?: {
57
+ configPath?: string;
58
+ }): {
59
+ server: McpServer;
60
+ config: LeashAgentConfig | null;
61
+ pending: PendingRegister | null;
62
+ defaults: LeashHostDefaults;
63
+ /** The mutable host wrapper. Useful for tests asserting state changes. */
64
+ hostRef: HostRef;
65
+ };
66
+ /**
67
+ * Run the MCP server on STDIO. Blocks the event loop until the
68
+ * client disconnects. Logs to stderr only — STDOUT is reserved
69
+ * for the JSON-RPC framed messages.
70
+ */
71
+ export declare function runStdioServer(opts?: {
72
+ configPath?: string;
73
+ }): Promise<void>;
74
+ /**
75
+ * Wraps a `LeashHost` so `registerAgent` can replace the underlying
76
+ * implementation in place. Forwards every standard method to the
77
+ * current `inner` host; intercepts `registerAgent` to handle the
78
+ * placeholder → pending → registered upgrade chain.
79
+ *
80
+ * We use a class with explicit forwarders (rather than a Proxy) so
81
+ * the TypeScript surface stays tight and readers can see exactly
82
+ * what each method does.
83
+ */
84
+ export declare class HostRef implements LeashHost {
85
+ private inner;
86
+ private readonly configPath;
87
+ private defaults;
88
+ private pending;
89
+ constructor(args: {
90
+ inner: LeashHost;
91
+ configPath: string;
92
+ defaults: LeashHostDefaults;
93
+ pending: PendingRegister | null;
94
+ });
95
+ /** Test/inspection hook. Not part of the `LeashHost` contract. */
96
+ getInner(): LeashHost;
97
+ get agentMint(): string | null;
98
+ get ownerWallet(): string | null;
99
+ get network(): SvmNetwork;
100
+ get rpcUrl(): string;
101
+ get apiBaseUrl(): string;
102
+ createPaymentLink(args: CreatePaymentLinkArgs): Promise<LeashToolResult>;
103
+ pay(args: PayArgs): Promise<LeashToolResult>;
104
+ withdraw(args: WithdrawArgs): Promise<LeashToolResult>;
105
+ checkTreasuryBalance(args: CheckTreasuryBalanceArgs): Promise<LeashToolResult>;
106
+ getIdentity(args: GetIdentityArgs): Promise<LeashToolResult>;
107
+ receipts(args: ReceiptsArgs): Promise<LeashToolResult>;
108
+ discover(args: DiscoverArgs): Promise<LeashToolResult>;
109
+ reputation(args: ReputationArgs): Promise<LeashToolResult>;
110
+ paySkillsProvider(args: PaySkillsProviderArgs): Promise<LeashToolResult>;
111
+ setSpendLimit(args: SetSpendLimitArgs): Promise<LeashToolResult>;
112
+ getSpendLimit(args: GetSpendLimitArgs): Promise<LeashToolResult>;
113
+ getReceipt(args: GetReceiptArgs): Promise<LeashToolResult>;
114
+ transactionHistory(args: TransactionHistoryArgs): Promise<LeashToolResult>;
115
+ dailyTransactions(args: DailyTransactionsArgs): Promise<LeashToolResult>;
116
+ /**
117
+ * Two-step registration:
118
+ * - First call: select keypair (generate / import), persist
119
+ * `pending_register`, return `funding_required` with the pubkey
120
+ * and minimum SOL amount.
121
+ * - Second call: resume from `pending_register`, balance-check,
122
+ * mint + delegate + record, write final `agent.json`, hot-swap.
123
+ */
124
+ registerAgent(args: RegisterAgentArgs): Promise<RegisterResultLike>;
125
+ private executiveFromPending;
126
+ private selectExecutive;
127
+ private persistPending;
128
+ }
129
+ type RegisterResultLike = LeashToolResult;
130
+ export {};
131
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js ADDED
@@ -0,0 +1,502 @@
1
+ /**
2
+ * STDIO-transport Leash MCP server.
3
+ *
4
+ * Builds an `@modelcontextprotocol/sdk` server, registers each
5
+ * `LeashTool` from `@leashmarket/mcp-core` against the standalone host,
6
+ * and returns the configured `McpServer` ready for the caller to
7
+ * connect to a transport (STDIO, HTTP, in-memory).
8
+ *
9
+ * The chat product wraps the same `LeashTool` set with the Claude
10
+ * Agent SDK's `tool()` helper; this module wraps them with the MCP
11
+ * SDK's `server.registerTool()`. Both call into the same `LeashHost`
12
+ * methods — only the runtime adapter differs.
13
+ *
14
+ * Boot states
15
+ * -----------
16
+ * The server boots in three states, all of which surface working
17
+ * tool schemas to the LLM:
18
+ *
19
+ * 1. **Registered.** `agent.json` has a mint + executive. The
20
+ * placeholder is never installed — the inner host is a real
21
+ * `StdioHost` from the start.
22
+ *
23
+ * 2. **Awaiting funding.** A previous `leash_register_agent` call
24
+ * generated (or imported) an executive keypair but the user
25
+ * hasn't sent it SOL yet. `agent.json` carries a
26
+ * `pending_register` block. Settlement tools return `no_agent`;
27
+ * the next `leash_register_agent` call resumes from the
28
+ * persisted pending block, balance-checks, and mints if funded.
29
+ *
30
+ * 3. **Fresh.** No agent state on disk. Settlement tools return
31
+ * `no_agent`; the first `leash_register_agent` call generates
32
+ * (or imports) a keypair, persists it, and returns
33
+ * `funding_required`.
34
+ *
35
+ * In every state `leash_register_agent` is fully functional, hot-swaps
36
+ * the in-memory host, and persists state to disk so the LLM can
37
+ * recover without restarting the MCP host.
38
+ */
39
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
40
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
41
+ import { LEASH_TOOLS, fetchDiscover, fetchPaySkillsProvider, fetchReputation, } from '@leashmarket/mcp-core';
42
+ import { defaultConfigPath, loadAgentSession, } from './config.js';
43
+ import { writeAgentConfig, writePendingRegister } from './config-write.js';
44
+ import { createStdioHost } from './host-stdio.js';
45
+ import { RECOMMENDED_FUND_LAMPORTS, RECOMMENDED_FUND_SOL, generateExecutive, getExecutiveBalanceLamports, importExecutive, lamportsToSol, mintAgentLocally, } from './mint-local.js';
46
+ const SERVER_NAME = 'leash';
47
+ const SERVER_VERSION = '0.2.0';
48
+ /**
49
+ * Build the MCP server bound to the given host. Each `LeashTool`
50
+ * gets registered via the SDK's `tool()` overload.
51
+ *
52
+ * `LeashTool.handler` receives `args, ctx`; we close over `host` so
53
+ * the MCP-SDK callback shape (`(args) => …`) lines up.
54
+ */
55
+ export function createLeashMcpServer(host) {
56
+ const server = new McpServer({
57
+ name: SERVER_NAME,
58
+ version: SERVER_VERSION,
59
+ });
60
+ for (const def of LEASH_TOOLS) {
61
+ registerLeashTool(server, def, host);
62
+ }
63
+ return server;
64
+ }
65
+ /**
66
+ * Register one shared `LeashTool` against an MCP server instance.
67
+ * Pulled out of the loop so the type-cast surface is small.
68
+ *
69
+ * We use the `tool(name, description, paramsSchema, cb)` overload
70
+ * (rather than the newer `registerTool` config-object form) because
71
+ * its generics flow better through our erased `LeashTool` type:
72
+ * `registerTool` infers `InputArgs = undefined` when the schema is
73
+ * widened, which then rejects our `(args) => Promise<...>` callback.
74
+ *
75
+ * `tool()` is marked `@deprecated` in the SDK but still functions
76
+ * identically — we'll migrate when MCP-SDK v2 lands.
77
+ */
78
+ function registerLeashTool(server, def, host) {
79
+ const shape = def.inputSchema.shape ??
80
+ def.inputSchema;
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ server.tool(def.name, def.description, shape, async (args) => def.handler(args, host));
83
+ }
84
+ /**
85
+ * High-level convenience: load on-disk config + env overrides, build
86
+ * a swappable `HostRef`, build the server. The `HostRef` is what
87
+ * lets `leash_register_agent` mutate the in-memory host without
88
+ * tearing down the MCP connection.
89
+ */
90
+ export function buildServerFromEnv(opts) {
91
+ const configPath = opts?.configPath ?? defaultConfigPath();
92
+ const session = loadAgentSession(opts?.configPath ? { path: configPath } : {});
93
+ const initialInner = session.config
94
+ ? createStdioHost(session.config)
95
+ : makePlaceholderHost(session.defaults);
96
+ const hostRef = new HostRef({
97
+ inner: initialInner,
98
+ configPath,
99
+ defaults: session.defaults,
100
+ pending: session.pending,
101
+ });
102
+ return {
103
+ server: createLeashMcpServer(hostRef),
104
+ config: session.config,
105
+ pending: session.pending,
106
+ defaults: session.defaults,
107
+ hostRef,
108
+ };
109
+ }
110
+ /**
111
+ * Run the MCP server on STDIO. Blocks the event loop until the
112
+ * client disconnects. Logs to stderr only — STDOUT is reserved
113
+ * for the JSON-RPC framed messages.
114
+ */
115
+ export async function runStdioServer(opts) {
116
+ const { server, config, pending, defaults } = buildServerFromEnv(opts);
117
+ if (config) {
118
+ process.stderr.write(`[leash-mcp] ready agent=${config.agentMint} network=${config.network} executive=${maskPubkey(loadExecPubkey(config))}\n`);
119
+ }
120
+ else if (pending) {
121
+ process.stderr.write(`[leash-mcp] ready (awaiting funding) network=${pending.network} executive=${maskPubkey(pending.executivePubkey)} — send ${RECOMMENDED_FUND_SOL} SOL to that address, then call leash_register_agent again\n`);
122
+ }
123
+ else {
124
+ process.stderr.write(`[leash-mcp] ready (no agent configured) network=${defaults.network} — call leash_register_agent to provision one\n`);
125
+ }
126
+ const transport = new StdioServerTransport();
127
+ await server.connect(transport);
128
+ }
129
+ function loadExecPubkey(config) {
130
+ const host = createStdioHost(config);
131
+ return host.ownerWallet ?? '<unknown>';
132
+ }
133
+ function maskPubkey(pk) {
134
+ if (pk.length < 12)
135
+ return pk;
136
+ return `${pk.slice(0, 4)}…${pk.slice(-4)}`;
137
+ }
138
+ // ────────────────────────────────────────────────────────────────────────────
139
+ // HostRef — swappable LeashHost wrapper
140
+ // ────────────────────────────────────────────────────────────────────────────
141
+ /**
142
+ * Wraps a `LeashHost` so `registerAgent` can replace the underlying
143
+ * implementation in place. Forwards every standard method to the
144
+ * current `inner` host; intercepts `registerAgent` to handle the
145
+ * placeholder → pending → registered upgrade chain.
146
+ *
147
+ * We use a class with explicit forwarders (rather than a Proxy) so
148
+ * the TypeScript surface stays tight and readers can see exactly
149
+ * what each method does.
150
+ */
151
+ export class HostRef {
152
+ inner;
153
+ configPath;
154
+ defaults;
155
+ pending;
156
+ constructor(args) {
157
+ this.inner = args.inner;
158
+ this.configPath = args.configPath;
159
+ this.defaults = args.defaults;
160
+ this.pending = args.pending;
161
+ }
162
+ /** Test/inspection hook. Not part of the `LeashHost` contract. */
163
+ getInner() {
164
+ return this.inner;
165
+ }
166
+ // ── identity getters (delegate to inner) ──
167
+ get agentMint() {
168
+ return this.inner.agentMint;
169
+ }
170
+ get ownerWallet() {
171
+ return this.inner.ownerWallet;
172
+ }
173
+ get network() {
174
+ return this.inner.network;
175
+ }
176
+ get rpcUrl() {
177
+ return this.inner.rpcUrl;
178
+ }
179
+ get apiBaseUrl() {
180
+ return this.inner.apiBaseUrl;
181
+ }
182
+ // ── settlement methods — pure delegation ──
183
+ createPaymentLink(args) {
184
+ return this.inner.createPaymentLink(args);
185
+ }
186
+ pay(args) {
187
+ return this.inner.pay(args);
188
+ }
189
+ withdraw(args) {
190
+ return this.inner.withdraw(args);
191
+ }
192
+ checkTreasuryBalance(args) {
193
+ return this.inner.checkTreasuryBalance(args);
194
+ }
195
+ getIdentity(args) {
196
+ return this.inner.getIdentity(args);
197
+ }
198
+ receipts(args) {
199
+ return this.inner.receipts(args);
200
+ }
201
+ discover(args) {
202
+ return this.inner.discover(args);
203
+ }
204
+ reputation(args) {
205
+ return this.inner.reputation(args);
206
+ }
207
+ paySkillsProvider(args) {
208
+ return this.inner.paySkillsProvider(args);
209
+ }
210
+ setSpendLimit(args) {
211
+ return this.inner.setSpendLimit(args);
212
+ }
213
+ getSpendLimit(args) {
214
+ return this.inner.getSpendLimit(args);
215
+ }
216
+ getReceipt(args) {
217
+ return this.inner.getReceipt(args);
218
+ }
219
+ transactionHistory(args) {
220
+ return this.inner.transactionHistory(args);
221
+ }
222
+ dailyTransactions(args) {
223
+ return this.inner.dailyTransactions(args);
224
+ }
225
+ /**
226
+ * Two-step registration:
227
+ * - First call: select keypair (generate / import), persist
228
+ * `pending_register`, return `funding_required` with the pubkey
229
+ * and minimum SOL amount.
230
+ * - Second call: resume from `pending_register`, balance-check,
231
+ * mint + delegate + record, write final `agent.json`, hot-swap.
232
+ */
233
+ async registerAgent(args) {
234
+ if (this.inner.agentMint) {
235
+ return this.inner.registerAgent(args);
236
+ }
237
+ try {
238
+ const executive = this.pending
239
+ ? this.executiveFromPending(this.pending)
240
+ : await this.selectExecutive(args);
241
+ const network = this.pending?.network ?? this.defaults.network;
242
+ const balance = await getExecutiveBalanceLamports({
243
+ rpcUrl: this.defaults.rpcUrl,
244
+ pubkey: executive.pubkey,
245
+ });
246
+ // Merge fresh args into persisted meta. Step 1 captures
247
+ // name/description/image/services; Step 2 keeps them. If the
248
+ // user re-runs Step 1 with fresh values, the new ones win.
249
+ const persistedMeta = this.pending?.meta ?? {};
250
+ const meta = {
251
+ ...persistedMeta,
252
+ ...(args.name ? { name: args.name } : {}),
253
+ ...(args.description ? { description: args.description } : {}),
254
+ ...(args.image_url ? { imageUrl: args.image_url } : {}),
255
+ ...(args.services && args.services.length > 0 ? { services: args.services } : {}),
256
+ };
257
+ if (balance < RECOMMENDED_FUND_LAMPORTS) {
258
+ if (!this.pending) {
259
+ // First call — persist the keypair AND the agent draft so
260
+ // the user can shut down the MCP host while funding and
261
+ // resume later without losing either.
262
+ const newPending = {
263
+ executiveSecretBase58: executive.secretBase58,
264
+ executivePubkey: executive.pubkey,
265
+ network,
266
+ createdAt: new Date().toISOString(),
267
+ ...(Object.keys(meta).length > 0 ? { meta } : {}),
268
+ };
269
+ await this.persistPending(newPending);
270
+ this.pending = newPending;
271
+ }
272
+ else if ((args.name || args.description || args.image_url || args.services?.length) &&
273
+ JSON.stringify(this.pending.meta ?? {}) !== JSON.stringify(meta)) {
274
+ // Pending exists, user is updating draft — re-persist.
275
+ const updated = {
276
+ ...this.pending,
277
+ ...(Object.keys(meta).length > 0 ? { meta } : {}),
278
+ };
279
+ await this.persistPending(updated);
280
+ this.pending = updated;
281
+ }
282
+ return fundingRequiredResult({
283
+ executive: executive.pubkey,
284
+ network,
285
+ balanceLamports: balance,
286
+ requiredLamports: RECOMMENDED_FUND_LAMPORTS,
287
+ configPath: this.configPath,
288
+ imported: !!args.executive_secret_base58,
289
+ });
290
+ }
291
+ // Funded — proceed with mint + delegate + record. Use the
292
+ // merged meta so Step 2 picks up Step 1's name/services even
293
+ // when called with no arguments.
294
+ const minted = await mintAgentLocally({
295
+ executive,
296
+ network,
297
+ rpcUrl: this.defaults.rpcUrl,
298
+ apiBaseUrl: this.defaults.apiBaseUrl,
299
+ apiKey: this.defaults.apiKey,
300
+ ...(meta.name ? { name: meta.name } : {}),
301
+ ...(meta.description ? { description: meta.description } : {}),
302
+ ...(meta.imageUrl ? { imageUrl: meta.imageUrl } : {}),
303
+ ...(meta.services && meta.services.length > 0 ? { services: meta.services } : {}),
304
+ });
305
+ const finalConfig = {
306
+ agentMint: minted.mint,
307
+ executiveSecretBase58: executive.secretBase58,
308
+ network: minted.network,
309
+ apiBaseUrl: this.defaults.apiBaseUrl,
310
+ rpcUrl: this.defaults.rpcUrl,
311
+ explorerBaseUrl: this.defaults.explorerBaseUrl,
312
+ apiKey: this.defaults.apiKey,
313
+ };
314
+ let configWrittenTo = null;
315
+ try {
316
+ configWrittenTo = await writeAgentConfig({
317
+ config: finalConfig,
318
+ path: this.configPath,
319
+ });
320
+ }
321
+ catch (err) {
322
+ process.stderr.write(`[leash-mcp] warning: failed to persist ~/.config/leash/agent.json: ${err instanceof Error ? err.message : 'unknown'}\n`);
323
+ }
324
+ // Hot-swap. Subsequent tool calls hit the real signer + RPC.
325
+ this.inner = createStdioHost(finalConfig);
326
+ this.pending = null;
327
+ return jsonOk({
328
+ kind: 'register_agent',
329
+ status: 'ok',
330
+ agent_mint: minted.mint,
331
+ treasury_address: minted.treasury,
332
+ executive_pubkey: minted.executivePubkey,
333
+ network: minted.network,
334
+ tx_signatures: minted.txSignatures,
335
+ receipts_service_url: minted.receiptsServiceUrl,
336
+ config_written_to: configWrittenTo,
337
+ note: 'Agent provisioned and recorded. The in-memory MCP host is now bound to the new agent — settlement tools are ready to use without restarting. Executive secret persisted to the config file with chmod 600.',
338
+ });
339
+ }
340
+ catch (err) {
341
+ return jsonOk({
342
+ kind: 'register_agent',
343
+ status: 'error',
344
+ message: err instanceof Error ? err.message : 'unknown error',
345
+ });
346
+ }
347
+ }
348
+ // ── helpers ──
349
+ executiveFromPending(p) {
350
+ return {
351
+ secretBase58: p.executiveSecretBase58,
352
+ pubkey: p.executivePubkey,
353
+ };
354
+ }
355
+ async selectExecutive(args) {
356
+ if (args.mode === 'import') {
357
+ if (!args.executive_secret_base58) {
358
+ throw new Error('mode: "import" requires `executive_secret_base58` (64-byte ed25519 secret, base58-encoded)');
359
+ }
360
+ return importExecutive(args.executive_secret_base58);
361
+ }
362
+ // Default + explicit "generate" — fresh keypair.
363
+ return generateExecutive();
364
+ }
365
+ async persistPending(pending) {
366
+ try {
367
+ await writePendingRegister({
368
+ pending,
369
+ defaults: this.defaults,
370
+ path: this.configPath,
371
+ });
372
+ }
373
+ catch (err) {
374
+ process.stderr.write(`[leash-mcp] warning: failed to persist pending_register: ${err instanceof Error ? err.message : 'unknown'}\n`);
375
+ }
376
+ }
377
+ }
378
+ function jsonOk(payload) {
379
+ return {
380
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
381
+ };
382
+ }
383
+ function fundingRequiredResult(args) {
384
+ const need = args.requiredLamports - args.balanceLamports;
385
+ const networkLabel = args.network === 'solana-mainnet' ? 'mainnet' : 'devnet';
386
+ const faucetHint = args.network === 'solana-devnet'
387
+ ? 'Devnet SOL is free — request it via `solana airdrop 1 ' +
388
+ args.executive +
389
+ ' --url https://api.devnet.solana.com` (or any devnet faucet such as faucet.solana.com / quicknode.com/faucet/sol).'
390
+ : 'Mainnet SOL must be sent from a wallet you control. Any wallet works (Phantom / Backpack / a Solana CLI keypair).';
391
+ return jsonOk({
392
+ kind: 'register_agent',
393
+ status: 'funding_required',
394
+ network: args.network,
395
+ executive_pubkey: args.executive,
396
+ balance_lamports: args.balanceLamports.toString(),
397
+ balance_sol: lamportsToSol(args.balanceLamports),
398
+ required_lamports: args.requiredLamports.toString(),
399
+ required_sol: RECOMMENDED_FUND_SOL,
400
+ needed_lamports: (need > 0n ? need : 0n).toString(),
401
+ config_path: args.configPath,
402
+ keypair_source: args.imported ? 'imported' : 'generated',
403
+ instructions: [
404
+ `Send at least ${RECOMMENDED_FUND_SOL} SOL on ${networkLabel} to ${args.executive}.`,
405
+ `Funds rent (~0.005 SOL) for the agent asset + USDC delegation, plus a small buffer for tx fees.`,
406
+ faucetHint,
407
+ `Once funded, call \`leash_register_agent\` again WITH NO ARGUMENTS — the host will resume from the persisted keypair and finish minting.`,
408
+ `The keypair is already saved to ${args.configPath} (chmod 600). Do NOT delete that file before the second call or you'll lose access to the funded executive.`,
409
+ ],
410
+ });
411
+ }
412
+ // ────────────────────────────────────────────────────────────────────────────
413
+ // Placeholder host
414
+ // ────────────────────────────────────────────────────────────────────────────
415
+ /**
416
+ * Stand-in `LeashHost` used when no agent is configured. Settlement
417
+ * tools return a `no_agent` JSON blob via the host method, so the
418
+ * LLM sees a recoverable error and is prompted to call
419
+ * `leash_register_agent`. `registerAgent` itself is intercepted by
420
+ * `HostRef` so the placeholder never sees that call.
421
+ */
422
+ function makePlaceholderHost(defaults) {
423
+ const noAgent = (kind) => ({
424
+ content: [
425
+ {
426
+ type: 'text',
427
+ text: JSON.stringify({
428
+ kind,
429
+ status: 'no_agent',
430
+ message: 'No Leash agent configured. Call `leash_register_agent` to provision one (the tool will walk you through generating or importing an executive keypair, funding it with SOL, and minting on-chain). See https://docs.leash.market/agents/mcp for details.',
431
+ }),
432
+ },
433
+ ],
434
+ });
435
+ return {
436
+ agentMint: null,
437
+ ownerWallet: null,
438
+ network: defaults.network,
439
+ rpcUrl: defaults.rpcUrl,
440
+ apiBaseUrl: defaults.apiBaseUrl,
441
+ async createPaymentLink() {
442
+ return noAgent('payment_link');
443
+ },
444
+ async pay() {
445
+ return noAgent('payment_receipt');
446
+ },
447
+ async withdraw() {
448
+ return noAgent('withdraw_receipt');
449
+ },
450
+ async checkTreasuryBalance() {
451
+ return noAgent('treasury_balance');
452
+ },
453
+ async getIdentity() {
454
+ return noAgent('identity');
455
+ },
456
+ async receipts() {
457
+ return noAgent('receipts');
458
+ },
459
+ async registerAgent() {
460
+ // HostRef intercepts this call before it ever reaches us.
461
+ // Implementing it as a no_agent passthrough is purely defensive.
462
+ return noAgent('register_agent');
463
+ },
464
+ async discover(args) {
465
+ return fetchDiscover({
466
+ apiBaseUrl: defaults.apiBaseUrl,
467
+ network: defaults.network,
468
+ query: args,
469
+ });
470
+ },
471
+ async reputation(args) {
472
+ return fetchReputation({
473
+ apiBaseUrl: defaults.apiBaseUrl,
474
+ network: defaults.network,
475
+ query: args,
476
+ });
477
+ },
478
+ async paySkillsProvider(args) {
479
+ return fetchPaySkillsProvider({
480
+ apiBaseUrl: defaults.apiBaseUrl,
481
+ network: defaults.network,
482
+ query: args,
483
+ });
484
+ },
485
+ async setSpendLimit() {
486
+ return noAgent('spend_limit');
487
+ },
488
+ async getSpendLimit() {
489
+ return noAgent('spend_limit');
490
+ },
491
+ async getReceipt() {
492
+ return noAgent('receipt');
493
+ },
494
+ async transactionHistory() {
495
+ return noAgent('transaction_history');
496
+ },
497
+ async dailyTransactions() {
498
+ return noAgent('daily_transactions');
499
+ },
500
+ };
501
+ }
502
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}