@x402scan/mcp 0.0.3 → 0.0.4
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 +17 -14
- package/dist/cjs/run-server.cjs +1095 -347
- package/dist/esm/index.js +484 -94
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
package/dist/esm/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import z, { z as z$1 } from 'zod';
|
|
3
3
|
import { getAddress, createPublicClient, http, erc20Abi, formatUnits } from 'viem';
|
|
4
|
-
import fs4, { mkdirSync, appendFileSync } from 'fs';
|
|
5
4
|
import path2, { join } from 'path';
|
|
6
5
|
import os, { homedir } from 'os';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import fs__default, { appendFileSync } from 'fs';
|
|
7
8
|
import { polygon, arbitrum, optimism, sepolia, mainnet, baseSepolia, base } from 'viem/chains';
|
|
8
|
-
import { intro, outro, log as log$1, confirm, stream, spinner, select } from '@clack/prompts';
|
|
9
|
-
import
|
|
10
|
-
import
|
|
9
|
+
import { intro, outro, log as log$1, confirm, stream, spinner, select, text } from '@clack/prompts';
|
|
10
|
+
import { errAsync, ResultAsync, err } from 'neverthrow';
|
|
11
|
+
import chalk from 'chalk';
|
|
11
12
|
import open from 'open';
|
|
12
13
|
import { x402Client, x402HTTPClient } from '@x402/core/client';
|
|
13
14
|
import { ExactEvmScheme } from '@x402/evm/exact/client';
|
|
@@ -16,8 +17,9 @@ import { base58 } from '@scure/base';
|
|
|
16
17
|
import 'tweetnacl';
|
|
17
18
|
import { SiweMessage } from 'siwe';
|
|
18
19
|
import { safeBase64Encode } from '@x402/core/utils';
|
|
20
|
+
import 'url';
|
|
19
21
|
import { randomBytes } from 'crypto';
|
|
20
|
-
import * as
|
|
22
|
+
import * as fs3 from 'fs/promises';
|
|
21
23
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
22
24
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
23
25
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
@@ -91,6 +93,25 @@ var init_types = __esm({
|
|
|
91
93
|
"src/server/types.ts"() {
|
|
92
94
|
}
|
|
93
95
|
});
|
|
96
|
+
var BASE_DIRECTORY, configFile;
|
|
97
|
+
var init_fs = __esm({
|
|
98
|
+
"src/lib/fs.ts"() {
|
|
99
|
+
BASE_DIRECTORY = join(homedir(), ".x402scan-mcp");
|
|
100
|
+
if (!fs.existsSync(BASE_DIRECTORY)) {
|
|
101
|
+
fs.mkdirSync(BASE_DIRECTORY, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
configFile = (name) => {
|
|
104
|
+
if (!fs.existsSync(BASE_DIRECTORY)) {
|
|
105
|
+
fs.mkdirSync(BASE_DIRECTORY, { recursive: true });
|
|
106
|
+
}
|
|
107
|
+
const filePath = join(BASE_DIRECTORY, name);
|
|
108
|
+
if (!fs.existsSync(filePath)) {
|
|
109
|
+
fs.writeFileSync(filePath, "{}");
|
|
110
|
+
}
|
|
111
|
+
return filePath;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
});
|
|
94
115
|
function format(args) {
|
|
95
116
|
return args.map(
|
|
96
117
|
(a) => typeof a === "object" && a !== null ? JSON.stringify(a) : String(a)
|
|
@@ -108,16 +129,12 @@ function write(level, msg, args) {
|
|
|
108
129
|
console.error(`[x402scan] ${formatted}`);
|
|
109
130
|
}
|
|
110
131
|
}
|
|
111
|
-
var
|
|
132
|
+
var LOG_FILE, DEBUG, log;
|
|
112
133
|
var init_log = __esm({
|
|
113
134
|
"src/lib/log.ts"() {
|
|
114
|
-
|
|
115
|
-
LOG_FILE =
|
|
135
|
+
init_fs();
|
|
136
|
+
LOG_FILE = configFile("mcp.log");
|
|
116
137
|
DEBUG = process.env.X402_DEBUG === "true";
|
|
117
|
-
try {
|
|
118
|
-
mkdirSync(LOG_DIR, { recursive: true });
|
|
119
|
-
} catch {
|
|
120
|
-
}
|
|
121
138
|
log = {
|
|
122
139
|
info: (msg, ...args) => write("INFO", msg, args),
|
|
123
140
|
error: (msg, ...args) => write("ERROR", msg, args),
|
|
@@ -249,35 +266,207 @@ var init_wait = __esm({
|
|
|
249
266
|
};
|
|
250
267
|
}
|
|
251
268
|
});
|
|
252
|
-
|
|
269
|
+
function safeFetch(input, init) {
|
|
270
|
+
return ResultAsync.fromPromise(
|
|
271
|
+
fetch(input, init),
|
|
272
|
+
(error) => ({
|
|
273
|
+
type: "network",
|
|
274
|
+
message: "Network error",
|
|
275
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
276
|
+
})
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
var safeFetchJson;
|
|
280
|
+
var init_safe_fetch = __esm({
|
|
281
|
+
"src/lib/safe-fetch.ts"() {
|
|
282
|
+
safeFetchJson = (input, init, errorMessage) => {
|
|
283
|
+
return safeFetch(input, init).andThen((response) => {
|
|
284
|
+
if (!response.ok) {
|
|
285
|
+
return ResultAsync.fromSafePromise(
|
|
286
|
+
response.json().catch(() => void 0)
|
|
287
|
+
).andThen(
|
|
288
|
+
(json) => err({
|
|
289
|
+
type: "http",
|
|
290
|
+
message: json !== void 0 && errorMessage ? errorMessage(json) : response.statusText,
|
|
291
|
+
status: response.status,
|
|
292
|
+
headers: response.headers,
|
|
293
|
+
json
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
return ResultAsync.fromPromise(
|
|
298
|
+
response.json(),
|
|
299
|
+
(error) => ({
|
|
300
|
+
type: "parse",
|
|
301
|
+
message: "Could not parse JSON from response",
|
|
302
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
303
|
+
})
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// src/lib/utils.ts
|
|
311
|
+
var getBaseUrl;
|
|
312
|
+
var init_utils = __esm({
|
|
313
|
+
"src/lib/utils.ts"() {
|
|
314
|
+
getBaseUrl = (dev) => {
|
|
315
|
+
return dev ? "http://localhost:3000" : "https://x402scan.com";
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
var STATE_FILE, stateSchema, getState, setState;
|
|
320
|
+
var init_state = __esm({
|
|
321
|
+
"src/lib/state.ts"() {
|
|
322
|
+
init_fs();
|
|
323
|
+
init_log();
|
|
324
|
+
STATE_FILE = configFile("state.json");
|
|
325
|
+
stateSchema = z.looseObject({
|
|
326
|
+
redeemedCodes: z.array(z.string())
|
|
327
|
+
}).partial();
|
|
328
|
+
getState = () => {
|
|
329
|
+
if (!fs__default.existsSync(STATE_FILE)) {
|
|
330
|
+
fs__default.writeFileSync(STATE_FILE, JSON.stringify({}));
|
|
331
|
+
return {};
|
|
332
|
+
}
|
|
333
|
+
const result = stateSchema.safeParse(
|
|
334
|
+
JSON.parse(fs__default.readFileSync(STATE_FILE, "utf-8"))
|
|
335
|
+
);
|
|
336
|
+
if (!result.success) {
|
|
337
|
+
log.error("Failed to parse state", { error: result.error });
|
|
338
|
+
return {};
|
|
339
|
+
}
|
|
340
|
+
return result.data;
|
|
341
|
+
};
|
|
342
|
+
setState = (state) => {
|
|
343
|
+
const existing = getState();
|
|
344
|
+
const newState = stateSchema.parse({ ...existing, ...state });
|
|
345
|
+
fs__default.writeFileSync(STATE_FILE, JSON.stringify(newState, null, 2));
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
var redeemInviteCode;
|
|
350
|
+
var init_redeem_invite = __esm({
|
|
351
|
+
"src/lib/redeem-invite.ts"() {
|
|
352
|
+
init_safe_fetch();
|
|
353
|
+
init_utils();
|
|
354
|
+
init_state();
|
|
355
|
+
redeemInviteCode = async ({
|
|
356
|
+
code,
|
|
357
|
+
dev,
|
|
358
|
+
address
|
|
359
|
+
}) => {
|
|
360
|
+
const state = getState();
|
|
361
|
+
if (state.redeemedCodes?.includes(code)) {
|
|
362
|
+
return Promise.resolve(
|
|
363
|
+
errAsync({
|
|
364
|
+
success: false,
|
|
365
|
+
message: "This invite code has already been redeemed"
|
|
366
|
+
})
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
return await safeFetchJson(
|
|
370
|
+
`${getBaseUrl(dev)}/api/invite/redeem`,
|
|
371
|
+
{
|
|
372
|
+
method: "POST",
|
|
373
|
+
headers: {
|
|
374
|
+
"Content-Type": "application/json"
|
|
375
|
+
},
|
|
376
|
+
body: JSON.stringify({
|
|
377
|
+
code,
|
|
378
|
+
recipientAddr: address
|
|
379
|
+
})
|
|
380
|
+
},
|
|
381
|
+
({ message }) => message
|
|
382
|
+
).andTee((result) => {
|
|
383
|
+
if (result.success) {
|
|
384
|
+
setState({
|
|
385
|
+
redeemedCodes: [...state.redeemedCodes ?? [], code]
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
var getDepositLink, openDepositLink, redeemInviteCodePrompt, promptDeposit;
|
|
253
393
|
var init_deposit = __esm({
|
|
254
394
|
"src/lib/deposit.ts"() {
|
|
255
395
|
init_networks();
|
|
256
396
|
init_wait();
|
|
397
|
+
init_redeem_invite();
|
|
398
|
+
init_utils();
|
|
257
399
|
getDepositLink = (address, flags) => {
|
|
258
|
-
|
|
259
|
-
return `${baseUrl}/deposit/${address}`;
|
|
400
|
+
return `${getBaseUrl(flags.dev)}/deposit/${address}`;
|
|
260
401
|
};
|
|
261
402
|
openDepositLink = async (address, flags) => {
|
|
262
403
|
const depositLink = getDepositLink(address, flags);
|
|
263
404
|
await open(depositLink);
|
|
264
405
|
};
|
|
406
|
+
redeemInviteCodePrompt = async (address, flags) => {
|
|
407
|
+
const code = await text({
|
|
408
|
+
message: "Enter your invite code",
|
|
409
|
+
placeholder: "MRT-XXXXX",
|
|
410
|
+
validate: (value) => {
|
|
411
|
+
if (!value || value.trim().length === 0) {
|
|
412
|
+
return "Please enter an invite code";
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
if (typeof code !== "string") {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
const s = spinner();
|
|
420
|
+
s.start("Redeeming invite code...");
|
|
421
|
+
const result = await redeemInviteCode({ code, dev: flags.dev, address });
|
|
422
|
+
return result.match(
|
|
423
|
+
async ({ data: { amount, txHash } }) => {
|
|
424
|
+
s.stop("Invite code redeemed successfully!");
|
|
425
|
+
await wait({
|
|
426
|
+
startText: "Processing...",
|
|
427
|
+
stopText: chalk.green(
|
|
428
|
+
`${chalk.bold(amount)} USDC has been sent to your wallet!`
|
|
429
|
+
),
|
|
430
|
+
ms: 1500
|
|
431
|
+
});
|
|
432
|
+
log$1.success(
|
|
433
|
+
chalk.bold(`Your wallet has been funded with ${amount} USDC`)
|
|
434
|
+
);
|
|
435
|
+
if (txHash) {
|
|
436
|
+
log$1.info(chalk.dim(`Transaction: https://basescan.org/tx/${txHash}`));
|
|
437
|
+
}
|
|
438
|
+
return true;
|
|
439
|
+
},
|
|
440
|
+
(error) => {
|
|
441
|
+
s.stop("Invite code redemption failed");
|
|
442
|
+
log$1.warning(
|
|
443
|
+
chalk.yellow(`Failed to redeem invite code: ${error?.message}`)
|
|
444
|
+
);
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
};
|
|
265
449
|
promptDeposit = async (address, flags) => {
|
|
266
450
|
const depositLink = getDepositLink(address, flags);
|
|
267
|
-
const
|
|
268
|
-
message:
|
|
269
|
-
initialValue:
|
|
451
|
+
const depositChoice = await select({
|
|
452
|
+
message: chalk.bold("How would you like to deposit?"),
|
|
453
|
+
initialValue: "guided",
|
|
270
454
|
options: [
|
|
271
455
|
{
|
|
272
|
-
label:
|
|
273
|
-
value:
|
|
456
|
+
label: "Guided - Recommended",
|
|
457
|
+
value: "guided",
|
|
274
458
|
hint: "Online portal in x402scan"
|
|
275
459
|
},
|
|
276
460
|
{
|
|
277
461
|
label: "Manual",
|
|
278
|
-
value:
|
|
462
|
+
value: "manual",
|
|
279
463
|
hint: "Print deposit instructions"
|
|
280
464
|
},
|
|
465
|
+
{
|
|
466
|
+
label: "Redeem Invite Code",
|
|
467
|
+
value: "invite",
|
|
468
|
+
hint: "Enter an invite code for starter money"
|
|
469
|
+
},
|
|
281
470
|
{
|
|
282
471
|
label: "Skip",
|
|
283
472
|
value: void 0,
|
|
@@ -285,30 +474,24 @@ var init_deposit = __esm({
|
|
|
285
474
|
}
|
|
286
475
|
]
|
|
287
476
|
});
|
|
288
|
-
if (
|
|
477
|
+
if (depositChoice === "guided") {
|
|
289
478
|
await wait({
|
|
290
479
|
startText: "Opening deposit page...",
|
|
291
|
-
stopText: `Opening ${
|
|
480
|
+
stopText: `Opening ${chalk.underline.hex("#2563eb")(depositLink)}`,
|
|
292
481
|
ms: 1e3
|
|
293
482
|
});
|
|
294
483
|
await open(depositLink);
|
|
295
|
-
} else if (
|
|
296
|
-
log$1.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
borderColor: "#2563eb",
|
|
307
|
-
title: "Deposit Instructions",
|
|
308
|
-
padding: 1
|
|
309
|
-
}
|
|
310
|
-
)
|
|
311
|
-
);
|
|
484
|
+
} else if (depositChoice === "manual") {
|
|
485
|
+
log$1.step(chalk.bold("Account Information"));
|
|
486
|
+
log$1.message(`Address: ${address}`);
|
|
487
|
+
log$1.message(`Network: ${getChainName(DEFAULT_NETWORK)}`);
|
|
488
|
+
log$1.step(chalk.bold("Online Portal"));
|
|
489
|
+
log$1.message(`${chalk.underline(depositLink)}`);
|
|
490
|
+
} else if (depositChoice === "invite") {
|
|
491
|
+
const redeemed = await redeemInviteCodePrompt(address, flags);
|
|
492
|
+
if (!redeemed) {
|
|
493
|
+
await promptDeposit(address, flags);
|
|
494
|
+
}
|
|
312
495
|
}
|
|
313
496
|
};
|
|
314
497
|
}
|
|
@@ -355,6 +538,27 @@ You can deposit USDC at ${getDepositLink(address, flags)}`
|
|
|
355
538
|
};
|
|
356
539
|
}
|
|
357
540
|
});
|
|
541
|
+
|
|
542
|
+
// src/server/lib/parse-response.ts
|
|
543
|
+
var parseResponse;
|
|
544
|
+
var init_parse_response = __esm({
|
|
545
|
+
"src/server/lib/parse-response.ts"() {
|
|
546
|
+
parseResponse = async (response) => {
|
|
547
|
+
try {
|
|
548
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
549
|
+
if (contentType.includes("application/json")) {
|
|
550
|
+
return await response.json();
|
|
551
|
+
} else if (contentType.includes("image/")) {
|
|
552
|
+
return await response.arrayBuffer();
|
|
553
|
+
} else {
|
|
554
|
+
return await response.text();
|
|
555
|
+
}
|
|
556
|
+
} catch {
|
|
557
|
+
return void 0;
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
});
|
|
358
562
|
var registerFetchX402ResourceTool;
|
|
359
563
|
var init_fetch_x402_resource = __esm({
|
|
360
564
|
"src/server/tools/fetch-x402-resource.ts"() {
|
|
@@ -365,6 +569,7 @@ var init_fetch_x402_resource = __esm({
|
|
|
365
569
|
init_networks();
|
|
366
570
|
init_token();
|
|
367
571
|
init_check_balance();
|
|
572
|
+
init_parse_response();
|
|
368
573
|
registerFetchX402ResourceTool = ({
|
|
369
574
|
server,
|
|
370
575
|
account,
|
|
@@ -416,9 +621,8 @@ var init_fetch_x402_resource = __esm({
|
|
|
416
621
|
}
|
|
417
622
|
});
|
|
418
623
|
if (!response.ok) {
|
|
419
|
-
const errorData = await response.text();
|
|
420
624
|
const errorResponse = {
|
|
421
|
-
data:
|
|
625
|
+
data: await parseResponse(response),
|
|
422
626
|
statusCode: response.status,
|
|
423
627
|
state
|
|
424
628
|
};
|
|
@@ -441,11 +645,11 @@ var init_fetch_x402_resource = __esm({
|
|
|
441
645
|
};
|
|
442
646
|
const settlement = getSettlement();
|
|
443
647
|
return mcpSuccess({
|
|
444
|
-
data: await response
|
|
648
|
+
data: await parseResponse(response),
|
|
445
649
|
payment: settlement
|
|
446
650
|
});
|
|
447
|
-
} catch (
|
|
448
|
-
return mcpError(
|
|
651
|
+
} catch (err2) {
|
|
652
|
+
return mcpError(err2, { state });
|
|
449
653
|
}
|
|
450
654
|
}
|
|
451
655
|
);
|
|
@@ -835,8 +1039,8 @@ var init_auth = __esm({
|
|
|
835
1039
|
chainId: serverInfo.chainId
|
|
836
1040
|
}
|
|
837
1041
|
});
|
|
838
|
-
} catch (
|
|
839
|
-
return mcpError(
|
|
1042
|
+
} catch (err2) {
|
|
1043
|
+
return mcpError(err2, { tool: "authed_call", url });
|
|
840
1044
|
}
|
|
841
1045
|
}
|
|
842
1046
|
);
|
|
@@ -956,8 +1160,131 @@ var init_check_endpoint_schema = __esm({
|
|
|
956
1160
|
statusCode: response.status,
|
|
957
1161
|
routeDetails
|
|
958
1162
|
});
|
|
959
|
-
} catch (
|
|
960
|
-
return mcpError(
|
|
1163
|
+
} catch (err2) {
|
|
1164
|
+
return mcpError(err2, { tool: "query_endpoint", url });
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
var registerRedeemInviteTool;
|
|
1172
|
+
var init_redeem_invite2 = __esm({
|
|
1173
|
+
"src/server/tools/redeem-invite.ts"() {
|
|
1174
|
+
init_response();
|
|
1175
|
+
registerRedeemInviteTool = ({
|
|
1176
|
+
server,
|
|
1177
|
+
account: { address },
|
|
1178
|
+
flags
|
|
1179
|
+
}) => {
|
|
1180
|
+
const baseUrl = flags.dev ? "http://localhost:3000" : "https://x402scan.com";
|
|
1181
|
+
server.registerTool(
|
|
1182
|
+
"redeem_invite",
|
|
1183
|
+
{
|
|
1184
|
+
description: "Redeem an invite code to receive USDC.",
|
|
1185
|
+
inputSchema: z.object({
|
|
1186
|
+
code: z.string().min(1).describe("The invite code")
|
|
1187
|
+
})
|
|
1188
|
+
},
|
|
1189
|
+
async ({ code }) => {
|
|
1190
|
+
const res = await fetch(`${baseUrl}/api/invite/redeem`, {
|
|
1191
|
+
method: "POST",
|
|
1192
|
+
headers: { "Content-Type": "application/json" },
|
|
1193
|
+
body: JSON.stringify({ code, recipientAddr: address })
|
|
1194
|
+
});
|
|
1195
|
+
const data = await res.json();
|
|
1196
|
+
if (!data.success) {
|
|
1197
|
+
return mcpError(data.error ?? "Failed to redeem invite code");
|
|
1198
|
+
}
|
|
1199
|
+
return mcpSuccess({
|
|
1200
|
+
amount: `${data.amount} USDC`,
|
|
1201
|
+
txHash: data.txHash
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
);
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
function getVersion() {
|
|
1209
|
+
{
|
|
1210
|
+
return "0.0.4";
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
var MCP_VERSION;
|
|
1214
|
+
var init_version = __esm({
|
|
1215
|
+
"src/server/lib/version.ts"() {
|
|
1216
|
+
MCP_VERSION = getVersion();
|
|
1217
|
+
}
|
|
1218
|
+
});
|
|
1219
|
+
var errorReportSchema, registerTelemetryTools;
|
|
1220
|
+
var init_telemetry = __esm({
|
|
1221
|
+
"src/server/tools/telemetry.ts"() {
|
|
1222
|
+
init_log();
|
|
1223
|
+
init_response();
|
|
1224
|
+
init_version();
|
|
1225
|
+
errorReportSchema = z$1.object({
|
|
1226
|
+
tool: z$1.string().describe("MCP tool name"),
|
|
1227
|
+
resource: z$1.string().optional().describe("x402 resource URL"),
|
|
1228
|
+
summary: z$1.string().describe("1-2 sentence summary"),
|
|
1229
|
+
errorMessage: z$1.string().describe("Error message"),
|
|
1230
|
+
stack: z$1.string().optional().describe("Stack trace"),
|
|
1231
|
+
fullReport: z$1.string().optional().describe("Detailed report with context, logs, repro steps")
|
|
1232
|
+
});
|
|
1233
|
+
registerTelemetryTools = ({
|
|
1234
|
+
server,
|
|
1235
|
+
account: { address },
|
|
1236
|
+
flags
|
|
1237
|
+
}) => {
|
|
1238
|
+
const baseUrl = flags.dev ? "http://localhost:3000" : "https://x402scan.com";
|
|
1239
|
+
server.registerTool(
|
|
1240
|
+
"report_error",
|
|
1241
|
+
{
|
|
1242
|
+
description: "EMERGENCY ONLY. Report critical MCP tool bugs. Do NOT use for normal errors (balance, network, 4xx) - those are recoverable.",
|
|
1243
|
+
inputSchema: errorReportSchema
|
|
1244
|
+
},
|
|
1245
|
+
async (input) => {
|
|
1246
|
+
try {
|
|
1247
|
+
log.info("Submitting error report", {
|
|
1248
|
+
tool: input.tool,
|
|
1249
|
+
resource: input.resource,
|
|
1250
|
+
summary: input.summary
|
|
1251
|
+
});
|
|
1252
|
+
const report = {
|
|
1253
|
+
...input,
|
|
1254
|
+
walletAddress: address,
|
|
1255
|
+
mcpVersion: MCP_VERSION,
|
|
1256
|
+
reportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1257
|
+
};
|
|
1258
|
+
const response = await fetch(`${baseUrl}/api/telemetry`, {
|
|
1259
|
+
method: "POST",
|
|
1260
|
+
headers: {
|
|
1261
|
+
"Content-Type": "application/json"
|
|
1262
|
+
},
|
|
1263
|
+
body: JSON.stringify(report)
|
|
1264
|
+
});
|
|
1265
|
+
if (!response.ok) {
|
|
1266
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
1267
|
+
log.error("Failed to submit error report", {
|
|
1268
|
+
status: response.status,
|
|
1269
|
+
error: errorText
|
|
1270
|
+
});
|
|
1271
|
+
return mcpError(
|
|
1272
|
+
`Failed to submit error report: ${response.status} ${errorText}`,
|
|
1273
|
+
{ tool: "report_error" }
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
const result = await response.json();
|
|
1277
|
+
log.info("Error report submitted successfully", {
|
|
1278
|
+
reportId: result.reportId
|
|
1279
|
+
});
|
|
1280
|
+
return mcpSuccess({
|
|
1281
|
+
submitted: true,
|
|
1282
|
+
reportId: result.reportId,
|
|
1283
|
+
message: "Error report submitted successfully. The x402scan team will investigate."
|
|
1284
|
+
});
|
|
1285
|
+
} catch (err2) {
|
|
1286
|
+
log.error("Failed to submit error report", { error: err2 });
|
|
1287
|
+
return mcpError(err2, { tool: "report_error" });
|
|
961
1288
|
}
|
|
962
1289
|
}
|
|
963
1290
|
);
|
|
@@ -1100,7 +1427,7 @@ async function getWallet() {
|
|
|
1100
1427
|
return { account: account2, isNew: false };
|
|
1101
1428
|
}
|
|
1102
1429
|
try {
|
|
1103
|
-
const data = await
|
|
1430
|
+
const data = await fs3.readFile(WALLET_FILE, "utf-8");
|
|
1104
1431
|
const stored2 = storedWalletSchema.parse(JSON.parse(data));
|
|
1105
1432
|
const account2 = privateKeyToAccount(stored2.privateKey);
|
|
1106
1433
|
log.info(`Loaded wallet: ${account2.address}`);
|
|
@@ -1114,23 +1441,22 @@ async function getWallet() {
|
|
|
1114
1441
|
address: account.address,
|
|
1115
1442
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1116
1443
|
};
|
|
1117
|
-
await
|
|
1118
|
-
await fs.writeFile(KEYSTORE_FILE, JSON.stringify(stored, null, 2));
|
|
1444
|
+
await fs3.writeFile(WALLET_FILE, JSON.stringify(stored, null, 2));
|
|
1119
1445
|
try {
|
|
1120
|
-
await
|
|
1446
|
+
await fs3.chmod(WALLET_FILE, 384);
|
|
1121
1447
|
} catch {
|
|
1122
1448
|
}
|
|
1123
1449
|
log.info(`Created wallet: ${account.address}`);
|
|
1124
|
-
log.info(`Saved to: ${
|
|
1450
|
+
log.info(`Saved to: ${WALLET_FILE}`);
|
|
1125
1451
|
return { account, isNew: true };
|
|
1126
1452
|
}
|
|
1127
|
-
var
|
|
1453
|
+
var WALLET_FILE, storedWalletSchema;
|
|
1128
1454
|
var init_wallet2 = __esm({
|
|
1129
1455
|
"src/lib/wallet.ts"() {
|
|
1130
1456
|
init_log();
|
|
1131
1457
|
init_schemas();
|
|
1132
|
-
|
|
1133
|
-
|
|
1458
|
+
init_fs();
|
|
1459
|
+
WALLET_FILE = configFile("wallet.json");
|
|
1134
1460
|
storedWalletSchema = z.object({
|
|
1135
1461
|
privateKey: ethereumPrivateKeySchema,
|
|
1136
1462
|
address: ethereumAddressSchema,
|
|
@@ -1168,9 +1494,9 @@ async function lookupDnsTxtRecord(hostname) {
|
|
|
1168
1494
|
log.debug(`DNS TXT value is not a valid URL: ${txtValue}`);
|
|
1169
1495
|
return null;
|
|
1170
1496
|
}
|
|
1171
|
-
} catch (
|
|
1497
|
+
} catch (err2) {
|
|
1172
1498
|
log.debug(
|
|
1173
|
-
`DNS lookup error: ${
|
|
1499
|
+
`DNS lookup error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
1174
1500
|
);
|
|
1175
1501
|
return null;
|
|
1176
1502
|
}
|
|
@@ -1193,10 +1519,10 @@ async function fetchLlmsTxt(origin) {
|
|
|
1193
1519
|
return { found: false, error: "llms.txt is empty" };
|
|
1194
1520
|
}
|
|
1195
1521
|
return { found: true, content };
|
|
1196
|
-
} catch (
|
|
1522
|
+
} catch (err2) {
|
|
1197
1523
|
return {
|
|
1198
1524
|
found: false,
|
|
1199
|
-
error: `Network error: ${
|
|
1525
|
+
error: `Network error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
1200
1526
|
};
|
|
1201
1527
|
}
|
|
1202
1528
|
}
|
|
@@ -1233,10 +1559,10 @@ async function fetchDiscoveryFromUrl(url) {
|
|
|
1233
1559
|
};
|
|
1234
1560
|
}
|
|
1235
1561
|
return { found: true, document: parsed.data };
|
|
1236
|
-
} catch (
|
|
1562
|
+
} catch (err2) {
|
|
1237
1563
|
return {
|
|
1238
1564
|
found: false,
|
|
1239
|
-
error: `Network error: ${
|
|
1565
|
+
error: `Network error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
1240
1566
|
};
|
|
1241
1567
|
}
|
|
1242
1568
|
}
|
|
@@ -1328,11 +1654,11 @@ async function queryResource(url) {
|
|
|
1328
1654
|
resource.signInWithX = { required: true, info: siwx.info };
|
|
1329
1655
|
}
|
|
1330
1656
|
return resource;
|
|
1331
|
-
} catch (
|
|
1657
|
+
} catch (err2) {
|
|
1332
1658
|
return {
|
|
1333
1659
|
url,
|
|
1334
1660
|
isX402Endpoint: false,
|
|
1335
|
-
error:
|
|
1661
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
1336
1662
|
};
|
|
1337
1663
|
}
|
|
1338
1664
|
}
|
|
@@ -1366,7 +1692,7 @@ function registerDiscoveryTools(server) {
|
|
|
1366
1692
|
)
|
|
1367
1693
|
}
|
|
1368
1694
|
},
|
|
1369
|
-
async ({ url,
|
|
1695
|
+
async ({ url, fanOut, concurrency }) => {
|
|
1370
1696
|
try {
|
|
1371
1697
|
const origin = getOrigin(url);
|
|
1372
1698
|
log.info(`Discovering resources for origin: ${origin}`);
|
|
@@ -1400,7 +1726,7 @@ function registerDiscoveryTools(server) {
|
|
|
1400
1726
|
usage: "Use query_endpoint to get full pricing/requirements for a resource. Use execute_call (for payment) or authed_call (for SIWX auth) to call it.",
|
|
1401
1727
|
resources: []
|
|
1402
1728
|
};
|
|
1403
|
-
if (!
|
|
1729
|
+
if (!fanOut) {
|
|
1404
1730
|
result.resources = doc.resources.map((resourceUrl) => ({
|
|
1405
1731
|
url: resourceUrl
|
|
1406
1732
|
}));
|
|
@@ -1417,8 +1743,8 @@ function registerDiscoveryTools(server) {
|
|
|
1417
1743
|
}
|
|
1418
1744
|
result.resources = allResources;
|
|
1419
1745
|
return mcpSuccess(result);
|
|
1420
|
-
} catch (
|
|
1421
|
-
return mcpError(
|
|
1746
|
+
} catch (err2) {
|
|
1747
|
+
return mcpError(err2, { tool: "discover_resources", url });
|
|
1422
1748
|
}
|
|
1423
1749
|
}
|
|
1424
1750
|
);
|
|
@@ -1465,17 +1791,30 @@ var init_server = __esm({
|
|
|
1465
1791
|
init_auth();
|
|
1466
1792
|
init_wallet();
|
|
1467
1793
|
init_check_endpoint_schema();
|
|
1794
|
+
init_redeem_invite2();
|
|
1795
|
+
init_telemetry();
|
|
1468
1796
|
init_origins();
|
|
1469
1797
|
init_log();
|
|
1470
1798
|
init_wallet2();
|
|
1471
1799
|
init_discover_resources();
|
|
1800
|
+
init_redeem_invite();
|
|
1801
|
+
init_version();
|
|
1472
1802
|
startServer = async (flags) => {
|
|
1473
1803
|
log.info("Starting x402scan-mcp...");
|
|
1804
|
+
const { dev, invite } = flags;
|
|
1474
1805
|
const { account } = await getWallet();
|
|
1806
|
+
const code = invite ?? process.env.INVITE_CODE;
|
|
1807
|
+
if (code) {
|
|
1808
|
+
await redeemInviteCode({
|
|
1809
|
+
code,
|
|
1810
|
+
dev,
|
|
1811
|
+
address: account.address
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1475
1814
|
const server = new McpServer(
|
|
1476
1815
|
{
|
|
1477
1816
|
name: "@x402scan/mcp",
|
|
1478
|
-
version:
|
|
1817
|
+
version: MCP_VERSION,
|
|
1479
1818
|
websiteUrl: "https://x402scan.com/mcp",
|
|
1480
1819
|
icons: [{ src: "https://x402scan.com/logo.svg" }]
|
|
1481
1820
|
},
|
|
@@ -1497,7 +1836,9 @@ var init_server = __esm({
|
|
|
1497
1836
|
registerAuthTools(props);
|
|
1498
1837
|
registerWalletTools(props);
|
|
1499
1838
|
registerCheckX402EndpointTool(props);
|
|
1839
|
+
registerRedeemInviteTool(props);
|
|
1500
1840
|
registerDiscoveryTools(server);
|
|
1841
|
+
registerTelemetryTools(props);
|
|
1501
1842
|
await registerOrigins({ server, flags });
|
|
1502
1843
|
const transport = new StdioServerTransport();
|
|
1503
1844
|
await server.connect(transport);
|
|
@@ -1628,7 +1969,7 @@ var init_get_client = __esm({
|
|
|
1628
1969
|
if (parsedClientSelection.success) {
|
|
1629
1970
|
return parsedClientSelection.data;
|
|
1630
1971
|
}
|
|
1631
|
-
outro(
|
|
1972
|
+
outro(chalk.bold.red("No MCP client selected"));
|
|
1632
1973
|
process.exit(0);
|
|
1633
1974
|
};
|
|
1634
1975
|
}
|
|
@@ -1674,7 +2015,7 @@ var parseClientConfig, serializeClientConfig, stringifyObject;
|
|
|
1674
2015
|
var init_file_types = __esm({
|
|
1675
2016
|
"src/install/2-add-server/lib/file-types.ts"() {
|
|
1676
2017
|
parseClientConfig = ({ format: format2, path: path3 }) => {
|
|
1677
|
-
const fileContent =
|
|
2018
|
+
const fileContent = fs__default.readFileSync(path3, "utf8");
|
|
1678
2019
|
let config = {};
|
|
1679
2020
|
if (format2 === "yaml" /* YAML */) {
|
|
1680
2021
|
config = yaml.load(fileContent);
|
|
@@ -1851,7 +2192,7 @@ var init_client_config_file = __esm({
|
|
|
1851
2192
|
"opencode.json"
|
|
1852
2193
|
);
|
|
1853
2194
|
const jsoncPath = jsonPath.replace(".json", ".jsonc");
|
|
1854
|
-
if (
|
|
2195
|
+
if (fs__default.existsSync(jsoncPath)) {
|
|
1855
2196
|
log.info(`Found .jsonc file for OpenCode, using: ${jsoncPath}`);
|
|
1856
2197
|
return {
|
|
1857
2198
|
path: jsoncPath,
|
|
@@ -1914,7 +2255,7 @@ async function addServer(client, globalFlags) {
|
|
|
1914
2255
|
const { serverName, command, args } = getMcpConfig(globalFlags);
|
|
1915
2256
|
if (client === "warp" /* Warp */) {
|
|
1916
2257
|
log$1.info(
|
|
1917
|
-
|
|
2258
|
+
chalk.bold.yellow("Warp requires a manual installation through their UI.")
|
|
1918
2259
|
);
|
|
1919
2260
|
log$1.message(
|
|
1920
2261
|
"Please copy the following configuration object and add it to your Warp MCP config:"
|
|
@@ -1951,7 +2292,7 @@ async function addServer(client, globalFlags) {
|
|
|
1951
2292
|
let config = {};
|
|
1952
2293
|
let content = void 0;
|
|
1953
2294
|
log.info(`Checking if config file exists at: ${clientFileTarget.path}`);
|
|
1954
|
-
if (!
|
|
2295
|
+
if (!fs__default.existsSync(clientFileTarget.path)) {
|
|
1955
2296
|
log.info("Config file not found, creating default empty config");
|
|
1956
2297
|
setNestedValue(config, clientFileTarget.configKey, {});
|
|
1957
2298
|
log.info("Config created successfully");
|
|
@@ -1985,7 +2326,7 @@ async function addServer(client, globalFlags) {
|
|
|
1985
2326
|
if (!servers || typeof servers !== "object") {
|
|
1986
2327
|
log.error(`Invalid ${clientFileTarget.configKey} structure in config`);
|
|
1987
2328
|
log$1.error(
|
|
1988
|
-
|
|
2329
|
+
chalk.bold.red(
|
|
1989
2330
|
`Invalid ${clientFileTarget.configKey} structure in config`
|
|
1990
2331
|
)
|
|
1991
2332
|
);
|
|
@@ -2023,7 +2364,9 @@ async function addServer(client, globalFlags) {
|
|
|
2023
2364
|
};
|
|
2024
2365
|
}
|
|
2025
2366
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
2026
|
-
log$1.step(
|
|
2367
|
+
log$1.step(
|
|
2368
|
+
`The following will be added to ${chalk.bold.underline(clientFileTarget.path)}`
|
|
2369
|
+
);
|
|
2027
2370
|
const configStr = formatDiffByFormat(
|
|
2028
2371
|
{
|
|
2029
2372
|
[clientFileTarget.configKey]: {
|
|
@@ -2055,7 +2398,7 @@ async function addServer(client, globalFlags) {
|
|
|
2055
2398
|
inactive: "Cancel"
|
|
2056
2399
|
});
|
|
2057
2400
|
if (isConfirmed !== true) {
|
|
2058
|
-
outro(
|
|
2401
|
+
outro(chalk.bold.red("Installation cancelled"));
|
|
2059
2402
|
process.exit(0);
|
|
2060
2403
|
}
|
|
2061
2404
|
const configContent = serializeClientConfig(
|
|
@@ -2063,10 +2406,10 @@ async function addServer(client, globalFlags) {
|
|
|
2063
2406
|
config,
|
|
2064
2407
|
content
|
|
2065
2408
|
);
|
|
2066
|
-
|
|
2067
|
-
log$1.success(
|
|
2409
|
+
fs__default.writeFileSync(clientFileTarget.path, configContent);
|
|
2410
|
+
log$1.success(chalk.bold.green(`Added x402scan MCP to ${name}`));
|
|
2068
2411
|
} catch (e) {
|
|
2069
|
-
log$1.error(
|
|
2412
|
+
log$1.error(chalk.bold.red(`Error adding x402scan MCP to ${name}`));
|
|
2070
2413
|
throw e;
|
|
2071
2414
|
}
|
|
2072
2415
|
}
|
|
@@ -2100,7 +2443,7 @@ var init_add_server = __esm({
|
|
|
2100
2443
|
const diffLines = [0, 1, numLines - 2, numLines - 1];
|
|
2101
2444
|
const isDiffLine = !diffLines.includes(index);
|
|
2102
2445
|
if (isDiffLine) {
|
|
2103
|
-
return `${
|
|
2446
|
+
return `${chalk.bold.green(`+ ${line.slice(2)}`)}`;
|
|
2104
2447
|
}
|
|
2105
2448
|
return line;
|
|
2106
2449
|
}).join("\n");
|
|
@@ -2110,14 +2453,14 @@ var init_add_server = __esm({
|
|
|
2110
2453
|
const diffLines = [0, 1, str.length - 2, str.length - 1];
|
|
2111
2454
|
const isDiffLine = !diffLines.includes(index);
|
|
2112
2455
|
if (isDiffLine) {
|
|
2113
|
-
return `${
|
|
2456
|
+
return `${chalk.bold.green(`+ ${line.slice(2)}`)}`;
|
|
2114
2457
|
}
|
|
2115
2458
|
return line;
|
|
2116
2459
|
}).join("\n");
|
|
2117
2460
|
}
|
|
2118
2461
|
case "toml" /* TOML */: {
|
|
2119
2462
|
return str.split("\n").filter((line) => line.trim() !== "").map((line) => {
|
|
2120
|
-
return `${
|
|
2463
|
+
return `${chalk.bold.green(`+ ${line.trim()}`)}`;
|
|
2121
2464
|
}).join("\n");
|
|
2122
2465
|
}
|
|
2123
2466
|
}
|
|
@@ -2139,12 +2482,12 @@ var init_add_funds = __esm({
|
|
|
2139
2482
|
const balance = await getUSDCBalance({ address });
|
|
2140
2483
|
await wait({
|
|
2141
2484
|
startText: "Checking balance...",
|
|
2142
|
-
stopText: `Balance: ${
|
|
2485
|
+
stopText: `Balance: ${chalk.bold(`${balance} USDC`)} `,
|
|
2143
2486
|
ms: 1e3
|
|
2144
2487
|
});
|
|
2145
2488
|
if (balance < 1) {
|
|
2146
2489
|
log$1.warning(
|
|
2147
|
-
|
|
2490
|
+
chalk.bold(
|
|
2148
2491
|
`Your balance is low (${balance} USDC). Consider topping up.`
|
|
2149
2492
|
)
|
|
2150
2493
|
);
|
|
@@ -2154,6 +2497,41 @@ var init_add_funds = __esm({
|
|
|
2154
2497
|
};
|
|
2155
2498
|
}
|
|
2156
2499
|
});
|
|
2500
|
+
var redeemInviteCode2;
|
|
2501
|
+
var init_redeem_invite3 = __esm({
|
|
2502
|
+
"src/install/4-redeem-invite/index.ts"() {
|
|
2503
|
+
init_wait();
|
|
2504
|
+
init_redeem_invite();
|
|
2505
|
+
redeemInviteCode2 = async (props) => {
|
|
2506
|
+
const s = spinner();
|
|
2507
|
+
s.start("Redeeming invite code...");
|
|
2508
|
+
const result = await redeemInviteCode(props);
|
|
2509
|
+
return result.match(
|
|
2510
|
+
async ({ data }) => {
|
|
2511
|
+
s.stop("Invite code redeemed successfully!");
|
|
2512
|
+
await wait({
|
|
2513
|
+
startText: "Processing...",
|
|
2514
|
+
stopText: chalk.green(
|
|
2515
|
+
`${chalk.bold(data.amount)} USDC has been sent to your wallet!`
|
|
2516
|
+
),
|
|
2517
|
+
ms: 1e3
|
|
2518
|
+
});
|
|
2519
|
+
log$1.info(
|
|
2520
|
+
chalk.dim(`Transaction: https://basescan.org/tx/${data.txHash}`)
|
|
2521
|
+
);
|
|
2522
|
+
return true;
|
|
2523
|
+
},
|
|
2524
|
+
(error) => {
|
|
2525
|
+
s.stop("Invite code redemption failed");
|
|
2526
|
+
log$1.warning(
|
|
2527
|
+
chalk.yellow(`Failed to redeem invite code: ${error?.message}`)
|
|
2528
|
+
);
|
|
2529
|
+
return false;
|
|
2530
|
+
}
|
|
2531
|
+
);
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2534
|
+
});
|
|
2157
2535
|
|
|
2158
2536
|
// src/install/index.ts
|
|
2159
2537
|
var install_exports = {};
|
|
@@ -2167,16 +2545,24 @@ var init_install = __esm({
|
|
|
2167
2545
|
init_get_client();
|
|
2168
2546
|
init_add_server();
|
|
2169
2547
|
init_add_funds();
|
|
2548
|
+
init_redeem_invite3();
|
|
2170
2549
|
installMcpServer = async (flags) => {
|
|
2171
2550
|
const {
|
|
2172
2551
|
account: { address },
|
|
2173
2552
|
isNew
|
|
2174
2553
|
} = await getWallet();
|
|
2175
|
-
intro(
|
|
2554
|
+
intro(chalk.green.bold(`Install x402scan MCP`));
|
|
2176
2555
|
const client = await getClient(flags);
|
|
2177
2556
|
await addServer(client, flags);
|
|
2178
|
-
|
|
2179
|
-
|
|
2557
|
+
const inviteRedeemed = flags.invite ? await redeemInviteCode2({
|
|
2558
|
+
code: flags.invite,
|
|
2559
|
+
dev: flags.dev,
|
|
2560
|
+
address
|
|
2561
|
+
}) : false;
|
|
2562
|
+
if (!inviteRedeemed) {
|
|
2563
|
+
await addFunds({ flags, address, isNew });
|
|
2564
|
+
}
|
|
2565
|
+
outro(chalk.bold.green("Your x402scan MCP server is ready to use!"));
|
|
2180
2566
|
};
|
|
2181
2567
|
}
|
|
2182
2568
|
});
|
|
@@ -2192,12 +2578,12 @@ var init_fund = __esm({
|
|
|
2192
2578
|
init_wallet2();
|
|
2193
2579
|
init_deposit();
|
|
2194
2580
|
fundMcpServer = async (flags) => {
|
|
2195
|
-
intro(
|
|
2581
|
+
intro(chalk.bold(`Fund ${chalk.hex("#2563eb")("x402scan MCP")}`));
|
|
2196
2582
|
const {
|
|
2197
2583
|
account: { address }
|
|
2198
2584
|
} = await getWallet();
|
|
2199
2585
|
await promptDeposit(address, flags);
|
|
2200
|
-
outro(
|
|
2586
|
+
outro(chalk.bold.green("Your x402scan MCP server is funded!"));
|
|
2201
2587
|
};
|
|
2202
2588
|
}
|
|
2203
2589
|
});
|
|
@@ -2205,6 +2591,10 @@ void yargs(hideBin(process.argv)).scriptName("@x402scan/mcp").option("dev", {
|
|
|
2205
2591
|
type: "boolean",
|
|
2206
2592
|
description: "Enable dev mode",
|
|
2207
2593
|
default: false
|
|
2594
|
+
}).option("invite", {
|
|
2595
|
+
type: "string",
|
|
2596
|
+
description: "Invite code to redeem for starter money",
|
|
2597
|
+
required: false
|
|
2208
2598
|
}).command(
|
|
2209
2599
|
"$0",
|
|
2210
2600
|
"Start the MCP server",
|
|
@@ -2223,7 +2613,7 @@ void yargs(hideBin(process.argv)).scriptName("@x402scan/mcp").option("dev", {
|
|
|
2223
2613
|
}),
|
|
2224
2614
|
async (args) => {
|
|
2225
2615
|
const { installMcpServer: installMcpServer2 } = await Promise.resolve().then(() => (init_install(), install_exports));
|
|
2226
|
-
await installMcpServer2(
|
|
2616
|
+
await installMcpServer2(args);
|
|
2227
2617
|
}
|
|
2228
2618
|
).command(
|
|
2229
2619
|
"fund",
|
|
@@ -2233,8 +2623,8 @@ void yargs(hideBin(process.argv)).scriptName("@x402scan/mcp").option("dev", {
|
|
|
2233
2623
|
const { fundMcpServer: fundMcpServer2 } = await Promise.resolve().then(() => (init_fund(), fund_exports));
|
|
2234
2624
|
await fundMcpServer2(args);
|
|
2235
2625
|
}
|
|
2236
|
-
).strict().demandCommand(0, 1, "", "Too many commands provided").help().parseAsync().catch((
|
|
2237
|
-
console.error("Fatal:",
|
|
2626
|
+
).strict().demandCommand(0, 1, "", "Too many commands provided").help().parseAsync().catch((err2) => {
|
|
2627
|
+
console.error("Fatal:", err2);
|
|
2238
2628
|
process.exit(1);
|
|
2239
2629
|
});
|
|
2240
2630
|
//# sourceMappingURL=index.js.map
|