@openclawcash/mcp-server 0.1.20 → 0.1.23
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 +2 -0
- package/openclawcash-mcp.mjs +161 -6
- package/package.json +2 -2
package/README.md
CHANGED
package/openclawcash-mcp.mjs
CHANGED
|
@@ -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.
|
|
10
|
+
const SERVER_VERSION = "0.1.23";
|
|
11
11
|
const PROTOCOL_VERSION = "2024-11-05";
|
|
12
12
|
const DEFAULT_BASE_URL = "https://openclawcash.com";
|
|
13
13
|
|
|
@@ -102,6 +102,7 @@ const walletSelectorSchema = walletSelectorBaseSchema.refine(
|
|
|
102
102
|
const walletsListArgsSchema = z.object({
|
|
103
103
|
includeBalances: z.boolean().optional(),
|
|
104
104
|
});
|
|
105
|
+
const policiesListArgsSchema = z.object({}).strict();
|
|
105
106
|
const skillLatestArgsSchema = z.object({}).strict();
|
|
106
107
|
|
|
107
108
|
const tokenlistArgsSchema = z.object({
|
|
@@ -248,8 +249,8 @@ const userTagSetArgsSchema = z.object({
|
|
|
248
249
|
.trim()
|
|
249
250
|
.toLowerCase()
|
|
250
251
|
.min(3)
|
|
251
|
-
.max(
|
|
252
|
-
.regex(/^[a-z0-9][a-z0-9._-]{2,
|
|
252
|
+
.max(8)
|
|
253
|
+
.regex(/^[a-z0-9][a-z0-9._-]{2,7}$/),
|
|
253
254
|
});
|
|
254
255
|
|
|
255
256
|
const polymarketLimitArgsSchema = z
|
|
@@ -347,6 +348,43 @@ const polymarketMarketSearchArgsSchema = z.object({
|
|
|
347
348
|
limit: z.number().int().positive().max(50).optional(),
|
|
348
349
|
});
|
|
349
350
|
|
|
351
|
+
const yieldwolfCasinoLinkArgsSchema = z
|
|
352
|
+
.object({
|
|
353
|
+
walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
|
|
354
|
+
walletAddress: z.string().min(1).optional(),
|
|
355
|
+
agentName: z.string().min(1).max(64).optional(),
|
|
356
|
+
lane: z.enum(["real", "test"]).optional(),
|
|
357
|
+
})
|
|
358
|
+
.strict()
|
|
359
|
+
.refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
|
|
360
|
+
message: "Provide exactly one of walletId or walletAddress.",
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const yieldwolfCasinoUnlinkArgsSchema = z
|
|
364
|
+
.object({
|
|
365
|
+
walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
|
|
366
|
+
walletAddress: z.string().min(1).optional(),
|
|
367
|
+
})
|
|
368
|
+
.strict()
|
|
369
|
+
.refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
|
|
370
|
+
message: "Provide exactly one of walletId or walletAddress.",
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const yieldwolfCasinoCallArgsSchema = z
|
|
374
|
+
.object({
|
|
375
|
+
walletId: z.union([z.number().int().positive(), z.string().min(1)]).optional(),
|
|
376
|
+
walletAddress: z.string().min(1).optional(),
|
|
377
|
+
method: z.enum(["GET", "POST"]).optional(),
|
|
378
|
+
path: z.string().min(1),
|
|
379
|
+
body: z.unknown().optional(),
|
|
380
|
+
query: z.record(z.string()).optional(),
|
|
381
|
+
idempotencyKey: z.string().min(1).optional(),
|
|
382
|
+
})
|
|
383
|
+
.strict()
|
|
384
|
+
.refine((data) => [data.walletId, data.walletAddress].filter((v) => v !== undefined).length === 1, {
|
|
385
|
+
message: "Provide exactly one of walletId or walletAddress.",
|
|
386
|
+
});
|
|
387
|
+
|
|
350
388
|
const checkoutEscrowIdArgsSchema = z.object({
|
|
351
389
|
id: z.string().min(1),
|
|
352
390
|
});
|
|
@@ -473,7 +511,7 @@ function requireAgentKey() {
|
|
|
473
511
|
return agentKey;
|
|
474
512
|
}
|
|
475
513
|
|
|
476
|
-
async function callAgentApi({ method, pathName, query, body, requireAuth = true }) {
|
|
514
|
+
async function callAgentApi({ method, pathName, query, body, requireAuth = true, extraHeaders }) {
|
|
477
515
|
const headers = {
|
|
478
516
|
Accept: "application/json",
|
|
479
517
|
};
|
|
@@ -488,6 +526,11 @@ async function callAgentApi({ method, pathName, query, body, requireAuth = true
|
|
|
488
526
|
if (["POST", "PATCH", "DELETE"].includes(String(method || "").toUpperCase())) {
|
|
489
527
|
headers["Idempotency-Key"] = `mcp-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
490
528
|
}
|
|
529
|
+
if (extraHeaders && typeof extraHeaders === "object") {
|
|
530
|
+
for (const [k, v] of Object.entries(extraHeaders)) {
|
|
531
|
+
if (typeof v === "string" && v.length > 0) headers[k] = v;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
491
534
|
|
|
492
535
|
const url = `${getBaseUrl()}${pathName}${queryString(query || {})}`;
|
|
493
536
|
const response = await fetch(url, {
|
|
@@ -607,6 +650,44 @@ const tools = [
|
|
|
607
650
|
query: args,
|
|
608
651
|
}),
|
|
609
652
|
},
|
|
653
|
+
{
|
|
654
|
+
name: "policies_list",
|
|
655
|
+
description:
|
|
656
|
+
"List active governance policies (spending limits, allowlists, testnet-only, etc.) for every managed wallet accessible to this agent key. Call this before suggesting or executing transfers/swaps so requests stay inside configured limits.",
|
|
657
|
+
inputSchema: {
|
|
658
|
+
type: "object",
|
|
659
|
+
properties: {},
|
|
660
|
+
additionalProperties: false,
|
|
661
|
+
},
|
|
662
|
+
parse: (args) => policiesListArgsSchema.parse(args ?? {}),
|
|
663
|
+
execute: async () =>
|
|
664
|
+
callAgentApi({
|
|
665
|
+
method: "GET",
|
|
666
|
+
pathName: "/api/agent/policies",
|
|
667
|
+
}),
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
name: "policy_get",
|
|
671
|
+
description:
|
|
672
|
+
"Get active governance policies for one managed wallet (whitelist, spending_limit, daily/weekly/monthly_spending_limit, disallow_live_transactions, wallet_purpose, checkout_access, venue_access, max_open_escrows, trusted_counterparty_tags). Call this before suggesting or executing a transfer/swap on the wallet so the request stays inside configured limits.",
|
|
673
|
+
inputSchema: {
|
|
674
|
+
type: "object",
|
|
675
|
+
properties: {
|
|
676
|
+
walletId: { oneOf: [{ type: "integer" }, { type: "string" }], description: selectorDescription() },
|
|
677
|
+
walletLabel: { type: "string", description: selectorDescription() },
|
|
678
|
+
walletAddress: { type: "string", description: selectorDescription() },
|
|
679
|
+
chain: { type: "string", enum: ["evm", "solana"] },
|
|
680
|
+
},
|
|
681
|
+
additionalProperties: false,
|
|
682
|
+
},
|
|
683
|
+
parse: (args) => walletSelectorSchema.parse(args ?? {}),
|
|
684
|
+
execute: async (args) =>
|
|
685
|
+
callAgentApi({
|
|
686
|
+
method: "GET",
|
|
687
|
+
pathName: "/api/agent/policy",
|
|
688
|
+
query: args,
|
|
689
|
+
}),
|
|
690
|
+
},
|
|
610
691
|
{
|
|
611
692
|
name: "transactions_list",
|
|
612
693
|
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.",
|
|
@@ -962,11 +1043,11 @@ const tools = [
|
|
|
962
1043
|
},
|
|
963
1044
|
{
|
|
964
1045
|
name: "user_tag_set",
|
|
965
|
-
description: withWriteSafety("Set global checkout user tag once (immutable after set)."),
|
|
1046
|
+
description: withWriteSafety("Set global checkout user tag once (immutable after set). 3-8 lowercase characters: a-z, 0-9, '.', '_', '-'."),
|
|
966
1047
|
inputSchema: {
|
|
967
1048
|
type: "object",
|
|
968
1049
|
properties: {
|
|
969
|
-
userTag: { type: "string" },
|
|
1050
|
+
userTag: { type: "string", minLength: 3, maxLength: 8, pattern: "^[a-z0-9][a-z0-9._-]{2,7}$" },
|
|
970
1051
|
},
|
|
971
1052
|
required: ["userTag"],
|
|
972
1053
|
additionalProperties: false,
|
|
@@ -1641,6 +1722,80 @@ const tools = [
|
|
|
1641
1722
|
body: args,
|
|
1642
1723
|
}),
|
|
1643
1724
|
},
|
|
1725
|
+
{
|
|
1726
|
+
name: "yieldwolf_casino_link",
|
|
1727
|
+
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."),
|
|
1728
|
+
inputSchema: {
|
|
1729
|
+
type: "object",
|
|
1730
|
+
properties: {
|
|
1731
|
+
walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
|
|
1732
|
+
walletAddress: { type: "string" },
|
|
1733
|
+
agentName: { type: "string", description: "Optional agent display name registered at the casino (max 64 chars)." },
|
|
1734
|
+
lane: { type: "string", enum: ["real", "test"], description: "Network lane. Defaults to 'real'." },
|
|
1735
|
+
},
|
|
1736
|
+
additionalProperties: false,
|
|
1737
|
+
},
|
|
1738
|
+
parse: (args) => yieldwolfCasinoLinkArgsSchema.parse(args ?? {}),
|
|
1739
|
+
execute: async (args) =>
|
|
1740
|
+
callAgentApi({
|
|
1741
|
+
method: "POST",
|
|
1742
|
+
pathName: "/api/agent/venues/yieldwolf-casino/link",
|
|
1743
|
+
body: args,
|
|
1744
|
+
}),
|
|
1745
|
+
},
|
|
1746
|
+
{
|
|
1747
|
+
name: "yieldwolf_casino_unlink",
|
|
1748
|
+
description: withWriteSafety("Clear the YieldWolf Casino binding for a linked wallet."),
|
|
1749
|
+
inputSchema: {
|
|
1750
|
+
type: "object",
|
|
1751
|
+
properties: {
|
|
1752
|
+
walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
|
|
1753
|
+
walletAddress: { type: "string" },
|
|
1754
|
+
},
|
|
1755
|
+
additionalProperties: false,
|
|
1756
|
+
},
|
|
1757
|
+
parse: (args) => yieldwolfCasinoUnlinkArgsSchema.parse(args ?? {}),
|
|
1758
|
+
execute: async (args) =>
|
|
1759
|
+
callAgentApi({
|
|
1760
|
+
method: "POST",
|
|
1761
|
+
pathName: "/api/agent/venues/yieldwolf-casino/unlink",
|
|
1762
|
+
body: args,
|
|
1763
|
+
}),
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
name: "yieldwolf_casino_call",
|
|
1767
|
+
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."),
|
|
1768
|
+
inputSchema: {
|
|
1769
|
+
type: "object",
|
|
1770
|
+
properties: {
|
|
1771
|
+
walletId: { oneOf: [{ type: "integer" }, { type: "string" }] },
|
|
1772
|
+
walletAddress: { type: "string" },
|
|
1773
|
+
method: { type: "string", enum: ["GET", "POST"], description: "HTTP method. Defaults to GET. Use POST for writes (play, withdraw, etc.)." },
|
|
1774
|
+
path: { type: "string", description: "YieldWolf upstream path under /gw/. Multi-segment paths supported (e.g. 'agents/me/balance', 'games/play', 'arena/kuhn/check')." },
|
|
1775
|
+
body: { description: "Optional JSON body, forwarded verbatim to YieldWolf for non-GET calls." },
|
|
1776
|
+
query: { type: "object", additionalProperties: { type: "string" }, description: "Optional extra query params forwarded to YieldWolf (walletId is added automatically)." },
|
|
1777
|
+
idempotencyKey: { type: "string", description: "Optional idempotency key forwarded as X-Idempotency-Key so the casino does not double-submit a write on retry." },
|
|
1778
|
+
},
|
|
1779
|
+
required: ["path"],
|
|
1780
|
+
additionalProperties: false,
|
|
1781
|
+
},
|
|
1782
|
+
parse: (args) => yieldwolfCasinoCallArgsSchema.parse(args ?? {}),
|
|
1783
|
+
execute: async (args) => {
|
|
1784
|
+
const upstreamPath = String(args.path).replace(/^\/+/, "");
|
|
1785
|
+
const method = (args.method || "GET").toUpperCase();
|
|
1786
|
+
const walletQuery =
|
|
1787
|
+
args.walletId !== undefined ? { walletId: String(args.walletId) } : { walletAddress: String(args.walletAddress) };
|
|
1788
|
+
const query = { ...walletQuery, ...(args.query || {}) };
|
|
1789
|
+
const extraHeaders = args.idempotencyKey ? { "X-Idempotency-Key": args.idempotencyKey } : undefined;
|
|
1790
|
+
return callAgentApi({
|
|
1791
|
+
method,
|
|
1792
|
+
pathName: `/api/agent/venues/yieldwolf-casino/proxy/${upstreamPath}`,
|
|
1793
|
+
query,
|
|
1794
|
+
body: method === "GET" ? undefined : args.body,
|
|
1795
|
+
extraHeaders,
|
|
1796
|
+
});
|
|
1797
|
+
},
|
|
1798
|
+
},
|
|
1644
1799
|
];
|
|
1645
1800
|
|
|
1646
1801
|
const resources = [
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclawcash/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "OpenClawCash MCP server for managed agent wallets, balances, transfers, swaps, approvals, cross-chain bridges, Get Paid checkout escrow flows,
|
|
3
|
+
"version": "0.1.23",
|
|
4
|
+
"description": "OpenClawCash MCP server for managed agent wallets, balances, transfers, swaps, approvals, governance policy checks, 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",
|