@venicestats/mcp-server 0.1.0
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/LICENSE +21 -0
- package/README.md +114 -0
- package/bin/venicestats-mcp.mjs +2 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +5 -0
- package/dist/lib/api-client.js +58 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/branding.d.ts +26 -0
- package/dist/lib/branding.js +38 -0
- package/dist/lib/branding.js.map +1 -0
- package/dist/lib/format.d.ts +12 -0
- package/dist/lib/format.js +53 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +49 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/airdrop.d.ts +2 -0
- package/dist/tools/airdrop.js +43 -0
- package/dist/tools/airdrop.js.map +1 -0
- package/dist/tools/burns.d.ts +2 -0
- package/dist/tools/burns.js +34 -0
- package/dist/tools/burns.js.map +1 -0
- package/dist/tools/buzz.d.ts +2 -0
- package/dist/tools/buzz.js +42 -0
- package/dist/tools/buzz.js.map +1 -0
- package/dist/tools/diem.d.ts +2 -0
- package/dist/tools/diem.js +35 -0
- package/dist/tools/diem.js.map +1 -0
- package/dist/tools/insider-flow.d.ts +2 -0
- package/dist/tools/insider-flow.js +61 -0
- package/dist/tools/insider-flow.js.map +1 -0
- package/dist/tools/large-trades.d.ts +2 -0
- package/dist/tools/large-trades.js +49 -0
- package/dist/tools/large-trades.js.map +1 -0
- package/dist/tools/leaderboard.d.ts +2 -0
- package/dist/tools/leaderboard.js +33 -0
- package/dist/tools/leaderboard.js.map +1 -0
- package/dist/tools/live.d.ts +2 -0
- package/dist/tools/live.js +49 -0
- package/dist/tools/live.js.map +1 -0
- package/dist/tools/market-volume.d.ts +2 -0
- package/dist/tools/market-volume.js +39 -0
- package/dist/tools/market-volume.js.map +1 -0
- package/dist/tools/price.d.ts +2 -0
- package/dist/tools/price.js +28 -0
- package/dist/tools/price.js.map +1 -0
- package/dist/tools/protocol-overview.d.ts +2 -0
- package/dist/tools/protocol-overview.js +86 -0
- package/dist/tools/protocol-overview.js.map +1 -0
- package/dist/tools/social.d.ts +2 -0
- package/dist/tools/social.js +38 -0
- package/dist/tools/social.js.map +1 -0
- package/dist/tools/staking.d.ts +2 -0
- package/dist/tools/staking.js +37 -0
- package/dist/tools/staking.js.map +1 -0
- package/dist/tools/treasury.d.ts +2 -0
- package/dist/tools/treasury.js +30 -0
- package/dist/tools/treasury.js.map +1 -0
- package/dist/tools/trends.d.ts +2 -0
- package/dist/tools/trends.js +89 -0
- package/dist/tools/trends.js.map +1 -0
- package/dist/tools/vesting.d.ts +2 -0
- package/dist/tools/vesting.js +31 -0
- package/dist/tools/vesting.js.map +1 -0
- package/dist/tools/wallet-trades.d.ts +2 -0
- package/dist/tools/wallet-trades.js +58 -0
- package/dist/tools/wallet-trades.js.map +1 -0
- package/dist/tools/wallet.d.ts +2 -0
- package/dist/tools/wallet.js +50 -0
- package/dist/tools/wallet.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { apiGet } from "../lib/api-client.js";
|
|
2
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
3
|
+
import { fmtToken, fmtRatio, fmtPct } from "../lib/format.js";
|
|
4
|
+
export function registerStakingTool(server) {
|
|
5
|
+
server.tool("venicestats_staking", "Get VVV staking overview: total staked, staking ratio, APR, lock ratio, growth trends, cooldown wave, and net flow. Use when someone asks about staking yield, staking health, or how much VVV is staked.", { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async () => {
|
|
6
|
+
try {
|
|
7
|
+
const d = await apiGet("/api/metrics");
|
|
8
|
+
const lines = [
|
|
9
|
+
`## Staking Overview`,
|
|
10
|
+
`Total Staked: ${fmtToken(d.totalStaked, "sVVV")} (${fmtRatio(d.stakingRatio)} of supply)`,
|
|
11
|
+
`Staking Ratio 24h Change: ${fmtPct(d.stakingRatioChange24h)} pp`,
|
|
12
|
+
`Staker APR: ${d.stakerApr.toFixed(1)}%`,
|
|
13
|
+
`Emission: ${fmtToken(d.emissionPerYear, "VVV")}/year`,
|
|
14
|
+
"",
|
|
15
|
+
`## Lock Status`,
|
|
16
|
+
`sVVV Supply: ${fmtToken(d.svvvSupply)}`,
|
|
17
|
+
`Locked: ${fmtToken(d.svvvLocked)} (${fmtRatio(d.lockRatio)}) | Unlocked: ${fmtToken(d.svvvUnlocked)}`,
|
|
18
|
+
"",
|
|
19
|
+
`## Growth`,
|
|
20
|
+
`7d: ${fmtPct(d.stakingGrowth7d)} | 30d: ${fmtPct(d.stakingGrowth30d)}`,
|
|
21
|
+
`Net Flow (7d): ${fmtToken(d.netFlow7d, "VVV")}`,
|
|
22
|
+
`New Stakers (7d): ${d.newStakers7dCount} | Active Wallets (7d): ${d.activeWallets7dCount}`,
|
|
23
|
+
"",
|
|
24
|
+
`## Cooldown Wave`,
|
|
25
|
+
`${fmtToken(d.cooldownVvv, "VVV")} in cooldown across ${d.cooldownWallets} wallets`,
|
|
26
|
+
];
|
|
27
|
+
return brandedResponse(lines.join("\n"), {
|
|
28
|
+
deepLink: "/staking",
|
|
29
|
+
tip: "Use venicestats_price for current prices, or venicestats_leaderboard to see top stakers.",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=staking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staking.js","sourceRoot":"","sources":["../../src/tools/staking.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAqB9D,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,2MAA2M,EAC3M,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EACzF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAkB,cAAc,CAAC,CAAC;YAExD,MAAM,KAAK,GAAG;gBACZ,qBAAqB;gBACrB,iBAAiB,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa;gBAC1F,6BAA6B,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK;gBACjE,eAAe,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;gBACxC,aAAa,QAAQ,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,OAAO;gBACtD,EAAE;gBACF,gBAAgB;gBAChB,gBAAgB,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;gBACxC,WAAW,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;gBACtG,EAAE;gBACF,WAAW;gBACX,OAAO,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE;gBACvE,kBAAkB,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE;gBAChD,qBAAqB,CAAC,CAAC,iBAAiB,2BAA2B,CAAC,CAAC,oBAAoB,EAAE;gBAC3F,EAAE;gBACF,kBAAkB;gBAClB,GAAG,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC,eAAe,UAAU;aACpF,CAAC;YAEF,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACvC,QAAQ,EAAE,UAAU;gBACpB,GAAG,EAAE,0FAA0F;aAChG,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,aAAa,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { apiGet } from "../lib/api-client.js";
|
|
2
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
3
|
+
import { fmtUsd, fmtToken } from "../lib/format.js";
|
|
4
|
+
export function registerTreasuryTool(server) {
|
|
5
|
+
server.tool("venicestats_treasury", "Get Venice protocol treasury balances: total VVV, sVVV, and DIEM held across all treasury wallets, with breakdown by category (treasury, incentive fund, staking, liquidity, grants). Use when someone asks about treasury holdings or how much money the project has.", { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async () => {
|
|
6
|
+
try {
|
|
7
|
+
const d = await apiGet("/api/treasury", { mode: "overview" });
|
|
8
|
+
const lines = [
|
|
9
|
+
`## Venice Treasury — ${fmtUsd(d.totalValueUsd)}`,
|
|
10
|
+
`VVV: ${fmtToken(d.totalVvv)} | sVVV: ${fmtToken(d.totalSvvv)} | DIEM: ${fmtToken(d.totalDiem)}`,
|
|
11
|
+
`Wallets tracked: ${d.walletsTracked}`,
|
|
12
|
+
"",
|
|
13
|
+
`## Breakdown by Category`,
|
|
14
|
+
];
|
|
15
|
+
for (const c of d.categoryBreakdown) {
|
|
16
|
+
if (c.valueUsd > 0) {
|
|
17
|
+
lines.push(`- **${c.category}**: ${fmtUsd(c.valueUsd)} (${fmtToken(c.vvv, "VVV")}, ${fmtToken(c.svvv, "sVVV")})`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return brandedResponse(lines.join("\n"), {
|
|
21
|
+
deepLink: "/treasury",
|
|
22
|
+
tip: "Use venicestats_vesting for unlock schedules, or venicestats_protocol_overview for full protocol economics.",
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=treasury.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury.js","sourceRoot":"","sources":["../../src/tools/treasury.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAoBpD,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,wQAAwQ,EACxQ,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EACzF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAmB,eAAe,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAEhF,MAAM,KAAK,GAAG;gBACZ,wBAAwB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;gBACjD,QAAQ,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE;gBAChG,oBAAoB,CAAC,CAAC,cAAc,EAAE;gBACtC,EAAE;gBACF,0BAA0B;aAC3B,CAAC;YAEF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;gBACpC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;oBACnB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpH,CAAC;YACH,CAAC;YAED,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACvC,QAAQ,EAAE,WAAW;gBACrB,GAAG,EAAE,6GAA6G;aACnH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,aAAa,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiGet } from "../lib/api-client.js";
|
|
3
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
4
|
+
import { fmtDate } from "../lib/format.js";
|
|
5
|
+
const METRICS = [
|
|
6
|
+
"vvvPrice", "diemPrice", "ethPrice",
|
|
7
|
+
"stakingRatio", "totalStaked", "lockRatio", "svvvLocked",
|
|
8
|
+
"diemSupply", "diemStaked", "diemStakeRatio",
|
|
9
|
+
"mintRate", "cooldownWave",
|
|
10
|
+
];
|
|
11
|
+
const METRIC_LABELS = {
|
|
12
|
+
vvvPrice: "VVV Price (USD)",
|
|
13
|
+
diemPrice: "DIEM Price (USD)",
|
|
14
|
+
ethPrice: "ETH Price (USD)",
|
|
15
|
+
stakingRatio: "Staking Ratio",
|
|
16
|
+
totalStaked: "Total Staked (sVVV)",
|
|
17
|
+
lockRatio: "Lock Ratio",
|
|
18
|
+
svvvLocked: "sVVV Locked",
|
|
19
|
+
diemSupply: "DIEM Supply",
|
|
20
|
+
diemStaked: "DIEM Staked",
|
|
21
|
+
diemStakeRatio: "DIEM Stake Ratio",
|
|
22
|
+
mintRate: "DIEM Mint Rate (sVVV/DIEM)",
|
|
23
|
+
cooldownWave: "Cooldown Wave (VVV)",
|
|
24
|
+
};
|
|
25
|
+
function summarizeSeries(points, label) {
|
|
26
|
+
if (points.length === 0)
|
|
27
|
+
return [`No data available for ${label}.`];
|
|
28
|
+
const values = points.map((p) => p.v);
|
|
29
|
+
const first = values[0];
|
|
30
|
+
const last = values[values.length - 1];
|
|
31
|
+
const min = Math.min(...values);
|
|
32
|
+
const max = Math.max(...values);
|
|
33
|
+
const change = first !== 0 ? ((last - first) / first) * 100 : 0;
|
|
34
|
+
const sign = change > 0 ? "+" : "";
|
|
35
|
+
const startDate = fmtDate(new Date(points[0].t).toISOString());
|
|
36
|
+
const endDate = fmtDate(new Date(points[points.length - 1].t).toISOString());
|
|
37
|
+
const lines = [
|
|
38
|
+
`## ${label} — Trend`,
|
|
39
|
+
`Period: ${startDate} → ${endDate} (${points.length} data points)`,
|
|
40
|
+
"",
|
|
41
|
+
`| Metric | Value |`,
|
|
42
|
+
`|--------|-------|`,
|
|
43
|
+
`| Start | ${first.toLocaleString(undefined, { maximumFractionDigits: 4 })} |`,
|
|
44
|
+
`| End | ${last.toLocaleString(undefined, { maximumFractionDigits: 4 })} |`,
|
|
45
|
+
`| Change | ${sign}${change.toFixed(2)}% |`,
|
|
46
|
+
`| Min | ${min.toLocaleString(undefined, { maximumFractionDigits: 4 })} |`,
|
|
47
|
+
`| Max | ${max.toLocaleString(undefined, { maximumFractionDigits: 4 })} |`,
|
|
48
|
+
];
|
|
49
|
+
// Sample 10 evenly-spaced points for the LLM to see the shape
|
|
50
|
+
const sampleSize = Math.min(10, points.length);
|
|
51
|
+
const step = Math.max(1, Math.floor(points.length / sampleSize));
|
|
52
|
+
lines.push("", `### Sampled Values (${sampleSize} points)`);
|
|
53
|
+
for (let i = 0; i < points.length; i += step) {
|
|
54
|
+
const p = points[i];
|
|
55
|
+
const date = fmtDate(new Date(p.t).toISOString());
|
|
56
|
+
lines.push(`- ${date}: ${p.v.toLocaleString(undefined, { maximumFractionDigits: 4 })}`);
|
|
57
|
+
}
|
|
58
|
+
// Always include the last point
|
|
59
|
+
const lastPoint = points[points.length - 1];
|
|
60
|
+
const lastDate = fmtDate(new Date(lastPoint.t).toISOString());
|
|
61
|
+
if (points.length > 1 && (points.length - 1) % step !== 0) {
|
|
62
|
+
lines.push(`- ${lastDate}: ${lastPoint.v.toLocaleString(undefined, { maximumFractionDigits: 4 })}`);
|
|
63
|
+
}
|
|
64
|
+
return lines;
|
|
65
|
+
}
|
|
66
|
+
export function registerTrendsTool(server) {
|
|
67
|
+
server.tool("venicestats_trends", `Get historical trend data for a specific metric over time. Returns summary stats (start, end, change %, min, max) plus sampled data points. Available metrics: ${METRICS.join(", ")}. Use when someone asks how something has changed over time, historical trends, or "show me the chart of X".`, {
|
|
68
|
+
metric: z.enum(METRICS).describe(`Metric to chart. Options: ${METRICS.join(", ")}`),
|
|
69
|
+
period: z.enum(["7d", "30d", "90d", "1y", "all"]).default("30d").describe("Lookback period"),
|
|
70
|
+
}, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ metric, period }) => {
|
|
71
|
+
try {
|
|
72
|
+
const data = await apiGet("/api/charts", { period });
|
|
73
|
+
const series = data[metric];
|
|
74
|
+
if (!series || series.length === 0) {
|
|
75
|
+
return brandedResponse(`No trend data available for "${metric}" in period "${period}".`, { deepLink: "/", tip: "Try a different period or metric." });
|
|
76
|
+
}
|
|
77
|
+
const label = METRIC_LABELS[metric] || metric;
|
|
78
|
+
const lines = summarizeSeries(series, label);
|
|
79
|
+
return brandedResponse(lines.join("\n"), {
|
|
80
|
+
deepLink: "/",
|
|
81
|
+
tip: `Available metrics: ${METRICS.join(", ")}. Use venicestats_protocol_overview for the latest snapshot values.`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=trends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trends.js","sourceRoot":"","sources":["../../src/tools/trends.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { apiGet } from "../lib/api-client.js";
|
|
2
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
3
|
+
import { fmtToken, fmtDate } from "../lib/format.js";
|
|
4
|
+
export function registerVestingTool(server) {
|
|
5
|
+
server.tool("venicestats_vesting", "Get vesting schedule overview: total locked VVV, daily drip rate, active streams, fully vested date, and next cliff. Vesting streams are Sablier linear unlocks for team/investors. Use when someone asks about vesting, token unlocks, sell pressure from vesting, or how much VVV is still locked.", { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async () => {
|
|
6
|
+
try {
|
|
7
|
+
const d = await apiGet("/api/vesting", { mode: "overview" });
|
|
8
|
+
const lines = [
|
|
9
|
+
`## Vesting Overview`,
|
|
10
|
+
`Total Locked: ${fmtToken(d.totalLocked, "VVV")} (${d.pctLocked}% of deposited)`,
|
|
11
|
+
`Total Deposited: ${fmtToken(d.totalDeposited, "VVV")} | Withdrawn: ${fmtToken(d.totalWithdrawn, "VVV")} (${d.pctClaimed}%)`,
|
|
12
|
+
`Daily Drip: ${fmtToken(d.dailyDripRate, "VVV")}/day`,
|
|
13
|
+
"",
|
|
14
|
+
`## Streams`,
|
|
15
|
+
`Active: ${d.activeStreams} of ${d.totalStreams} total | ${d.uniqueRecipients} unique recipients`,
|
|
16
|
+
`Fully Vested By: ${fmtDate(d.fullyVestedBy)}`,
|
|
17
|
+
];
|
|
18
|
+
if (d.dripCliff) {
|
|
19
|
+
lines.push("", `## Next Cliff`, `Date: ${fmtDate(d.dripCliff.date)}`, `Impact: ${d.dripCliff.dropPct}% drop in daily drip (${d.dripCliff.streamCount} streams end)`);
|
|
20
|
+
}
|
|
21
|
+
return brandedResponse(lines.join("\n"), {
|
|
22
|
+
deepLink: "/vesting",
|
|
23
|
+
tip: "Use venicestats_insider_flow to see what vesting recipients are doing with their tokens (buying vs selling).",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=vesting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vesting.js","sourceRoot":"","sources":["../../src/tools/vesting.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAY,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAiB/D,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,sSAAsS,EACtS,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EACzF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAkB,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAE9E,MAAM,KAAK,GAAG;gBACZ,qBAAqB;gBACrB,iBAAiB,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,iBAAiB;gBAChF,oBAAoB,QAAQ,CAAC,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,QAAQ,CAAC,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,IAAI;gBAC5H,eAAe,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM;gBACrD,EAAE;gBACF,YAAY;gBACZ,WAAW,CAAC,CAAC,aAAa,OAAO,CAAC,CAAC,YAAY,YAAY,CAAC,CAAC,gBAAgB,oBAAoB;gBACjG,oBAAoB,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;aAC/C,CAAC;YAEF,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,eAAe,EACf,SAAS,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EACpC,WAAW,CAAC,CAAC,SAAS,CAAC,OAAO,yBAAyB,CAAC,CAAC,SAAS,CAAC,WAAW,eAAe,CAC9F,CAAC;YACJ,CAAC;YAED,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACvC,QAAQ,EAAE,UAAU;gBACpB,GAAG,EAAE,8GAA8G;aACpH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,aAAa,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiGet } from "../lib/api-client.js";
|
|
3
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
4
|
+
import { fmtUsd, fmtToken, fmtAgo } from "../lib/format.js";
|
|
5
|
+
export function registerWalletTradesTool(server) {
|
|
6
|
+
server.tool("venicestats_wallet_trades", "Get a wallet's trading history: recent swaps, cost basis (average buy/sell price), PnL, and behavioral insights. Use when someone asks about a wallet's trading activity, whether they're buying or selling, their cost basis, or if they're profitable.", {
|
|
7
|
+
address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Must be a valid Ethereum address").describe("Ethereum wallet address to look up"),
|
|
8
|
+
}, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ address }) => {
|
|
9
|
+
try {
|
|
10
|
+
const d = await apiGet("/api/wallet-swaps", { address });
|
|
11
|
+
const lines = [
|
|
12
|
+
`## Trading History — ${address.slice(0, 8)}...${address.slice(-4)}`,
|
|
13
|
+
`${d.total} trades total`,
|
|
14
|
+
"",
|
|
15
|
+
];
|
|
16
|
+
// Cost basis per token
|
|
17
|
+
for (const [token, cb] of Object.entries(d.costBasis)) {
|
|
18
|
+
lines.push(`### ${token} Cost Basis`);
|
|
19
|
+
if (cb.avgBuyPrice != null)
|
|
20
|
+
lines.push(`Avg Buy: $${cb.avgBuyPrice.toFixed(2)} | Bought: ${fmtToken(cb.totalBought, token)}`);
|
|
21
|
+
if (cb.avgSellPrice != null)
|
|
22
|
+
lines.push(`Avg Sell: $${cb.avgSellPrice.toFixed(2)} | Sold: ${fmtToken(cb.totalSold, token)}`);
|
|
23
|
+
lines.push(`Net Position: ${fmtToken(cb.netPosition, token)}`);
|
|
24
|
+
if (cb.invested != null)
|
|
25
|
+
lines.push(`Invested: ${fmtUsd(cb.invested)}`);
|
|
26
|
+
if (cb.extracted != null)
|
|
27
|
+
lines.push(`Extracted: ${fmtUsd(cb.extracted)}`);
|
|
28
|
+
lines.push("");
|
|
29
|
+
}
|
|
30
|
+
// Insights
|
|
31
|
+
if (d.insights.length > 0) {
|
|
32
|
+
lines.push(`### Insights`);
|
|
33
|
+
for (const insight of d.insights) {
|
|
34
|
+
lines.push(`- ${insight}`);
|
|
35
|
+
}
|
|
36
|
+
lines.push("");
|
|
37
|
+
}
|
|
38
|
+
// Recent trades (last 5)
|
|
39
|
+
const recent = d.swaps.slice(0, 5);
|
|
40
|
+
if (recent.length > 0) {
|
|
41
|
+
lines.push(`### Recent Trades`);
|
|
42
|
+
for (const s of recent) {
|
|
43
|
+
const dir = s.direction === "buy" ? "🟢 BUY" : "🔴 SELL";
|
|
44
|
+
const price = s.effectivePrice ? ` @ $${s.effectivePrice.toFixed(2)}` : "";
|
|
45
|
+
lines.push(`- ${dir} ${fmtToken(s.amount, s.token)}${price} (${fmtUsd(s.volumeUsd)}) via ${s.via} — ${fmtAgo(s.timestamp)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return brandedResponse(lines.join("\n"), {
|
|
49
|
+
deepLink: `/wallet/${address}`,
|
|
50
|
+
tip: "Use venicestats_wallet for this wallet's full Venetian identity (role, badges, radar).",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=wallet-trades.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-trades.js","sourceRoot":"","sources":["../../src/tools/wallet-trades.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiGet } from "../lib/api-client.js";
|
|
3
|
+
import { brandedResponse, errorResponse } from "../lib/branding.js";
|
|
4
|
+
import { fmtToken, fmtUsd } from "../lib/format.js";
|
|
5
|
+
export function registerWalletTool(server) {
|
|
6
|
+
server.tool("venicestats_wallet", "Look up a wallet's full Venetian identity: role, era, size tier, badges, staking position, DIEM balance, conviction score, radar chart, chronicle, and next goals. Use when someone asks about a specific wallet or address.", {
|
|
7
|
+
address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Must be a valid Ethereum address").describe("Ethereum wallet address to look up"),
|
|
8
|
+
}, { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, async ({ address }) => {
|
|
9
|
+
try {
|
|
10
|
+
const d = await apiGet("/api/venetians", { address });
|
|
11
|
+
const name = d.ensName || d.username || `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
12
|
+
const badgeList = d.badges.length > 0 ? d.badges.join(", ") : "None yet";
|
|
13
|
+
const lines = [
|
|
14
|
+
`## ${name}`,
|
|
15
|
+
`${d.roleEmoji} **${d.roleLabel}** | ${d.eraLabel} | ${d.sizeEmoji} ${d.sizeLabel}`,
|
|
16
|
+
`Rank: #${d.rank} of ${d.totalVenetians.toLocaleString()} Venetians (Score: ${d.score.toLocaleString()})`,
|
|
17
|
+
"",
|
|
18
|
+
`## Position`,
|
|
19
|
+
`sVVV: ${fmtToken(d.svvvBalance)} (${fmtToken(d.svvvLocked)} locked, ${fmtToken(d.svvvUnlocked)} unlocked)`,
|
|
20
|
+
`DIEM: ${fmtToken(d.diemBalance)} wallet + ${fmtToken(d.diemStaked)} staked`,
|
|
21
|
+
`VVV (liquid): ${fmtToken(d.vvvBalance)} | Rewards pending: ${fmtToken(d.pendingRewards)}`,
|
|
22
|
+
`Total Exposure: ${fmtUsd(d.exposureUsd)}`,
|
|
23
|
+
d.personalBurnRate > 0 ? `Personal Burn Rate: ${Math.round(d.personalBurnRate)} sVVV/DIEM` : "",
|
|
24
|
+
"",
|
|
25
|
+
`## Badges (${d.badges.length})`,
|
|
26
|
+
badgeList,
|
|
27
|
+
"",
|
|
28
|
+
`## Radar`,
|
|
29
|
+
...d.radar.map((r) => `- ${r.label}: ${r.value}/100`),
|
|
30
|
+
"",
|
|
31
|
+
`## Chronicle`,
|
|
32
|
+
d.chronicle,
|
|
33
|
+
];
|
|
34
|
+
if (d.nextGoals.length > 0) {
|
|
35
|
+
lines.push("", `## Next Goals`);
|
|
36
|
+
for (const g of d.nextGoals) {
|
|
37
|
+
lines.push(`${g.icon} ${g.text}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return brandedResponse(lines.filter(Boolean).join("\n"), {
|
|
41
|
+
deepLink: `/wallet/${address}`,
|
|
42
|
+
tip: "Use venicestats_wallet_trades for this wallet's trading history and cost basis.",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
return errorResponse(err instanceof Error ? err.message : String(err));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/tools/wallet.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@venicestats/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for VeniceStats — real-time Venice.ai (VVV/DIEM) analytics for LLMs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"venicestats-mcp": "./bin/venicestats-mcp.mjs"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "tsx watch src/index.ts"
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
20
|
+
"express": "^5.1.0",
|
|
21
|
+
"zod": "^3.24.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/express": "^5.0.0",
|
|
25
|
+
"@types/node": "^22.0.0",
|
|
26
|
+
"tsx": "^4.19.0",
|
|
27
|
+
"typescript": "^5.7.0"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"mcp",
|
|
31
|
+
"venice",
|
|
32
|
+
"vvv",
|
|
33
|
+
"diem",
|
|
34
|
+
"crypto",
|
|
35
|
+
"analytics",
|
|
36
|
+
"llm",
|
|
37
|
+
"ai"
|
|
38
|
+
],
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/venicestats/venicestats-mcp.git"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://venicestats.com/developers",
|
|
45
|
+
"author": "gekko.eth"
|
|
46
|
+
}
|