@agentwonderland/mcp 0.1.9 → 0.1.11

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,10 @@
1
+ import type { LocalAccount } from "viem/accounts";
2
+ interface BaseChargeClientConfig {
3
+ account: LocalAccount;
4
+ rpcUrl?: string;
5
+ }
6
+ /**
7
+ * Creates a Base charge client method for sending ERC-20 USDC transfers.
8
+ */
9
+ export declare function baseChargeClient(config: BaseChargeClientConfig): any;
10
+ export {};
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Custom MPP payment method: Base EVM USDC charge (client-side).
3
+ *
4
+ * Signs and sends a standard ERC-20 transfer on Base chain, then returns
5
+ * the tx hash as a credential. Plugs into mppx's compose/dispatch system.
6
+ */
7
+ import { Method, Credential, z } from "mppx";
8
+ // Base USDC (Circle native)
9
+ const BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
10
+ const BASE_CHAIN_ID = 8453;
11
+ // Standard ERC-20 transfer function ABI
12
+ const ERC20_ABI = [
13
+ {
14
+ type: "function",
15
+ name: "transfer",
16
+ inputs: [
17
+ { name: "to", type: "address" },
18
+ { name: "value", type: "uint256" },
19
+ ],
20
+ outputs: [{ name: "", type: "bool" }],
21
+ stateMutability: "nonpayable",
22
+ },
23
+ ];
24
+ /**
25
+ * Method schema for base/charge — must match the server-side definition.
26
+ */
27
+ const baseChargeMethod = Method.from({
28
+ name: "base",
29
+ intent: "charge",
30
+ schema: {
31
+ credential: {
32
+ payload: z.object({
33
+ hash: z.string(),
34
+ type: z.literal("hash"),
35
+ }),
36
+ },
37
+ request: z.pipe(z.object({
38
+ amount: z.string(),
39
+ currency: z.string(),
40
+ recipient: z.string(),
41
+ chainId: z.optional(z.number()),
42
+ decimals: z.optional(z.number()),
43
+ }), z.transform((v) => ({ ...v, methodDetails: { chainId: v.chainId ?? BASE_CHAIN_ID } }))),
44
+ },
45
+ });
46
+ /**
47
+ * Creates a Base charge client method for sending ERC-20 USDC transfers.
48
+ */
49
+ export function baseChargeClient(config) {
50
+ return Method.toClient(baseChargeMethod, {
51
+ async createCredential({ challenge }) {
52
+ const { request } = challenge;
53
+ const amount = BigInt(request.amount);
54
+ const recipient = request.recipient;
55
+ const currency = (request.currency ?? BASE_USDC);
56
+ // Dynamic imports to keep the module lightweight
57
+ const { createWalletClient, createPublicClient, http, encodeFunctionData } = await import("viem");
58
+ const { base } = await import("viem/chains");
59
+ const rpcUrl = config.rpcUrl ?? "https://mainnet.base.org";
60
+ const walletClient = createWalletClient({
61
+ account: config.account,
62
+ chain: base,
63
+ transport: http(rpcUrl),
64
+ });
65
+ const publicClient = createPublicClient({
66
+ chain: base,
67
+ transport: http(rpcUrl),
68
+ });
69
+ // Send ERC-20 transfer
70
+ const hash = await walletClient.writeContract({
71
+ address: currency,
72
+ abi: ERC20_ABI,
73
+ functionName: "transfer",
74
+ args: [recipient, amount],
75
+ });
76
+ // Wait for confirmation
77
+ await publicClient.waitForTransactionReceipt({ hash });
78
+ return Credential.serialize({
79
+ challenge,
80
+ payload: { hash, type: "hash" },
81
+ source: `did:pkh:eip155:${BASE_CHAIN_ID}:${config.account.address}`,
82
+ });
83
+ },
84
+ });
85
+ }
@@ -35,7 +35,8 @@ async function initMpp(wallet) {
35
35
  else {
36
36
  return null;
37
37
  }
38
- const mppx = Mppx.create({ methods: [tempo({ account })] });
38
+ const { baseChargeClient } = await import("./base-charge.js");
39
+ const mppx = Mppx.create({ methods: [tempo({ account }), baseChargeClient({ account })] });
39
40
  return mppx.fetch.bind(mppx);
40
41
  }
