@openclawcash/mcp-server 0.1.16 → 0.1.21

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.
Files changed (2) hide show
  1. package/openclawcash-mcp.mjs +273 -21
  2. package/package.json +2 -2
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
7
7
  import { z } from "zod";
8
8
 
9
9
  const SERVER_NAME = "openclawcash";
10
- const SERVER_VERSION = "0.1.16";
10
+ const SERVER_VERSION = "0.1.21";
11
11
  const PROTOCOL_VERSION = "2024-11-05";
12
12
  const DEFAULT_BASE_URL = "https://openclawcash.com";
13
13
 
@@ -104,6 +104,11 @@ const walletsListArgsSchema = z.object({
104
104
  });
105
105
  const skillLatestArgsSchema = z.object({}).strict();
106
106
 
107
+ const tokenlistArgsSchema = z.object({
108
+ chainId: z.number().int().positive().optional(),
109
+ extended: z.boolean().optional(),
110
+ }).strict();
111
+
107
112
  const balancesArgsSchema = z
108
113
  .object({
109
114
  walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
@@ -119,6 +124,7 @@ const balancesArgsSchema = z
119
124
  const transferArgsSchema = walletSelectorBaseSchema
120
125
  .extend({
121
126
  to: z.string().min(1),
127
+ network: z.string().min(1).optional(),
122
128
  amountDisplay: z.string().min(1).optional(),
123
129
  valueBaseUnits: z.string().min(1).optional(),
124
130
  amount: z.string().min(1).optional(),
@@ -165,6 +171,7 @@ const swapExecuteArgsSchema = z
165
171
  amountIn: z.string().min(1),
166
172
  slippage: z.number().positive().optional(),
167
173
  chain: z.enum(["evm", "solana"]).optional(),
174
+ network: z.string().min(1).optional(),
168
175
  })
169
176
  .refine((data) => [data.walletId, data.walletAddress].filter((value) => value !== undefined).length === 1, {
170
177
  message: "Provide exactly one of walletId or walletAddress.",
@@ -178,11 +185,40 @@ const approveArgsSchema = z
178
185
  spender: z.string().min(1),
179
186
  amount: z.string().min(1),
180
187
  chain: z.enum(["evm", "solana"]).optional(),
188
+ network: z.string().min(1).optional(),
189
+ })
190
+ .refine((data) => [data.walletId, data.walletAddress].filter((value) => value !== undefined).length === 1, {
191
+ message: "Provide exactly one of walletId or walletAddress.",
192
+ });
193
+
194
+ const bridgeQuoteArgsSchema = z
195
+ .object({
196
+ walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
197
+ walletAddress: z.string().min(1).optional(),
198
+ fromNetwork: z.string().min(1),
199
+ fromToken: z.string().min(1),
200
+ toNetwork: z.string().min(1),
201
+ toToken: z.string().min(1),
202
+ toAddress: z.string().min(1).optional(),
203
+ amountIn: z.string().min(1),
204
+ slippagePercent: z.number().min(0).max(50).optional(),
181
205
  })
182
206
  .refine((data) => [data.walletId, data.walletAddress].filter((value) => value !== undefined).length === 1, {
183
207
  message: "Provide exactly one of walletId or walletAddress.",
184
208
  });
185
209
 
210
+ const bridgeExecuteArgsSchema = z
211
+ .object({
212
+ walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
213
+ walletAddress: z.string().min(1).optional(),
214
+ quoteId: z.string().min(1),
215
+ })
216
+ .refine((data) => [data.walletId, data.walletAddress].filter((value) => value !== undefined).length === 1, {
217
+ message: "Provide exactly one of walletId or walletAddress.",
218
+ });
219
+
220
+ const bridgeStatusArgsSchema = z.object({ bridgeTxId: z.string().min(1) });
221
+
186
222
  const supportedTokensArgsSchema = walletSelectorBaseSchema
187
223
  .extend({
188
224
  network: z.string().min(1).optional(),
@@ -193,7 +229,7 @@ const supportedTokensArgsSchema = walletSelectorBaseSchema
193
229
 
194
230
  const createWalletArgsSchema = z.object({
195
231
  label: z.string().min(1),
196
- network: z.enum(["sepolia", "mainnet", "polygon-mainnet", "solana-devnet", "solana-testnet", "solana-mainnet"]).optional(),
232
+ network: z.enum(["sepolia", "mainnet", "polygon-mainnet", "base-mainnet", "solana-devnet", "solana-testnet", "solana-mainnet"]).optional(),
197
233
  exportPassphrase: z.string().trim().min(12),
198
234
  exportPassphraseStorageType: z.enum(["env", "secret_manager", "vault", "other"]),
199
235
  exportPassphraseStorageRef: z.string().trim().min(3),
@@ -202,7 +238,7 @@ const createWalletArgsSchema = z.object({
202
238
 
203
239
  const importWalletArgsSchema = z.object({
204
240
  label: z.string().min(1),
205
- network: z.enum(["mainnet", "polygon-mainnet", "solana-mainnet"]),
241
+ network: z.enum(["mainnet", "polygon-mainnet", "base-mainnet", "solana-mainnet"]),
206
242
  privateKey: z.string().min(1),
207
243
  });
208
244
 
@@ -311,6 +347,43 @@ const polymarketMarketSearchArgsSchema = z.object({
311
347
  limit: z.number().int().positive().max(50).optional(),
312
348
  });
313
349
 
350
+ const yieldwolfCasinoLinkArgsSchema = z
351
+ .object({
352
+ walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
353
+ walletAddress: z.string().min(1).optional(),
354
+ agentName: z.string().min(1).max(64).optional(),
355
+ lane: z.enum(["real", "test"]).optional(),
356
+ })
357
+ .strict()
358
+ .refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
359
+ message: "Provide exactly one of walletId or walletAddress.",
360
+ });
361
+
362
+ const yieldwolfCasinoUnlinkArgsSchema = z
363
+ .object({
364
+ walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
365
+ walletAddress: z.string().min(1).optional(),
366
+ })
367
+ .strict()
368
+ .refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
369
+ message: "Provide exactly one of walletId or walletAddress.",
370
+ });
371
+
372
+ const yieldwolfCasinoCallArgsSchema = z
373
+ .object({
374
+ walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
375
+ walletAddress: z.string().min(1).optional(),
376
+ method: z.enum(["GET", "POST"]).optional(),
377
+ path: z.string().min(1),
378
+ body: z.unknown().optional(),
379
+ query: z.record(z.string()).optional(),
380
+ idempotencyKey: z.string().min(1).optional(),
381
+ })
382
+ .strict()
383
+ .refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
384
+ message: "Provide exactly one of walletId or walletAddress.",
385
+ });
386
+
314
387
  const checkoutEscrowIdArgsSchema = z.object({
315
388
  id: z.string().min(1),
316
389
  });
@@ -437,7 +510,7 @@ function requireAgentKey() {
437
510
  return agentKey;
438
511
  }
439
512
 
440
- async function callAgentApi({ method, pathName, query, body, requireAuth = true }) {
513
+ async function callAgentApi({ method, pathName, query, body, requireAuth = true, extraHeaders }) {
441
514
  const headers = {
442
515
  Accept: "application/json",
443
516
  };
@@ -452,6 +525,11 @@ async function callAgentApi({ method, pathName, query, body, requireAuth = true
452
525
  if (["POST", "PATCH", "DELETE"].includes(String(method || "").toUpperCase())) {
453
526
  headers["Idempotency-Key"] = `mcp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
454
527
  }
528
+ if (extraHeaders && typeof extraHeaders === "object") {
529
+ for (const [k, v] of Object.entries(extraHeaders)) {
530
+ if (typeof v === "string" && v.length > 0) headers[k] = v;
531
+ }
532
+ }
455
533
 
456
534
  const url = `${getBaseUrl()}${pathName}${queryString(query || {})}`;
457
535
  const response = await fetch(url, {
@@ -507,6 +585,31 @@ const tools = [
507
585
  requireAuth: false,
508
586
  }),
509
587
  },
588
+ {
589
+ name: "tokenlist_get",
590
+ description:
591
+ "Fetch the public OpenClawCash Token Lists v1 document covering every supported chain (Mainnet, Polygon, Base, Sepolia, Solana mainnet). Default merges curated + Uniswap (EVM) + Jupiter (Solana). Pass extended=false for curated-only, or chainId=<num> to scope to one chain (1=Mainnet, 137=Polygon, 8453=Base, 11155111=Sepolia, 101=Solana). No API key required.",
592
+ inputSchema: {
593
+ type: "object",
594
+ properties: {
595
+ chainId: { type: "integer", description: "EIP-155 chain id (EVM) or Solana Labs convention (101=mainnet, 102=testnet, 103=devnet). Omit for all chains." },
596
+ extended: { type: "boolean", description: "Default true: merge Uniswap + Jupiter community lists. Set false for curated-only.", default: true },
597
+ },
598
+ additionalProperties: false,
599
+ },
600
+ parse: (args) => tokenlistArgsSchema.parse(args ?? {}),
601
+ execute: async (args) => {
602
+ const query = {};
603
+ if (typeof args.chainId === "number") query.chainId = String(args.chainId);
604
+ if (args.extended === false) query.extended = "false";
605
+ return callAgentApi({
606
+ method: "GET",
607
+ pathName: "/api/public/tokenlist",
608
+ query: Object.keys(query).length > 0 ? query : undefined,
609
+ requireAuth: false,
610
+ });
611
+ },
612
+ },
510
613
  {
511
614
  name: "wallets_list",
512
615
  description: "List managed wallets accessible to the configured OpenClawCash agent key.",
@@ -548,7 +651,7 @@ const tools = [
548
651
  },
549
652
  {
550
653
  name: "transactions_list",
551
- description: "List merged transaction history for one managed wallet.",
654
+ description: "List merged transaction history for one managed wallet. EVM wallets accept optional `network` to scope to a single EVM chain (e.g. \"base-mainnet\") or `\"all\"` to merge activity across every supported EVM chain into one history. Solana wallets stay scoped to their cluster.",
552
655
  inputSchema: {
553
656
  type: "object",
554
657
  properties: {
@@ -556,6 +659,7 @@ const tools = [
556
659
  walletLabel: { type: "string", description: selectorDescription() },
557
660
  walletAddress: { type: "string", description: selectorDescription() },
558
661
  chain: { type: "string", enum: ["evm", "solana"] },
662
+ network: { type: "string", description: "Optional EVM network override: a known EVM network id (mainnet, polygon-mainnet, base-mainnet, sepolia) or the literal \"all\" to merge across the bucket. Omit to use the wallet's default chain." },
559
663
  },
560
664
  additionalProperties: false,
561
665
  },
@@ -614,7 +718,7 @@ const tools = [
614
718
  {
615
719
  name: "transfer_send",
616
720
  description: withWriteSafety(
617
- "Send a native asset or token transfer from a managed wallet. Do not use for checkout escrow funding; use checkout_quick_pay or checkout_swap_and_pay.",
721
+ "Send a native asset or token transfer from a managed wallet. EVM wallets accept optional `network` (e.g. \"base-mainnet\") to operate on a non-default EVM chain. Do not use for checkout escrow funding; use checkout_quick_pay or checkout_swap_and_pay.",
618
722
  ),
619
723
  inputSchema: {
620
724
  type: "object",
@@ -623,6 +727,7 @@ const tools = [
623
727
  walletLabel: { type: "string" },
624
728
  walletAddress: { type: "string" },
625
729
  chain: { type: "string", enum: ["evm", "solana"] },
730
+ network: { type: "string", description: "Optional EVM network override (mainnet, polygon-mainnet, base-mainnet, sepolia). Omit to use the wallet's default chain." },
626
731
  to: { type: "string" },
627
732
  amountDisplay: { type: "string", description: "Human-readable decimal amount (preferred)." },
628
733
  valueBaseUnits: { type: "string", description: "Base-units integer amount (preferred)." },
@@ -698,7 +803,7 @@ const tools = [
698
803
  },
699
804
  {
700
805
  name: "swap_execute",
701
- description: withWriteSafety("Execute a swap through OpenClawCash."),
806
+ description: withWriteSafety("Execute a swap through OpenClawCash. EVM wallets accept optional `network` to operate on a non-default EVM chain (mainnet, polygon-mainnet, base-mainnet, sepolia)."),
702
807
  inputSchema: {
703
808
  type: "object",
704
809
  properties: {
@@ -709,6 +814,7 @@ const tools = [
709
814
  amountIn: { type: "string" },
710
815
  slippage: { type: "number" },
711
816
  chain: { type: "string", enum: ["evm", "solana"] },
817
+ network: { type: "string", description: "Optional EVM network override; omit to use the wallet's default chain." },
712
818
  },
713
819
  required: ["tokenIn", "tokenOut", "amountIn"],
714
820
  additionalProperties: false,
@@ -723,7 +829,7 @@ const tools = [
723
829
  },
724
830
  {
725
831
  name: "approve_token",
726
- description: withWriteSafety("Approve ERC-20 token spending for a managed wallet."),
832
+ description: withWriteSafety("Approve ERC-20 token spending for a managed wallet. Optional `network` lets EVM wallets approve on a non-default EVM chain (mainnet, polygon-mainnet, base-mainnet, sepolia)."),
727
833
  inputSchema: {
728
834
  type: "object",
729
835
  properties: {
@@ -733,6 +839,7 @@ const tools = [
733
839
  spender: { type: "string" },
734
840
  amount: { type: "string" },
735
841
  chain: { type: "string", enum: ["evm", "solana"] },
842
+ network: { type: "string", description: "Optional EVM network override; omit to use the wallet's default chain." },
736
843
  },
737
844
  required: ["tokenAddress", "spender", "amount"],
738
845
  additionalProperties: false,
@@ -745,6 +852,77 @@ const tools = [
745
852
  body: args,
746
853
  }),
747
854
  },
855
+ {
856
+ name: "bridge_quote",
857
+ description:
858
+ "Quote a cross-chain bridge transfer. The aggregator (LiFi) picks the underlying bridge automatically and returns provider+bridgeName so you know which bridge was selected. EVM-EVM is fully supported; Solana source-side execute is gated to a follow-up. Quote TTL ~60s; pass the returned quoteId to bridge_execute.",
859
+ inputSchema: {
860
+ type: "object",
861
+ properties: {
862
+ walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
863
+ walletAddress: { type: "string" },
864
+ fromNetwork: { type: "string", description: "Source network. EVM-home wallets bucket-route across mainnet, polygon-mainnet, base-mainnet, sepolia." },
865
+ fromToken: { type: "string", description: "Source token symbol or contract address. Use 'native' for the chain's native gas token." },
866
+ toNetwork: { type: "string" },
867
+ toToken: { type: "string" },
868
+ toAddress: { type: "string", description: "Optional destination address. Defaults to the source wallet address." },
869
+ amountIn: { type: "string", description: "Source amount in base units (digits only)." },
870
+ slippagePercent: { type: "number", minimum: 0, maximum: 50 },
871
+ },
872
+ required: ["fromNetwork", "fromToken", "toNetwork", "toToken", "amountIn"],
873
+ additionalProperties: false,
874
+ },
875
+ parse: (args) => bridgeQuoteArgsSchema.parse(args ?? {}),
876
+ execute: async (args) =>
877
+ callAgentApi({
878
+ method: "POST",
879
+ pathName: "/api/agent/bridge/quote",
880
+ body: args,
881
+ }),
882
+ },
883
+ {
884
+ name: "bridge_execute",
885
+ description: withWriteSafety(
886
+ "Execute a previously quoted cross-chain bridge. Server signs the source-side transaction with the wallet's key, submits to chain, and collects the platform fee. Idempotency is automatic. Returns sourceTxHash; use bridge_status to track destination delivery.",
887
+ ),
888
+ inputSchema: {
889
+ type: "object",
890
+ properties: {
891
+ walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
892
+ walletAddress: { type: "string" },
893
+ quoteId: { type: "string", description: "Quote identifier returned from bridge_quote." },
894
+ },
895
+ required: ["quoteId"],
896
+ additionalProperties: false,
897
+ },
898
+ parse: (args) => bridgeExecuteArgsSchema.parse(args ?? {}),
899
+ execute: async (args) =>
900
+ callAgentApi({
901
+ method: "POST",
902
+ pathName: "/api/agent/bridge/execute",
903
+ body: args,
904
+ }),
905
+ },
906
+ {
907
+ name: "bridge_status",
908
+ description:
909
+ "Look up the status of a bridge transfer. Returns the current state (submitted | source_confirmed | destination_confirmed | completed | failed) and, when available, the destination chain tx hash and amount received.",
910
+ inputSchema: {
911
+ type: "object",
912
+ properties: {
913
+ bridgeTxId: { type: "string", description: "The bridgeTxId returned from bridge_execute (typically the source chain tx hash)." },
914
+ },
915
+ required: ["bridgeTxId"],
916
+ additionalProperties: false,
917
+ },
918
+ parse: (args) => bridgeStatusArgsSchema.parse(args ?? {}),
919
+ execute: async (args) =>
920
+ callAgentApi({
921
+ method: "GET",
922
+ pathName: "/api/agent/bridge/status",
923
+ query: { bridgeTxId: args.bridgeTxId },
924
+ }),
925
+ },
748
926
  {
749
927
  name: "wallet_create",
750
928
  description: withWriteSafety("Create a new managed wallet under the configured agent key."),
@@ -754,7 +932,7 @@ const tools = [
754
932
  label: { type: "string" },
755
933
  network: {
756
934
  type: "string",
757
- enum: ["sepolia", "mainnet", "polygon-mainnet", "solana-devnet", "solana-testnet", "solana-mainnet"],
935
+ enum: ["sepolia", "mainnet", "polygon-mainnet", "base-mainnet", "solana-devnet", "solana-testnet", "solana-mainnet"],
758
936
  },
759
937
  exportPassphrase: { type: "string", minLength: 12 },
760
938
  exportPassphraseStorageType: { type: "string", enum: ["env", "secret_manager", "vault", "other"] },
@@ -790,12 +968,12 @@ const tools = [
790
968
  },
791
969
  {
792
970
  name: "wallet_import",
793
- description: withWriteSafety("Import a mainnet, polygon-mainnet, or Solana mainnet wallet under the configured agent key."),
971
+ description: withWriteSafety("Import a mainnet, polygon-mainnet, base-mainnet, or Solana mainnet wallet under the configured agent key. EVM wallets work across all EVM chains regardless of which one is chosen here as the home network."),
794
972
  inputSchema: {
795
973
  type: "object",
796
974
  properties: {
797
975
  label: { type: "string" },
798
- network: { type: "string", enum: ["mainnet", "polygon-mainnet", "solana-mainnet"] },
976
+ network: { type: "string", enum: ["mainnet", "polygon-mainnet", "base-mainnet", "solana-mainnet"] },
799
977
  privateKey: { type: "string" },
800
978
  },
801
979
  required: ["label", "network", "privateKey"],
@@ -1290,7 +1468,7 @@ const tools = [
1290
1468
  },
1291
1469
  {
1292
1470
  name: "polymarket_order_limit",
1293
- description: withWriteSafety("Place a Polymarket limit order from a configured polygon-mainnet wallet. Use this for explicit target-price orders; for close-position intent, prefer market SELL unless a limit price is explicitly requested."),
1471
+ description: withWriteSafety("Place a Polymarket limit order from a configured Polymarket-linked EVM wallet. Use this for explicit target-price orders; for close-position intent, prefer market SELL unless a limit price is explicitly requested."),
1294
1472
  inputSchema: {
1295
1473
  type: "object",
1296
1474
  properties: {
@@ -1314,7 +1492,7 @@ const tools = [
1314
1492
  },
1315
1493
  {
1316
1494
  name: "polymarket_order_market",
1317
- description: withWriteSafety("Place a Polymarket market order from a configured polygon-mainnet wallet. For close-position intent on open markets, default to side=SELL (SELL amount is shares); use limit SELL only for explicit target-price requests."),
1495
+ description: withWriteSafety("Place a Polymarket market order from a configured Polymarket-linked EVM wallet. For close-position intent on open markets, default to side=SELL (SELL amount is shares); use limit SELL only for explicit target-price requests."),
1318
1496
  inputSchema: {
1319
1497
  type: "object",
1320
1498
  properties: {
@@ -1339,7 +1517,7 @@ const tools = [
1339
1517
  },
1340
1518
  {
1341
1519
  name: "polymarket_account",
1342
- description: "Read Polymarket account summary for a configured polygon-mainnet wallet.",
1520
+ description: "Read Polymarket account summary for a configured Polymarket-linked EVM wallet.",
1343
1521
  inputSchema: {
1344
1522
  type: "object",
1345
1523
  properties: {
@@ -1358,7 +1536,7 @@ const tools = [
1358
1536
  },
1359
1537
  {
1360
1538
  name: "polymarket_orders",
1361
- description: "List Polymarket open orders for a configured polygon-mainnet wallet.",
1539
+ description: "List Polymarket open orders for a configured Polymarket-linked EVM wallet.",
1362
1540
  inputSchema: {
1363
1541
  type: "object",
1364
1542
  properties: {
@@ -1380,7 +1558,7 @@ const tools = [
1380
1558
  },
1381
1559
  {
1382
1560
  name: "polymarket_cancel_order",
1383
- description: withWriteSafety("Cancel a Polymarket order for a configured polygon-mainnet wallet."),
1561
+ description: withWriteSafety("Cancel a Polymarket order for a configured Polymarket-linked EVM wallet."),
1384
1562
  inputSchema: {
1385
1563
  type: "object",
1386
1564
  properties: {
@@ -1401,7 +1579,7 @@ const tools = [
1401
1579
  },
1402
1580
  {
1403
1581
  name: "polymarket_clear_integration",
1404
- description: withWriteSafety("Clear Polymarket integration for a configured polygon-mainnet wallet."),
1582
+ description: withWriteSafety("Clear Polymarket integration for a configured Polymarket-linked EVM wallet."),
1405
1583
  inputSchema: {
1406
1584
  type: "object",
1407
1585
  properties: {
@@ -1420,7 +1598,7 @@ const tools = [
1420
1598
  },
1421
1599
  {
1422
1600
  name: "polymarket_activity",
1423
- description: "List Polymarket trade activity for a configured polygon-mainnet wallet.",
1601
+ description: "List Polymarket trade activity for a configured Polymarket-linked EVM wallet.",
1424
1602
  inputSchema: {
1425
1603
  type: "object",
1426
1604
  properties: {
@@ -1441,7 +1619,7 @@ const tools = [
1441
1619
  },
1442
1620
  {
1443
1621
  name: "polymarket_positions",
1444
- description: "List Polymarket open positions (open-market filtered) for a configured polygon-mainnet wallet, including position PnL fields.",
1622
+ description: "List Polymarket open positions (open-market filtered) for a configured Polymarket-linked EVM wallet, including position PnL fields.",
1445
1623
  inputSchema: {
1446
1624
  type: "object",
1447
1625
  properties: {
@@ -1461,7 +1639,7 @@ const tools = [
1461
1639
  },
1462
1640
  {
1463
1641
  name: "polymarket_redeemable",
1464
- description: "List currently redeemable Polymarket positions and tokenIds for a configured polygon-mainnet wallet.",
1642
+ description: "List currently redeemable Polymarket positions and tokenIds for a configured Polymarket-linked EVM wallet.",
1465
1643
  inputSchema: {
1466
1644
  type: "object",
1467
1645
  properties: {
@@ -1481,7 +1659,7 @@ const tools = [
1481
1659
  },
1482
1660
  {
1483
1661
  name: "polymarket_redeem",
1484
- description: withWriteSafety("Redeem Polymarket position(s) for a configured polygon-mainnet wallet. The server picks the signing path from the wallet config: signatureType 0 redeems directly on-chain (small POL gas required); 1 / 2 redeems through Polymarket's gasless relayer. Run polymarket_redeemable first to pick a tokenId for single redeem. Omit tokenId to redeem all currently redeemable positions. All-mode is chunked; loop while hasMoreRedeemable=true. Response includes signingPath ('direct' | 'gasless') and signatureType."),
1662
+ description: withWriteSafety("Redeem Polymarket position(s) for a configured Polymarket-linked EVM wallet. The server picks the signing path from the wallet config: signatureType 0 redeems directly on-chain (small POL gas required); 1 / 2 redeems through Polymarket's gasless relayer. Run polymarket_redeemable first to pick a tokenId for single redeem. Omit tokenId to redeem all currently redeemable positions. All-mode is chunked; loop while hasMoreRedeemable=true. Response includes signingPath ('direct' | 'gasless') and signatureType."),
1485
1663
  inputSchema: {
1486
1664
  type: "object",
1487
1665
  properties: {
@@ -1505,6 +1683,80 @@ const tools = [
1505
1683
  body: args,
1506
1684
  }),
1507
1685
  },
1686
+ {
1687
+ name: "yieldwolf_casino_link",
1688
+ description: withWriteSafety("Bind a Solana wallet to a YieldWolf Casino account. Lane is fixed at link time: 'real' = solana-mainnet (default), 'test' = solana-devnet/testnet. The response carries `proxy_base` and a runtime `instructions` payload (skill_doc, summary, flows, responsible_play, lane_note). The raw casino API key is intentionally not returned to the agent: every casino call must go through `yieldwolf_casino_call` so OpenClawCash can enforce wallet ownership, venue scope, and audit. The linked wallet is the only allowed withdrawal destination. To switch lanes later, call yieldwolf_casino_unlink and re-link."),
1689
+ inputSchema: {
1690
+ type: "object",
1691
+ properties: {
1692
+ walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
1693
+ walletAddress: { type: "string" },
1694
+ agentName: { type: "string", description: "Optional agent display name registered at the casino (max 64 chars)." },
1695
+ lane: { type: "string", enum: ["real", "test"], description: "Network lane. Defaults to 'real'." },
1696
+ },
1697
+ additionalProperties: false,
1698
+ },
1699
+ parse: (args) => yieldwolfCasinoLinkArgsSchema.parse(args ?? {}),
1700
+ execute: async (args) =>
1701
+ callAgentApi({
1702
+ method: "POST",
1703
+ pathName: "/api/agent/venues/yieldwolf-casino/link",
1704
+ body: args,
1705
+ }),
1706
+ },
1707
+ {
1708
+ name: "yieldwolf_casino_unlink",
1709
+ description: withWriteSafety("Clear the YieldWolf Casino binding for a linked wallet."),
1710
+ inputSchema: {
1711
+ type: "object",
1712
+ properties: {
1713
+ walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
1714
+ walletAddress: { type: "string" },
1715
+ },
1716
+ additionalProperties: false,
1717
+ },
1718
+ parse: (args) => yieldwolfCasinoUnlinkArgsSchema.parse(args ?? {}),
1719
+ execute: async (args) =>
1720
+ callAgentApi({
1721
+ method: "POST",
1722
+ pathName: "/api/agent/venues/yieldwolf-casino/unlink",
1723
+ body: args,
1724
+ }),
1725
+ },
1726
+ {
1727
+ name: "yieldwolf_casino_call",
1728
+ description: withWriteSafety("Generic dispatcher for a linked YieldWolf Casino wallet. Routes through OpenClawCash's proxy so wallet ownership, venue scope (read for GET, trade for non-GET), and audit are enforced server-side. `path` is the YieldWolf upstream path (multi-segment paths accepted; e.g. 'agents/me/balance', 'transactions/history', 'games', 'games/info' for reads; 'games/play', 'transactions/withdraw', 'arena/kuhn/check' for writes). `method` defaults to GET. `body` is forwarded verbatim for non-GET calls. Pass `idempotencyKey` so the casino does not double-submit a write on retry. See https://yieldwolf.finance/SKILL.md for the full upstream surface and request shapes."),
1729
+ inputSchema: {
1730
+ type: "object",
1731
+ properties: {
1732
+ walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
1733
+ walletAddress: { type: "string" },
1734
+ method: { type: "string", enum: ["GET", "POST"], description: "HTTP method. Defaults to GET. Use POST for writes (play, withdraw, etc.)." },
1735
+ path: { type: "string", description: "YieldWolf upstream path under /gw/. Multi-segment paths supported (e.g. 'agents/me/balance', 'games/play', 'arena/kuhn/check')." },
1736
+ body: { description: "Optional JSON body, forwarded verbatim to YieldWolf for non-GET calls." },
1737
+ query: { type: "object", additionalProperties: { type: "string" }, description: "Optional extra query params forwarded to YieldWolf (walletId is added automatically)." },
1738
+ idempotencyKey: { type: "string", description: "Optional idempotency key forwarded as X-Idempotency-Key so the casino does not double-submit a write on retry." },
1739
+ },
1740
+ required: ["path"],
1741
+ additionalProperties: false,
1742
+ },
1743
+ parse: (args) => yieldwolfCasinoCallArgsSchema.parse(args ?? {}),
1744
+ execute: async (args) => {
1745
+ const upstreamPath = String(args.path).replace(/^\/+/, "");
1746
+ const method = (args.method || "GET").toUpperCase();
1747
+ const walletQuery =
1748
+ args.walletId !== undefined ? { walletId: String(args.walletId) } : { walletAddress: String(args.walletAddress) };
1749
+ const query = { ...walletQuery, ...(args.query || {}) };
1750
+ const extraHeaders = args.idempotencyKey ? { "X-Idempotency-Key": args.idempotencyKey } : undefined;
1751
+ return callAgentApi({
1752
+ method,
1753
+ pathName: `/api/agent/venues/yieldwolf-casino/proxy/${upstreamPath}`,
1754
+ query,
1755
+ body: method === "GET" ? undefined : args.body,
1756
+ extraHeaders,
1757
+ });
1758
+ },
1759
+ },
1508
1760
  ];
1509
1761
 
1510
1762
  const resources = [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openclawcash/mcp-server",
3
- "version": "0.1.16",
4
- "description": "OpenClawCash MCP server for managed agent wallets, balances, transfers, swaps, approvals, Get Paid checkout escrow flows, and Polymarket market resolution/order tools.",
3
+ "version": "0.1.21",
4
+ "description": "OpenClawCash MCP server for managed agent wallets, balances, transfers, swaps, approvals, cross-chain bridges, Get Paid checkout escrow flows, Polymarket market resolution/order tools, and YieldWolf Casino link/unlink/proxy tools.",
5
5
  "type": "module",
6
6
  "license": "Proprietary",
7
7
  "homepage": "https://openclawcash.com/mcp",