@agentwonderland/mcp 0.1.41 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/__tests__/api-client.test.js +1 -1
- package/dist/core/__tests__/setup.test.js +3 -3
- package/dist/core/api-client.js +2 -2
- package/dist/core/ows-adapter.js +58 -3
- package/dist/core/payments.js +52 -41
- package/dist/core/version.d.ts +1 -0
- package/dist/core/version.js +1 -0
- package/dist/index.js +3 -3
- package/dist/setup.js +2 -2
- package/dist/tools/wallet.js +19 -1
- package/package.json +2 -1
- package/src/core/__tests__/api-client.test.ts +1 -1
- package/src/core/__tests__/setup.test.ts +3 -3
- package/src/core/api-client.ts +2 -3
- package/src/core/ows-adapter.ts +67 -3
- package/src/core/payments.ts +52 -40
- package/src/core/version.ts +1 -0
- package/src/index.ts +3 -4
- package/src/setup.ts +2 -2
- package/src/tools/wallet.ts +24 -6
|
@@ -46,7 +46,7 @@ describe("api-client headers", () => {
|
|
|
46
46
|
"X-AW-Consumer-Principal": "did:pkh:solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:42W2HfLfveSm1T5et9WTLp2CZ2QXdF2EYCUvyJ2gPpxF",
|
|
47
47
|
"X-AW-Rebate-Principal": "did:pkh:eip155:8453:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
48
48
|
"X-AW-Surface": "mcp",
|
|
49
|
-
"X-AW-MCP-Version": "0.1.
|
|
49
|
+
"X-AW-MCP-Version": "0.1.43",
|
|
50
50
|
"X-AW-MCP-Tool": "run_agent",
|
|
51
51
|
"X-AW-MCP-Action": "execute",
|
|
52
52
|
}),
|
|
@@ -20,7 +20,7 @@ describe("MCP setup", () => {
|
|
|
20
20
|
expect(next.mcpServers.existing.command).toBe("node");
|
|
21
21
|
expect(next.mcpServers.agentwonderland).toEqual({
|
|
22
22
|
command: "npx",
|
|
23
|
-
args: ["-y", "@agentwonderland/mcp"],
|
|
23
|
+
args: ["-y", "@agentwonderland/mcp@latest"],
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
it("replaces an existing Codex TOML block without disturbing other servers", () => {
|
|
@@ -40,7 +40,7 @@ describe("MCP setup", () => {
|
|
|
40
40
|
expect(next).toContain("[mcp_servers.other]");
|
|
41
41
|
expect(next).toContain("[mcp_servers.agentwonderland]");
|
|
42
42
|
expect(next).toContain('command = "npx"');
|
|
43
|
-
expect(next).toContain('args = ["-y", "@agentwonderland/mcp"]');
|
|
43
|
+
expect(next).toContain('args = ["-y", "@agentwonderland/mcp@latest"]');
|
|
44
44
|
expect(next).not.toContain('command = "old"');
|
|
45
45
|
expect(next).toContain("[model_provider.openai]");
|
|
46
46
|
});
|
|
@@ -61,7 +61,7 @@ describe("MCP setup", () => {
|
|
|
61
61
|
const written = JSON.parse(await readFile(configPath, "utf8"));
|
|
62
62
|
expect(result.status).toBe("updated");
|
|
63
63
|
expect(result.backupPath).toBeTruthy();
|
|
64
|
-
expect(written.mcpServers.agentwonderland.args).toEqual(["-y", "@agentwonderland/mcp"]);
|
|
64
|
+
expect(written.mcpServers.agentwonderland.args).toEqual(["-y", "@agentwonderland/mcp@latest"]);
|
|
65
65
|
});
|
|
66
66
|
it("parses client selection flags", () => {
|
|
67
67
|
expect(parseSetupArgs(["--clients", "codex,cursor", "--yes"])).toEqual({
|
package/dist/core/api-client.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getApiUrl, getApiKey } from "./config.js";
|
|
2
2
|
import { getPaymentFetch } from "./payments.js";
|
|
3
3
|
import { getBaseRebatePrincipal, ensureConsumerPrincipalForMethod, getConsumerPrincipalForMethod, } from "./principal.js";
|
|
4
|
+
import { MCP_PACKAGE_VERSION } from "./version.js";
|
|
4
5
|
// ── Error class ────────────────────────────────────────────────────
|
|
5
6
|
export class ApiError extends Error {
|
|
6
7
|
status;
|
|
@@ -12,7 +13,6 @@ export class ApiError extends Error {
|
|
|
12
13
|
this.name = "ApiError";
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
const MCP_VERSION = "0.1.41";
|
|
16
16
|
function inferToolHeaders(path, method) {
|
|
17
17
|
if (path === "/solve") {
|
|
18
18
|
return { "X-AW-MCP-Tool": "solve", "X-AW-MCP-Action": method === "POST" ? "execute" : "view" };
|
|
@@ -36,7 +36,7 @@ async function buildHeaders(path, method, options) {
|
|
|
36
36
|
"Content-Type": "application/json",
|
|
37
37
|
Accept: "application/json",
|
|
38
38
|
"X-AW-Surface": "mcp",
|
|
39
|
-
"X-AW-MCP-Version":
|
|
39
|
+
"X-AW-MCP-Version": MCP_PACKAGE_VERSION,
|
|
40
40
|
...inferToolHeaders(path, method),
|
|
41
41
|
};
|
|
42
42
|
const apiKey = getApiKey();
|
package/dist/core/ows-adapter.js
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* The OWS SDK (`@open-wallet-standard/core`) is a NAPI native module.
|
|
8
8
|
* ALL imports are dynamic so the MCP server works without OWS installed.
|
|
9
9
|
*/
|
|
10
|
+
import { createHmac } from "node:crypto";
|
|
11
|
+
import { mnemonicToSeedSync, validateMnemonic } from "@scure/bip39";
|
|
12
|
+
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
10
13
|
// ── Helpers ──────────────────────────────────────────────────────
|
|
11
14
|
const OWS_INSTALL_HINT = "OWS is not installed. Install with: npm install -g @open-wallet-standard/core";
|
|
12
15
|
async function loadOws() {
|
|
@@ -58,6 +61,51 @@ function keypairFromEd25519Hex(privateKeyHex, KeypairCtor) {
|
|
|
58
61
|
}
|
|
59
62
|
throw new Error(`Unsupported ed25519 key length: ${bytes.length} bytes.`);
|
|
60
63
|
}
|
|
64
|
+
function parseExportedSecret(exported) {
|
|
65
|
+
const secret = exported.trim();
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(secret);
|
|
68
|
+
if (parsed.secp256k1 || parsed.ed25519 || parsed.mnemonic)
|
|
69
|
+
return parsed;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// OWS-created wallets export a BIP-39 mnemonic, not a JSON key object.
|
|
73
|
+
}
|
|
74
|
+
const hex = secret.startsWith("0x") ? secret.slice(2) : secret;
|
|
75
|
+
if (/^[0-9a-fA-F]+$/.test(hex)) {
|
|
76
|
+
if (hex.length === 64)
|
|
77
|
+
return { secp256k1: hex, ed25519: hex };
|
|
78
|
+
if (hex.length === 128)
|
|
79
|
+
return { ed25519: hex };
|
|
80
|
+
}
|
|
81
|
+
if (validateMnemonic(secret, wordlist)) {
|
|
82
|
+
return { mnemonic: secret };
|
|
83
|
+
}
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
function deriveSolanaSeedFromMnemonic(mnemonic, path = "m/44'/501'/0'/0'") {
|
|
87
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
88
|
+
let digest = createHmac("sha512", "ed25519 seed").update(seed).digest();
|
|
89
|
+
let key = digest.subarray(0, 32);
|
|
90
|
+
let chainCode = digest.subarray(32);
|
|
91
|
+
for (const part of path.split("/").slice(1)) {
|
|
92
|
+
if (!part.endsWith("'")) {
|
|
93
|
+
throw new Error(`Unsupported non-hardened ed25519 path segment: ${part}`);
|
|
94
|
+
}
|
|
95
|
+
const index = Number(part.slice(0, -1));
|
|
96
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
97
|
+
throw new Error(`Unsupported ed25519 path segment: ${part}`);
|
|
98
|
+
}
|
|
99
|
+
const data = Buffer.alloc(37);
|
|
100
|
+
data[0] = 0;
|
|
101
|
+
Buffer.from(key).copy(data, 1);
|
|
102
|
+
data.writeUInt32BE(index + 0x80000000, 33);
|
|
103
|
+
digest = createHmac("sha512", chainCode).update(data).digest();
|
|
104
|
+
key = digest.subarray(0, 32);
|
|
105
|
+
chainCode = digest.subarray(32);
|
|
106
|
+
}
|
|
107
|
+
return Uint8Array.from(key);
|
|
108
|
+
}
|
|
61
109
|
// ── Public API ───────────────────────────────────────────────────
|
|
62
110
|
/**
|
|
63
111
|
* Check whether the OWS native module can be loaded.
|
|
@@ -160,7 +208,11 @@ export async function owsAccountFromWalletId(walletId, _chain) {
|
|
|
160
208
|
// (EIP-5806 delegate calls) which OWS's native signing can't serialize.
|
|
161
209
|
// OWS provides encrypted storage at rest; viem handles signing in memory.
|
|
162
210
|
const exported = ows.exportWallet(walletId);
|
|
163
|
-
const keys =
|
|
211
|
+
const keys = parseExportedSecret(exported);
|
|
212
|
+
if (keys.mnemonic) {
|
|
213
|
+
const { mnemonicToAccount } = await import("viem/accounts");
|
|
214
|
+
return mnemonicToAccount(keys.mnemonic);
|
|
215
|
+
}
|
|
164
216
|
if (!keys.secp256k1) {
|
|
165
217
|
throw new Error(`Wallet "${wallet.name}" has no secp256k1 key for EVM signing.`);
|
|
166
218
|
}
|
|
@@ -172,11 +224,14 @@ export async function owsSolanaKeypairFromWalletId(walletId) {
|
|
|
172
224
|
const wallet = ows.getWallet(walletId);
|
|
173
225
|
findSolanaAccount(wallet);
|
|
174
226
|
const exported = ows.exportWallet(walletId);
|
|
175
|
-
const keys =
|
|
227
|
+
const keys = parseExportedSecret(exported);
|
|
228
|
+
const { Keypair } = await import("@solana/web3.js");
|
|
229
|
+
if (keys.mnemonic) {
|
|
230
|
+
return Keypair.fromSeed(deriveSolanaSeedFromMnemonic(keys.mnemonic));
|
|
231
|
+
}
|
|
176
232
|
if (!keys.ed25519) {
|
|
177
233
|
throw new Error(`Wallet "${wallet.name}" has no ed25519 key for Solana signing.`);
|
|
178
234
|
}
|
|
179
|
-
const { Keypair } = await import("@solana/web3.js");
|
|
180
235
|
return keypairFromEd25519Hex(keys.ed25519, Keypair);
|
|
181
236
|
}
|
|
182
237
|
export async function getOwsWalletAddress(walletId, chain = "evm") {
|
package/dist/core/payments.js
CHANGED
|
@@ -53,52 +53,42 @@ function clearStaleCardCache(activeKey) {
|
|
|
53
53
|
}
|
|
54
54
|
// ── Per-protocol initializers ───────────────────────────────────
|
|
55
55
|
async function initEvmMppForChain(wallet, chain) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
account = await owsAccountFromWalletId(wallet.owsWalletId);
|
|
62
|
-
}
|
|
63
|
-
else if (wallet.key) {
|
|
64
|
-
const { privateKeyToAccount } = await import("viem/accounts");
|
|
65
|
-
account = privateKeyToAccount(normalizeKey(wallet.key));
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
const methods = [];
|
|
71
|
-
if (chain === "tempo") {
|
|
72
|
-
const { tempoChargeClient } = await import("./tempo-charge.js");
|
|
73
|
-
methods.push(tempoChargeClient({ account }));
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
const { baseChargeClient } = await import("./base-charge.js");
|
|
77
|
-
methods.push(baseChargeClient({ account }));
|
|
78
|
-
}
|
|
79
|
-
const mppx = Mppx.create({ methods: methods, polyfill: false });
|
|
80
|
-
return mppx.fetch.bind(mppx);
|
|
56
|
+
const { Mppx } = await import("./mpp-client.js");
|
|
57
|
+
let account;
|
|
58
|
+
if (wallet.keyType === "ows" && wallet.owsWalletId) {
|
|
59
|
+
const { owsAccountFromWalletId } = await import("./ows-adapter.js");
|
|
60
|
+
account = await owsAccountFromWalletId(wallet.owsWalletId);
|
|
81
61
|
}
|
|
82
|
-
|
|
62
|
+
else if (wallet.key) {
|
|
63
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
64
|
+
account = privateKeyToAccount(normalizeKey(wallet.key));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
83
67
|
return null;
|
|
84
68
|
}
|
|
69
|
+
const methods = [];
|
|
70
|
+
if (chain === "tempo") {
|
|
71
|
+
const { tempoChargeClient } = await import("./tempo-charge.js");
|
|
72
|
+
methods.push(tempoChargeClient({ account }));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const { baseChargeClient } = await import("./base-charge.js");
|
|
76
|
+
methods.push(baseChargeClient({ account }));
|
|
77
|
+
}
|
|
78
|
+
const mppx = Mppx.create({ methods: methods, polyfill: false });
|
|
79
|
+
return mppx.fetch.bind(mppx);
|
|
85
80
|
}
|
|
86
81
|
async function initSolanaMpp(wallet) {
|
|
87
|
-
|
|
88
|
-
if (wallet.keyType !== "ows" && !wallet.key) {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
const { Mppx } = await import("./mpp-client.js");
|
|
92
|
-
const { solanaChargeClient } = await import("./solana-charge.js");
|
|
93
|
-
const mppx = Mppx.create({
|
|
94
|
-
methods: [solanaChargeClient({ wallet })],
|
|
95
|
-
polyfill: false,
|
|
96
|
-
});
|
|
97
|
-
return mppx.fetch.bind(mppx);
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
82
|
+
if (wallet.keyType !== "ows" && !wallet.key) {
|
|
100
83
|
return null;
|
|
101
84
|
}
|
|
85
|
+
const { Mppx } = await import("./mpp-client.js");
|
|
86
|
+
const { solanaChargeClient } = await import("./solana-charge.js");
|
|
87
|
+
const mppx = Mppx.create({
|
|
88
|
+
methods: [solanaChargeClient({ wallet })],
|
|
89
|
+
polyfill: false,
|
|
90
|
+
});
|
|
91
|
+
return mppx.fetch.bind(mppx);
|
|
102
92
|
}
|
|
103
93
|
async function initCard() {
|
|
104
94
|
const cardConfig = getCardConfig();
|
|
@@ -149,6 +139,10 @@ async function initForChain(wallet, chain) {
|
|
|
149
139
|
}
|
|
150
140
|
return null;
|
|
151
141
|
}
|
|
142
|
+
function initFailureMessage(method, wallet, chain, err) {
|
|
143
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
144
|
+
return `Payment method "${method}" is configured as ${chain} on wallet "${wallet.id}", but the signer could not initialize: ${reason}`;
|
|
145
|
+
}
|
|
152
146
|
// ── Public API ──────────────────────────────────────────────────
|
|
153
147
|
/**
|
|
154
148
|
* Returns a payment-aware fetch for a specific method, or the best
|
|
@@ -185,7 +179,13 @@ export async function getPaymentFetch(method) {
|
|
|
185
179
|
const ck = cacheKey(resolved.wallet.id, resolved.chain);
|
|
186
180
|
if (fetchCache.has(ck))
|
|
187
181
|
return fetchCache.get(ck);
|
|
188
|
-
|
|
182
|
+
let pf;
|
|
183
|
+
try {
|
|
184
|
+
pf = await initForChain(resolved.wallet, resolved.chain);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
throw new Error(initFailureMessage(method, resolved.wallet, resolved.chain, err));
|
|
188
|
+
}
|
|
189
189
|
if (pf) {
|
|
190
190
|
fetchCache.set(ck, pf);
|
|
191
191
|
return pf;
|
|
@@ -234,7 +234,18 @@ export async function getPaymentFetch(method) {
|
|
|
234
234
|
const ck = cacheKey(resolved.wallet.id, resolved.chain);
|
|
235
235
|
if (fetchCache.has(ck))
|
|
236
236
|
return fetchCache.get(ck);
|
|
237
|
-
|
|
237
|
+
let pf;
|
|
238
|
+
try {
|
|
239
|
+
pf = await initForChain(resolved.wallet, resolved.chain);
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
if (m === defaultMethod) {
|
|
243
|
+
const others = configured.filter((x) => x !== m);
|
|
244
|
+
const altText = others.length > 0 ? ` Alternatives: ${others.join(", ")}` : "";
|
|
245
|
+
throw new Error(`${initFailureMessage(m, resolved.wallet, resolved.chain, err)}.${altText}`);
|
|
246
|
+
}
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
238
249
|
if (pf) {
|
|
239
250
|
fetchCache.set(ck, pf);
|
|
240
251
|
return pf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MCP_PACKAGE_VERSION = "0.1.43";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MCP_PACKAGE_VERSION = "0.1.43";
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { registerJobResources } from "./resources/jobs.js";
|
|
|
22
22
|
// ── Prompts ──────────────────────────────────────────────────────
|
|
23
23
|
import { registerPrompts } from "./prompts/index.js";
|
|
24
24
|
import { runSetupCli } from "./setup.js";
|
|
25
|
-
|
|
25
|
+
import { MCP_PACKAGE_VERSION } from "./core/version.js";
|
|
26
26
|
export async function startMcpServer() {
|
|
27
27
|
const server = new McpServer({
|
|
28
28
|
name: "agentwonderland",
|
|
@@ -115,7 +115,7 @@ if (isCli) {
|
|
|
115
115
|
"in a terminal it waits silently for MCP JSON-RPC messages on stdin.",
|
|
116
116
|
"",
|
|
117
117
|
"MCP client config:",
|
|
118
|
-
' { "mcpServers": { "agentwonderland": { "command": "npx", "args": ["-y", "@agentwonderland/mcp"] } } }',
|
|
118
|
+
' { "mcpServers": { "agentwonderland": { "command": "npx", "args": ["-y", "@agentwonderland/mcp@latest"] } } }',
|
|
119
119
|
"",
|
|
120
120
|
"Options:",
|
|
121
121
|
" -h, --help Show this help",
|
|
@@ -124,7 +124,7 @@ if (isCli) {
|
|
|
124
124
|
process.exit(0);
|
|
125
125
|
}
|
|
126
126
|
else if (args.includes("--version") || args.includes("-v")) {
|
|
127
|
-
console.log(
|
|
127
|
+
console.log(MCP_PACKAGE_VERSION);
|
|
128
128
|
process.exit(0);
|
|
129
129
|
}
|
|
130
130
|
else {
|
package/dist/setup.js
CHANGED
|
@@ -8,7 +8,7 @@ import { execFileSync } from "node:child_process";
|
|
|
8
8
|
export const SERVER_NAME = "agentwonderland";
|
|
9
9
|
export const SERVER_CONFIG = {
|
|
10
10
|
command: "npx",
|
|
11
|
-
args: ["-y", "@agentwonderland/mcp"],
|
|
11
|
+
args: ["-y", "@agentwonderland/mcp@latest"],
|
|
12
12
|
};
|
|
13
13
|
const CLIENT_ORDER = [
|
|
14
14
|
"codex",
|
|
@@ -272,7 +272,7 @@ export function mergeCodexTomlConfig(existing) {
|
|
|
272
272
|
const block = [
|
|
273
273
|
`[mcp_servers.${SERVER_NAME}]`,
|
|
274
274
|
`command = "npx"`,
|
|
275
|
-
`args = ["-y", "@agentwonderland/mcp"]`,
|
|
275
|
+
`args = ["-y", "@agentwonderland/mcp@latest"]`,
|
|
276
276
|
"",
|
|
277
277
|
].join("\n");
|
|
278
278
|
const pattern = new RegExp(`\\n?\\[mcp_servers\\.${SERVER_NAME.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\][\\s\\S]*?(?=\\n\\[[^\\]]+\\]|$)`);
|
package/dist/tools/wallet.js
CHANGED
|
@@ -6,6 +6,7 @@ import { getSettings } from "../core/settings.js";
|
|
|
6
6
|
import { getOrCreatePendingCardSetup, formatCardSetupBlocks, getCardCapabilities, pollCardSetup, } from "../core/card-setup.js";
|
|
7
7
|
import { isOwsAvailable, createOwsWallet, importKeyToOws, listOwsWallets, listOwsWalletsByChain, installOws, platformSupportsOws, } from "../core/ows-adapter.js";
|
|
8
8
|
import { ensureConsumerPrincipal, getConsumerPrincipal } from "../core/principal.js";
|
|
9
|
+
import { MCP_PACKAGE_VERSION } from "../core/version.js";
|
|
9
10
|
function text(t) {
|
|
10
11
|
return { content: [{ type: "text", text: t }] };
|
|
11
12
|
}
|
|
@@ -21,7 +22,10 @@ export function registerWalletTools(server) {
|
|
|
21
22
|
}
|
|
22
23
|
const settings = await getSettings();
|
|
23
24
|
const networkLabel = settings ? ` (${settings.network})` : "";
|
|
24
|
-
const lines = [
|
|
25
|
+
const lines = [
|
|
26
|
+
`Agent Wonderland MCP: ${MCP_PACKAGE_VERSION}`,
|
|
27
|
+
`Payment methods${networkLabel}:`,
|
|
28
|
+
];
|
|
25
29
|
for (const w of wallets) {
|
|
26
30
|
const label = w.label ? ` (${w.label})` : "";
|
|
27
31
|
const storage = w.keyType === "ows" ? " [encrypted]" : " [plaintext]";
|
|
@@ -213,6 +217,8 @@ export function registerWalletTools(server) {
|
|
|
213
217
|
"",
|
|
214
218
|
chainStatus,
|
|
215
219
|
"",
|
|
220
|
+
"No MCP restart is required for wallet changes.",
|
|
221
|
+
"",
|
|
216
222
|
`Fund this address with USDC on ${defaultCh === "solana" ? "Solana" : "Tempo"} to start using agents.`,
|
|
217
223
|
].join("\n"));
|
|
218
224
|
}
|
|
@@ -244,6 +250,8 @@ export function registerWalletTools(server) {
|
|
|
244
250
|
` Chains: solana`,
|
|
245
251
|
` Consumer principal: ${principal}`,
|
|
246
252
|
"",
|
|
253
|
+
"No MCP restart is required for wallet changes.",
|
|
254
|
+
"",
|
|
247
255
|
"Fund this address with USDC on Solana to start using agents.",
|
|
248
256
|
].join("\n") + owsNudge);
|
|
249
257
|
}
|
|
@@ -269,6 +277,8 @@ export function registerWalletTools(server) {
|
|
|
269
277
|
` Chains: tempo, base`,
|
|
270
278
|
` Consumer principal: ${principal}`,
|
|
271
279
|
"",
|
|
280
|
+
"No MCP restart is required for wallet changes.",
|
|
281
|
+
"",
|
|
272
282
|
`Fund this address with USDC on Tempo or Base to start using agents.`,
|
|
273
283
|
].join("\n") + owsNudge);
|
|
274
284
|
}
|
|
@@ -293,6 +303,8 @@ export function registerWalletTools(server) {
|
|
|
293
303
|
` Storage: ~/.ows/ (AES-256-GCM encrypted)`,
|
|
294
304
|
` Consumer principal: ${principal}`,
|
|
295
305
|
"",
|
|
306
|
+
"No MCP restart is required for wallet changes.",
|
|
307
|
+
"",
|
|
296
308
|
`Fund this address with USDC on ${defaultCh === "solana" ? "Solana" : "Tempo"} to start using agents.`,
|
|
297
309
|
"For testnet: npx mppx account fund",
|
|
298
310
|
].join("\n"));
|
|
@@ -317,6 +329,8 @@ export function registerWalletTools(server) {
|
|
|
317
329
|
` Name: ${walletName}`,
|
|
318
330
|
` Chains: ${selectedChains.join(", ")}`,
|
|
319
331
|
` Consumer principal: ${principal}`,
|
|
332
|
+
"",
|
|
333
|
+
"No MCP restart is required for wallet changes.",
|
|
320
334
|
].join("\n"));
|
|
321
335
|
}
|
|
322
336
|
if (defaultCh === "solana") {
|
|
@@ -345,6 +359,8 @@ export function registerWalletTools(server) {
|
|
|
345
359
|
` Name: ${walletName}`,
|
|
346
360
|
` Chains: solana`,
|
|
347
361
|
` Consumer principal: ${principal}`,
|
|
362
|
+
"",
|
|
363
|
+
"No MCP restart is required for wallet changes.",
|
|
348
364
|
].join("\n") + owsNudge);
|
|
349
365
|
}
|
|
350
366
|
catch (err) {
|
|
@@ -376,6 +392,8 @@ export function registerWalletTools(server) {
|
|
|
376
392
|
` Name: ${walletName}`,
|
|
377
393
|
` Chains: ${selectedChains.join(", ")}`,
|
|
378
394
|
` Consumer principal: ${principal}`,
|
|
395
|
+
"",
|
|
396
|
+
"No MCP restart is required for wallet changes.",
|
|
379
397
|
].join("\n") + owsNudge);
|
|
380
398
|
}
|
|
381
399
|
catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentwonderland/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server for the Agent Wonderland AI agent marketplace",
|
|
6
6
|
"bin": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
26
|
+
"@scure/bip39": "^1.6.0",
|
|
26
27
|
"@solana/spl-token": "^0.4.14",
|
|
27
28
|
"@solana/web3.js": "1.95.8",
|
|
28
29
|
"qrcode": "^1.5.4",
|
|
@@ -72,7 +72,7 @@ describe("api-client headers", () => {
|
|
|
72
72
|
"X-AW-Rebate-Principal":
|
|
73
73
|
"did:pkh:eip155:8453:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
|
74
74
|
"X-AW-Surface": "mcp",
|
|
75
|
-
"X-AW-MCP-Version": "0.1.
|
|
75
|
+
"X-AW-MCP-Version": "0.1.43",
|
|
76
76
|
"X-AW-MCP-Tool": "run_agent",
|
|
77
77
|
"X-AW-MCP-Action": "execute",
|
|
78
78
|
}),
|
|
@@ -30,7 +30,7 @@ describe("MCP setup", () => {
|
|
|
30
30
|
expect(next.mcpServers.existing.command).toBe("node");
|
|
31
31
|
expect(next.mcpServers.agentwonderland).toEqual({
|
|
32
32
|
command: "npx",
|
|
33
|
-
args: ["-y", "@agentwonderland/mcp"],
|
|
33
|
+
args: ["-y", "@agentwonderland/mcp@latest"],
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
|
|
@@ -52,7 +52,7 @@ describe("MCP setup", () => {
|
|
|
52
52
|
expect(next).toContain("[mcp_servers.other]");
|
|
53
53
|
expect(next).toContain("[mcp_servers.agentwonderland]");
|
|
54
54
|
expect(next).toContain('command = "npx"');
|
|
55
|
-
expect(next).toContain('args = ["-y", "@agentwonderland/mcp"]');
|
|
55
|
+
expect(next).toContain('args = ["-y", "@agentwonderland/mcp@latest"]');
|
|
56
56
|
expect(next).not.toContain('command = "old"');
|
|
57
57
|
expect(next).toContain("[model_provider.openai]");
|
|
58
58
|
});
|
|
@@ -76,7 +76,7 @@ describe("MCP setup", () => {
|
|
|
76
76
|
|
|
77
77
|
expect(result.status).toBe("updated");
|
|
78
78
|
expect(result.backupPath).toBeTruthy();
|
|
79
|
-
expect(written.mcpServers.agentwonderland.args).toEqual(["-y", "@agentwonderland/mcp"]);
|
|
79
|
+
expect(written.mcpServers.agentwonderland.args).toEqual(["-y", "@agentwonderland/mcp@latest"]);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it("parses client selection flags", () => {
|
package/src/core/api-client.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getConsumerPrincipal,
|
|
8
8
|
getConsumerPrincipalForMethod,
|
|
9
9
|
} from "./principal.js";
|
|
10
|
+
import { MCP_PACKAGE_VERSION } from "./version.js";
|
|
10
11
|
|
|
11
12
|
// ── Error class ────────────────────────────────────────────────────
|
|
12
13
|
|
|
@@ -29,8 +30,6 @@ interface RequestOptions {
|
|
|
29
30
|
extraHeaders?: Record<string, string>;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const MCP_VERSION = "0.1.41";
|
|
33
|
-
|
|
34
33
|
function inferToolHeaders(path: string, method: string): Record<string, string> {
|
|
35
34
|
if (path === "/solve") {
|
|
36
35
|
return { "X-AW-MCP-Tool": "solve", "X-AW-MCP-Action": method === "POST" ? "execute" : "view" };
|
|
@@ -55,7 +54,7 @@ async function buildHeaders(path: string, method: string, options?: RequestOptio
|
|
|
55
54
|
"Content-Type": "application/json",
|
|
56
55
|
Accept: "application/json",
|
|
57
56
|
"X-AW-Surface": "mcp",
|
|
58
|
-
"X-AW-MCP-Version":
|
|
57
|
+
"X-AW-MCP-Version": MCP_PACKAGE_VERSION,
|
|
59
58
|
...inferToolHeaders(path, method),
|
|
60
59
|
};
|
|
61
60
|
|
package/src/core/ows-adapter.ts
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
import type { LocalAccount } from "viem/accounts";
|
|
12
12
|
import type { Hex } from "viem";
|
|
13
13
|
import type { Keypair } from "@solana/web3.js";
|
|
14
|
+
import { createHmac } from "node:crypto";
|
|
15
|
+
import { mnemonicToSeedSync, validateMnemonic } from "@scure/bip39";
|
|
16
|
+
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
14
17
|
|
|
15
18
|
// Note: OWS provides encrypted key storage at rest (~/.ows/, AES-256-GCM).
|
|
16
19
|
// For EVM signing, we export the secp256k1 key and use viem's native
|
|
@@ -155,6 +158,56 @@ function keypairFromEd25519Hex(privateKeyHex: string, KeypairCtor: typeof import
|
|
|
155
158
|
throw new Error(`Unsupported ed25519 key length: ${bytes.length} bytes.`);
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
function parseExportedSecret(exported: string): { secp256k1?: string; ed25519?: string; mnemonic?: string } {
|
|
162
|
+
const secret = exported.trim();
|
|
163
|
+
try {
|
|
164
|
+
const parsed = JSON.parse(secret) as { secp256k1?: string; ed25519?: string; mnemonic?: string };
|
|
165
|
+
if (parsed.secp256k1 || parsed.ed25519 || parsed.mnemonic) return parsed;
|
|
166
|
+
} catch {
|
|
167
|
+
// OWS-created wallets export a BIP-39 mnemonic, not a JSON key object.
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const hex = secret.startsWith("0x") ? secret.slice(2) : secret;
|
|
171
|
+
if (/^[0-9a-fA-F]+$/.test(hex)) {
|
|
172
|
+
if (hex.length === 64) return { secp256k1: hex, ed25519: hex };
|
|
173
|
+
if (hex.length === 128) return { ed25519: hex };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (validateMnemonic(secret, wordlist)) {
|
|
177
|
+
return { mnemonic: secret };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function deriveSolanaSeedFromMnemonic(mnemonic: string, path = "m/44'/501'/0'/0'"): Uint8Array {
|
|
184
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
185
|
+
let digest = createHmac("sha512", "ed25519 seed").update(seed).digest();
|
|
186
|
+
let key = digest.subarray(0, 32);
|
|
187
|
+
let chainCode = digest.subarray(32);
|
|
188
|
+
|
|
189
|
+
for (const part of path.split("/").slice(1)) {
|
|
190
|
+
if (!part.endsWith("'")) {
|
|
191
|
+
throw new Error(`Unsupported non-hardened ed25519 path segment: ${part}`);
|
|
192
|
+
}
|
|
193
|
+
const index = Number(part.slice(0, -1));
|
|
194
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
195
|
+
throw new Error(`Unsupported ed25519 path segment: ${part}`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const data = Buffer.alloc(37);
|
|
199
|
+
data[0] = 0;
|
|
200
|
+
Buffer.from(key).copy(data, 1);
|
|
201
|
+
data.writeUInt32BE(index + 0x80000000, 33);
|
|
202
|
+
|
|
203
|
+
digest = createHmac("sha512", chainCode).update(data).digest();
|
|
204
|
+
key = digest.subarray(0, 32);
|
|
205
|
+
chainCode = digest.subarray(32);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return Uint8Array.from(key);
|
|
209
|
+
}
|
|
210
|
+
|
|
158
211
|
// ── Public API ───────────────────────────────────────────────────
|
|
159
212
|
|
|
160
213
|
/**
|
|
@@ -278,7 +331,13 @@ export async function owsAccountFromWalletId(
|
|
|
278
331
|
// (EIP-5806 delegate calls) which OWS's native signing can't serialize.
|
|
279
332
|
// OWS provides encrypted storage at rest; viem handles signing in memory.
|
|
280
333
|
const exported = ows.exportWallet(walletId);
|
|
281
|
-
const keys =
|
|
334
|
+
const keys = parseExportedSecret(exported);
|
|
335
|
+
|
|
336
|
+
if (keys.mnemonic) {
|
|
337
|
+
const { mnemonicToAccount } = await import("viem/accounts");
|
|
338
|
+
return mnemonicToAccount(keys.mnemonic);
|
|
339
|
+
}
|
|
340
|
+
|
|
282
341
|
if (!keys.secp256k1) {
|
|
283
342
|
throw new Error(`Wallet "${wallet.name}" has no secp256k1 key for EVM signing.`);
|
|
284
343
|
}
|
|
@@ -295,12 +354,17 @@ export async function owsSolanaKeypairFromWalletId(
|
|
|
295
354
|
findSolanaAccount(wallet);
|
|
296
355
|
|
|
297
356
|
const exported = ows.exportWallet(walletId);
|
|
298
|
-
const keys =
|
|
357
|
+
const keys = parseExportedSecret(exported);
|
|
358
|
+
const { Keypair } = await import("@solana/web3.js");
|
|
359
|
+
|
|
360
|
+
if (keys.mnemonic) {
|
|
361
|
+
return Keypair.fromSeed(deriveSolanaSeedFromMnemonic(keys.mnemonic));
|
|
362
|
+
}
|
|
363
|
+
|
|
299
364
|
if (!keys.ed25519) {
|
|
300
365
|
throw new Error(`Wallet "${wallet.name}" has no ed25519 key for Solana signing.`);
|
|
301
366
|
}
|
|
302
367
|
|
|
303
|
-
const { Keypair } = await import("@solana/web3.js");
|
|
304
368
|
return keypairFromEd25519Hex(keys.ed25519, Keypair);
|
|
305
369
|
}
|
|
306
370
|
|
package/src/core/payments.ts
CHANGED
|
@@ -76,52 +76,44 @@ async function initEvmMppForChain(
|
|
|
76
76
|
wallet: WalletEntry,
|
|
77
77
|
chain: "tempo" | "base",
|
|
78
78
|
): Promise<typeof fetch | null> {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
let account;
|
|
82
|
-
|
|
83
|
-
if (wallet.keyType === "ows" && wallet.owsWalletId) {
|
|
84
|
-
const { owsAccountFromWalletId } = await import("./ows-adapter.js");
|
|
85
|
-
account = await owsAccountFromWalletId(wallet.owsWalletId);
|
|
86
|
-
} else if (wallet.key) {
|
|
87
|
-
const { privateKeyToAccount } = await import("viem/accounts");
|
|
88
|
-
account = privateKeyToAccount(normalizeKey(wallet.key));
|
|
89
|
-
} else {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const methods = [];
|
|
94
|
-
if (chain === "tempo") {
|
|
95
|
-
const { tempoChargeClient } = await import("./tempo-charge.js");
|
|
96
|
-
methods.push(tempoChargeClient({ account }));
|
|
97
|
-
} else {
|
|
98
|
-
const { baseChargeClient } = await import("./base-charge.js");
|
|
99
|
-
methods.push(baseChargeClient({ account }));
|
|
100
|
-
}
|
|
79
|
+
const { Mppx } = await import("./mpp-client.js");
|
|
80
|
+
let account;
|
|
101
81
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
82
|
+
if (wallet.keyType === "ows" && wallet.owsWalletId) {
|
|
83
|
+
const { owsAccountFromWalletId } = await import("./ows-adapter.js");
|
|
84
|
+
account = await owsAccountFromWalletId(wallet.owsWalletId);
|
|
85
|
+
} else if (wallet.key) {
|
|
86
|
+
const { privateKeyToAccount } = await import("viem/accounts");
|
|
87
|
+
account = privateKeyToAccount(normalizeKey(wallet.key));
|
|
88
|
+
} else {
|
|
105
89
|
return null;
|
|
106
90
|
}
|
|
91
|
+
|
|
92
|
+
const methods = [];
|
|
93
|
+
if (chain === "tempo") {
|
|
94
|
+
const { tempoChargeClient } = await import("./tempo-charge.js");
|
|
95
|
+
methods.push(tempoChargeClient({ account }));
|
|
96
|
+
} else {
|
|
97
|
+
const { baseChargeClient } = await import("./base-charge.js");
|
|
98
|
+
methods.push(baseChargeClient({ account }));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const mppx = Mppx.create({ methods: methods as any, polyfill: false });
|
|
102
|
+
return mppx.fetch.bind(mppx) as typeof fetch;
|
|
107
103
|
}
|
|
108
104
|
|
|
109
105
|
async function initSolanaMpp(wallet: WalletEntry): Promise<typeof fetch | null> {
|
|
110
|
-
|
|
111
|
-
if (wallet.keyType !== "ows" && !wallet.key) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const { Mppx } = await import("./mpp-client.js");
|
|
116
|
-
const { solanaChargeClient } = await import("./solana-charge.js");
|
|
117
|
-
const mppx = Mppx.create({
|
|
118
|
-
methods: [solanaChargeClient({ wallet })] as any,
|
|
119
|
-
polyfill: false,
|
|
120
|
-
});
|
|
121
|
-
return mppx.fetch.bind(mppx) as typeof fetch;
|
|
122
|
-
} catch {
|
|
106
|
+
if (wallet.keyType !== "ows" && !wallet.key) {
|
|
123
107
|
return null;
|
|
124
108
|
}
|
|
109
|
+
|
|
110
|
+
const { Mppx } = await import("./mpp-client.js");
|
|
111
|
+
const { solanaChargeClient } = await import("./solana-charge.js");
|
|
112
|
+
const mppx = Mppx.create({
|
|
113
|
+
methods: [solanaChargeClient({ wallet })] as any,
|
|
114
|
+
polyfill: false,
|
|
115
|
+
});
|
|
116
|
+
return mppx.fetch.bind(mppx) as typeof fetch;
|
|
125
117
|
}
|
|
126
118
|
|
|
127
119
|
async function initCard(): Promise<typeof fetch | null> {
|
|
@@ -178,6 +170,11 @@ async function initForChain(wallet: WalletEntry, chain: string): Promise<typeof
|
|
|
178
170
|
return null;
|
|
179
171
|
}
|
|
180
172
|
|
|
173
|
+
function initFailureMessage(method: string, wallet: WalletEntry, chain: string, err: unknown): string {
|
|
174
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
175
|
+
return `Payment method "${method}" is configured as ${chain} on wallet "${wallet.id}", but the signer could not initialize: ${reason}`;
|
|
176
|
+
}
|
|
177
|
+
|
|
181
178
|
// ── Public API ──────────────────────────────────────────────────
|
|
182
179
|
|
|
183
180
|
/**
|
|
@@ -214,7 +211,12 @@ export async function getPaymentFetch(method?: string): Promise<typeof fetch> {
|
|
|
214
211
|
}
|
|
215
212
|
const ck = cacheKey(resolved.wallet.id, resolved.chain);
|
|
216
213
|
if (fetchCache.has(ck)) return fetchCache.get(ck)!;
|
|
217
|
-
|
|
214
|
+
let pf: typeof fetch | null;
|
|
215
|
+
try {
|
|
216
|
+
pf = await initForChain(resolved.wallet, resolved.chain);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
throw new Error(initFailureMessage(method, resolved.wallet, resolved.chain, err));
|
|
219
|
+
}
|
|
218
220
|
if (pf) {
|
|
219
221
|
fetchCache.set(ck, pf);
|
|
220
222
|
return pf;
|
|
@@ -264,7 +266,17 @@ export async function getPaymentFetch(method?: string): Promise<typeof fetch> {
|
|
|
264
266
|
}
|
|
265
267
|
const ck = cacheKey(resolved.wallet.id, resolved.chain);
|
|
266
268
|
if (fetchCache.has(ck)) return fetchCache.get(ck)!;
|
|
267
|
-
|
|
269
|
+
let pf: typeof fetch | null;
|
|
270
|
+
try {
|
|
271
|
+
pf = await initForChain(resolved.wallet, resolved.chain);
|
|
272
|
+
} catch (err) {
|
|
273
|
+
if (m === defaultMethod) {
|
|
274
|
+
const others = configured.filter((x) => x !== m);
|
|
275
|
+
const altText = others.length > 0 ? ` Alternatives: ${others.join(", ")}` : "";
|
|
276
|
+
throw new Error(`${initFailureMessage(m, resolved.wallet, resolved.chain, err)}.${altText}`);
|
|
277
|
+
}
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
268
280
|
if (pf) {
|
|
269
281
|
fetchCache.set(ck, pf);
|
|
270
282
|
return pf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MCP_PACKAGE_VERSION = "0.1.43";
|
package/src/index.ts
CHANGED
|
@@ -26,8 +26,7 @@ import { registerJobResources } from "./resources/jobs.js";
|
|
|
26
26
|
// ── Prompts ──────────────────────────────────────────────────────
|
|
27
27
|
import { registerPrompts } from "./prompts/index.js";
|
|
28
28
|
import { runSetupCli } from "./setup.js";
|
|
29
|
-
|
|
30
|
-
const PACKAGE_VERSION = "0.1.41";
|
|
29
|
+
import { MCP_PACKAGE_VERSION } from "./core/version.js";
|
|
31
30
|
|
|
32
31
|
export async function startMcpServer(): Promise<void> {
|
|
33
32
|
const server = new McpServer(
|
|
@@ -131,7 +130,7 @@ if (isCli) {
|
|
|
131
130
|
"in a terminal it waits silently for MCP JSON-RPC messages on stdin.",
|
|
132
131
|
"",
|
|
133
132
|
"MCP client config:",
|
|
134
|
-
' { "mcpServers": { "agentwonderland": { "command": "npx", "args": ["-y", "@agentwonderland/mcp"] } } }',
|
|
133
|
+
' { "mcpServers": { "agentwonderland": { "command": "npx", "args": ["-y", "@agentwonderland/mcp@latest"] } } }',
|
|
135
134
|
"",
|
|
136
135
|
"Options:",
|
|
137
136
|
" -h, --help Show this help",
|
|
@@ -139,7 +138,7 @@ if (isCli) {
|
|
|
139
138
|
].join("\n"));
|
|
140
139
|
process.exit(0);
|
|
141
140
|
} else if (args.includes("--version") || args.includes("-v")) {
|
|
142
|
-
console.log(
|
|
141
|
+
console.log(MCP_PACKAGE_VERSION);
|
|
143
142
|
process.exit(0);
|
|
144
143
|
} else {
|
|
145
144
|
if (process.stdin.isTTY && process.stdout.isTTY) {
|
package/src/setup.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { execFileSync } from "node:child_process";
|
|
|
9
9
|
export const SERVER_NAME = "agentwonderland";
|
|
10
10
|
export const SERVER_CONFIG = {
|
|
11
11
|
command: "npx",
|
|
12
|
-
args: ["-y", "@agentwonderland/mcp"],
|
|
12
|
+
args: ["-y", "@agentwonderland/mcp@latest"],
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export type SetupClientId =
|
|
@@ -330,7 +330,7 @@ export function mergeCodexTomlConfig(existing: string): string {
|
|
|
330
330
|
const block = [
|
|
331
331
|
`[mcp_servers.${SERVER_NAME}]`,
|
|
332
332
|
`command = "npx"`,
|
|
333
|
-
`args = ["-y", "@agentwonderland/mcp"]`,
|
|
333
|
+
`args = ["-y", "@agentwonderland/mcp@latest"]`,
|
|
334
334
|
"",
|
|
335
335
|
].join("\n");
|
|
336
336
|
|
package/src/tools/wallet.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
platformSupportsOws,
|
|
29
29
|
} from "../core/ows-adapter.js";
|
|
30
30
|
import { ensureConsumerPrincipal, getConsumerPrincipal } from "../core/principal.js";
|
|
31
|
+
import { MCP_PACKAGE_VERSION } from "../core/version.js";
|
|
31
32
|
|
|
32
33
|
function text(t: string) {
|
|
33
34
|
return { content: [{ type: "text" as const, text: t }] };
|
|
@@ -53,7 +54,10 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
53
54
|
|
|
54
55
|
const settings = await getSettings();
|
|
55
56
|
const networkLabel = settings ? ` (${settings.network})` : "";
|
|
56
|
-
const lines = [
|
|
57
|
+
const lines = [
|
|
58
|
+
`Agent Wonderland MCP: ${MCP_PACKAGE_VERSION}`,
|
|
59
|
+
`Payment methods${networkLabel}:`,
|
|
60
|
+
];
|
|
57
61
|
|
|
58
62
|
for (const w of wallets) {
|
|
59
63
|
const label = w.label ? ` (${w.label})` : "";
|
|
@@ -280,6 +284,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
280
284
|
"",
|
|
281
285
|
chainStatus,
|
|
282
286
|
"",
|
|
287
|
+
"No MCP restart is required for wallet changes.",
|
|
288
|
+
"",
|
|
283
289
|
`Fund this address with USDC on ${defaultCh === "solana" ? "Solana" : "Tempo"} to start using agents.`,
|
|
284
290
|
].join("\n"));
|
|
285
291
|
}
|
|
@@ -313,6 +319,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
313
319
|
` Chains: solana`,
|
|
314
320
|
` Consumer principal: ${principal}`,
|
|
315
321
|
"",
|
|
322
|
+
"No MCP restart is required for wallet changes.",
|
|
323
|
+
"",
|
|
316
324
|
"Fund this address with USDC on Solana to start using agents.",
|
|
317
325
|
].join("\n") + owsNudge,
|
|
318
326
|
);
|
|
@@ -340,6 +348,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
340
348
|
` Chains: tempo, base`,
|
|
341
349
|
` Consumer principal: ${principal}`,
|
|
342
350
|
"",
|
|
351
|
+
"No MCP restart is required for wallet changes.",
|
|
352
|
+
"",
|
|
343
353
|
`Fund this address with USDC on Tempo or Base to start using agents.`,
|
|
344
354
|
].join("\n") + owsNudge,
|
|
345
355
|
);
|
|
@@ -369,6 +379,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
369
379
|
` Storage: ~/.ows/ (AES-256-GCM encrypted)`,
|
|
370
380
|
` Consumer principal: ${principal}`,
|
|
371
381
|
"",
|
|
382
|
+
"No MCP restart is required for wallet changes.",
|
|
383
|
+
"",
|
|
372
384
|
`Fund this address with USDC on ${defaultCh === "solana" ? "Solana" : "Tempo"} to start using agents.`,
|
|
373
385
|
"For testnet: npx mppx account fund",
|
|
374
386
|
].join("\n"),
|
|
@@ -395,11 +407,13 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
395
407
|
`Key imported to OWS [encrypted]:`,
|
|
396
408
|
` ID: ${result.walletId}`,
|
|
397
409
|
` Address: ${result.address}`,
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
410
|
+
` Name: ${walletName}`,
|
|
411
|
+
` Chains: ${selectedChains.join(", ")}`,
|
|
412
|
+
` Consumer principal: ${principal}`,
|
|
413
|
+
"",
|
|
414
|
+
"No MCP restart is required for wallet changes.",
|
|
415
|
+
].join("\n"),
|
|
416
|
+
);
|
|
403
417
|
}
|
|
404
418
|
|
|
405
419
|
if (defaultCh === "solana") {
|
|
@@ -429,6 +443,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
429
443
|
` Name: ${walletName}`,
|
|
430
444
|
` Chains: solana`,
|
|
431
445
|
` Consumer principal: ${principal}`,
|
|
446
|
+
"",
|
|
447
|
+
"No MCP restart is required for wallet changes.",
|
|
432
448
|
].join("\n") + owsNudge,
|
|
433
449
|
);
|
|
434
450
|
} catch (err) {
|
|
@@ -468,6 +484,8 @@ export function registerWalletTools(server: McpServer): void {
|
|
|
468
484
|
` Name: ${walletName}`,
|
|
469
485
|
` Chains: ${selectedChains.join(", ")}`,
|
|
470
486
|
` Consumer principal: ${principal}`,
|
|
487
|
+
"",
|
|
488
|
+
"No MCP restart is required for wallet changes.",
|
|
471
489
|
].join("\n") + owsNudge,
|
|
472
490
|
);
|
|
473
491
|
} catch {
|