41
42
  catch {
package/dist/index.js CHANGED
@@ -21,6 +21,28 @@ export async function startMcpServer() {
21
21
  const server = new McpServer({
22
22
  name: "agentwonderland",
23
23
  version: "0.2.0",
24
+ }, {
25
+ instructions: [
26
+ "Agent Wonderland is an AI agent marketplace. Use these tools to discover, run, and rate AI agents.",
27
+ "",
28
+ "IMPORTANT — File handling:",
29
+ "When an agent needs a file (image, PDF, document, etc.), pass the LOCAL FILE PATH directly as the input value.",
30
+ "Example: run_agent({ agent_id: \"bg-remover\", input: { image: \"/Users/you/photo.jpg\", bgColor: \"transparent\", outputFormat: \"png\" } })",
31
+ "The MCP automatically uploads local files to temporary cloud storage and replaces them with download URLs before sending to the agent.",
32
+ "NEVER base64-encode files. NEVER ask the user to upload files manually. Just pass the path.",
33
+ "",
34
+ "IMPORTANT — Required fields:",
35
+ "Always call get_agent() first to check the agent's input schema before running it.",
36
+ "The 402 payment challenge includes the schema in the X-Agent-Input-Schema header — use it to construct correct input on the first attempt.",
37
+ "",
38
+ "Workflow:",
39
+ "1. search_agents or solve to find agents",
40
+ "2. get_agent to check required input fields and pricing",
41
+ "3. run_agent or solve with ALL required fields filled in",
42
+ "4. After a successful run, ask the user if they want to rate or tip",
43
+ "",
44
+ "Payment is automatic via the configured wallet. The user does not need to do anything for payment.",
45
+ ].join("\n"),
24
46
  });
25
47
  // Register tools
26
48
  registerSearchTools(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentwonderland/mcp",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "MCP server for the Agent Wonderland AI agent marketplace",
6
6
  "bin": {
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Custom MPP payment method: Base EVM USDC charge (client-side).
3
+ *
4
+ * Signs and sends a standard ERC-20 transfer on Base chain, then returns
5
+ * the tx hash as a credential. Plugs into mppx's compose/dispatch system.
6
+ */
7
+ import { Method, Credential, z } from "mppx";
8
+ import type { LocalAccount } from "viem/accounts";
9
+
10
+ // Base USDC (Circle native)
11
+ const BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" as const;
12
+ const BASE_CHAIN_ID = 8453;
13
+
14
+ // Standard ERC-20 transfer function ABI
15
+ const ERC20_ABI = [
16
+ {
17
+ type: "function",
18
+ name: "transfer",
19
+ inputs: [
20
+ { name: "to", type: "address" },
21
+ { name: "value", type: "uint256" },
22
+ ],
23
+ outputs: [{ name: "", type: "bool" }],
24
+ stateMutability: "nonpayable",
25
+ },
26
+ ] as const;
27
+
28
+ /**
29
+ * Method schema for base/charge — must match the server-side definition.
30
+ */
31
+ const baseChargeMethod = Method.from({
32
+ name: "base" as const,
33
+ intent: "charge" as const,
34
+ schema: {
35
+ credential: {
36
+ payload: z.object({
37
+ hash: z.string(),
38
+ type: z.literal("hash"),
39
+ }),
40
+ },
41
+ request: z.pipe(
42
+ z.object({
43
+ amount: z.string(),
44
+ currency: z.string(),
45
+ recipient: z.string(),
46
+ chainId: z.optional(z.number()),
47
+ decimals: z.optional(z.number()),
48
+ }),
49
+ z.transform((v: any) => ({ ...v, methodDetails: { chainId: v.chainId ?? BASE_CHAIN_ID } })),
50
+ ),
51
+ },
52
+ });
53
+
54
+ interface BaseChargeClientConfig {
55
+ account: LocalAccount;
56
+ rpcUrl?: string;
57
+ }
58
+
59
+ /**
60
+ * Creates a Base charge client method for sending ERC-20 USDC transfers.
61
+ */
62
+ export function baseChargeClient(config: BaseChargeClientConfig) {
63
+ return Method.toClient(baseChargeMethod as any, {
64
+ async createCredential({ challenge }: any) {
65
+ const { request } = challenge;
66
+ const amount = BigInt(request.amount);
67
+ const recipient = request.recipient as `0x${string}`;
68
+ const currency = (request.currency ?? BASE_USDC) as `0x${string}`;
69
+
70
+ // Dynamic imports to keep the module lightweight
71
+ const { createWalletClient, createPublicClient, http, encodeFunctionData } = await import("viem");
72
+ const { base } = await import("viem/chains");
73
+
74
+ const rpcUrl = config.rpcUrl ?? "https://mainnet.base.org";
75
+
76
+ const walletClient = createWalletClient({
77
+ account: config.account,
78
+ chain: base,
79
+ transport: http(rpcUrl),
80
+ });
81
+
82
+ const publicClient = createPublicClient({
83
+ chain: base,
84
+ transport: http(rpcUrl),
85
+ });
86
+
87
+ // Send ERC-20 transfer
88
+ const hash = await walletClient.writeContract({
89
+ address: currency,
90
+ abi: ERC20_ABI,
91
+ functionName: "transfer",
92
+ args: [recipient, amount],
93
+ });
94
+
95
+ // Wait for confirmation
96
+ await publicClient.waitForTransactionReceipt({ hash });
97
+
98
+ return Credential.serialize({
99
+ challenge,
100
+ payload: { hash, type: "hash" as const },
101
+ source: `did:pkh:eip155:${BASE_CHAIN_ID}:${config.account.address}`,
102
+ });
103
+ },
104
+ });
105
+ }
@@ -49,7 +49,8 @@ async function initMpp(wallet: WalletEntry): Promise<typeof fetch | null> {
49
49
  return null;
50
50
  }
51
51
 
52
- const mppx = Mppx.create({ methods: [tempo({ account })] as any });
52
+ const { baseChargeClient } = await import("./base-charge.js");
53
+ const mppx = Mppx.create({ methods: [tempo({ account }), baseChargeClient({ account })] as any });
53
54
  return mppx.fetch.bind(mppx) as typeof fetch;
54
55
  } catch {
55
56
  return null;
package/src/index.ts CHANGED
@@ -23,10 +23,35 @@ import { registerJobResources } from "./resources/jobs.js";
23
23
  import { registerPrompts } from "./prompts/index.js";
24
24
 
25
25
  export async function startMcpServer(): Promise<void> {
26
- const server = new McpServer({
27
- name: "agentwonderland",
28
- version: "0.2.0",
29
- });
26
+ const server = new McpServer(
27
+ {
28
+ name: "agentwonderland",
29
+ version: "0.2.0",
30
+ },
31
+ {
32
+ instructions: [
33
+ "Agent Wonderland is an AI agent marketplace. Use these tools to discover, run, and rate AI agents.",
34
+ "",
35
+ "IMPORTANT — File handling:",
36
+ "When an agent needs a file (image, PDF, document, etc.), pass the LOCAL FILE PATH directly as the input value.",
37
+ "Example: run_agent({ agent_id: \"bg-remover\", input: { image: \"/Users/you/photo.jpg\", bgColor: \"transparent\", outputFormat: \"png\" } })",
38
+ "The MCP automatically uploads local files to temporary cloud storage and replaces them with download URLs before sending to the agent.",
39
+ "NEVER base64-encode files. NEVER ask the user to upload files manually. Just pass the path.",
40
+ "",
41
+ "IMPORTANT — Required fields:",
42
+ "Always call get_agent() first to check the agent's input schema before running it.",
43
+ "The 402 payment challenge includes the schema in the X-Agent-Input-Schema header — use it to construct correct input on the first attempt.",
44
+ "",
45
+ "Workflow:",
46
+ "1. search_agents or solve to find agents",
47
+ "2. get_agent to check required input fields and pricing",
48
+ "3. run_agent or solve with ALL required fields filled in",
49
+ "4. After a successful run, ask the user if they want to rate or tip",
50
+ "",
51
+ "Payment is automatic via the configured wallet. The user does not need to do anything for payment.",
52
+ ].join("\n"),
53
+ },
54
+ );
30
55
 
31
56
  // Register tools
32
57
  registerSearchTools(server);