@carbon-copy/mcp 0.3.0 → 0.4.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.
@@ -1,369 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { z } from "zod";
3
- import type { CarbonCopyClient } from "../client.js";
4
-
5
- export function registerTraderTools(
6
- server: McpServer,
7
- client: CarbonCopyClient,
8
- ): void {
9
- server.registerTool(
10
- "list_traders",
11
- {
12
- title: "List Traders",
13
- description: "List all traders you are currently following.",
14
- inputSchema: z.object({}),
15
- annotations: {
16
- readOnlyHint: true,
17
- openWorldHint: false,
18
- },
19
- },
20
- async () => {
21
- const data = await client.getTraders();
22
- return {
23
- content: [
24
- {
25
- type: "text",
26
- text: JSON.stringify(data ?? { success: true }, null, 2),
27
- },
28
- ],
29
- };
30
- },
31
- );
32
-
33
- server.registerTool(
34
- "discover_traders",
35
- {
36
- title: "Discover Traders",
37
- description: "Search and rank traders available to follow.",
38
- inputSchema: z.object({
39
- q: z
40
- .string()
41
- .optional()
42
- .describe("Search term for trader username/wallet."),
43
- sortBy: z
44
- .enum(["profit", "volume", "followers", "copyability", "roi"])
45
- .optional()
46
- .describe("Sort mode for discovered traders."),
47
- minVolume: z
48
- .number()
49
- .optional()
50
- .describe("Minimum all-time volume in USD."),
51
- minRoi: z.number().optional().describe("Minimum ROI percentage."),
52
- minWinRate: z
53
- .number()
54
- .optional()
55
- .describe("Minimum win rate percentage."),
56
- limit: z
57
- .number()
58
- .int()
59
- .min(1)
60
- .max(200)
61
- .optional()
62
- .describe("Maximum number of traders to return."),
63
- }),
64
- annotations: {
65
- readOnlyHint: true,
66
- openWorldHint: false,
67
- },
68
- },
69
- async (params) => {
70
- const data = await client.discoverTraders(params);
71
- return {
72
- content: [
73
- {
74
- type: "text",
75
- text: JSON.stringify(data ?? { success: true }, null, 2),
76
- },
77
- ],
78
- };
79
- },
80
- );
81
-
82
- server.registerTool(
83
- "follow_trader",
84
- {
85
- title: "Follow Trader",
86
- description:
87
- "Start copy-trading a Polymarket trader by their wallet address.",
88
- inputSchema: z.object({
89
- wallet: z
90
- .string()
91
- .describe("The Polymarket wallet address of the trader to follow."),
92
- copyPercentage: z
93
- .number()
94
- .min(0)
95
- .max(100)
96
- .describe(
97
- "Percentage of the trader's position size to copy (0–100).",
98
- ),
99
- maxCopyAmount: z
100
- .number()
101
- .positive()
102
- .optional()
103
- .describe("Maximum USDC amount to copy per trade."),
104
- notificationsEnabled: z
105
- .boolean()
106
- .optional()
107
- .describe(
108
- "Whether to receive notifications for this trader's trades.",
109
- ),
110
- }),
111
- annotations: {
112
- readOnlyHint: false,
113
- openWorldHint: false,
114
- },
115
- },
116
- async (params) => {
117
- const data = await client.followTrader(params);
118
- return {
119
- content: [
120
- {
121
- type: "text",
122
- text: JSON.stringify(data ?? { success: true }, null, 2),
123
- },
124
- ],
125
- };
126
- },
127
- );
128
-
129
- server.registerTool(
130
- "get_trader",
131
- {
132
- title: "Get Trader",
133
- description:
134
- "Retrieve details about a specific trader you are following.",
135
- inputSchema: z.object({
136
- wallet: z
137
- .string()
138
- .describe("The Polymarket wallet address of the trader."),
139
- }),
140
- annotations: {
141
- readOnlyHint: true,
142
- openWorldHint: false,
143
- },
144
- },
145
- async ({ wallet }) => {
146
- const data = await client.getTrader(wallet);
147
- return {
148
- content: [
149
- {
150
- type: "text",
151
- text: JSON.stringify(data ?? { success: true }, null, 2),
152
- },
153
- ],
154
- };
155
- },
156
- );
157
-
158
- server.registerTool(
159
- "get_trader_performance",
160
- {
161
- title: "Get Trader Performance",
162
- description: "Retrieve performance metrics and history for a trader.",
163
- inputSchema: z.object({
164
- wallet: z
165
- .string()
166
- .describe("The Polymarket wallet address of the trader."),
167
- }),
168
- annotations: {
169
- readOnlyHint: true,
170
- openWorldHint: false,
171
- },
172
- },
173
- async ({ wallet }) => {
174
- const data = await client.getTraderPerformance(wallet);
175
- return {
176
- content: [
177
- {
178
- type: "text",
179
- text: JSON.stringify(data ?? { success: true }, null, 2),
180
- },
181
- ],
182
- };
183
- },
184
- );
185
-
186
- server.registerTool(
187
- "update_trader",
188
- {
189
- title: "Update Trader",
190
- description:
191
- "Update copy-trading settings for a trader you are following.",
192
- inputSchema: z.object({
193
- wallet: z
194
- .string()
195
- .describe("The Polymarket wallet address of the trader to update."),
196
- copyPercentage: z
197
- .number()
198
- .min(0)
199
- .max(100)
200
- .optional()
201
- .describe("New copy percentage (0–100)."),
202
- maxCopyAmount: z
203
- .number()
204
- .positive()
205
- .optional()
206
- .describe("New maximum USDC amount per trade."),
207
- notificationsEnabled: z
208
- .boolean()
209
- .optional()
210
- .describe(
211
- "Whether to receive notifications for this trader's trades.",
212
- ),
213
- copyTradingEnabled: z
214
- .boolean()
215
- .optional()
216
- .describe("Whether copy-trading is enabled for this trader."),
217
- }),
218
- annotations: {
219
- readOnlyHint: false,
220
- idempotentHint: true,
221
- openWorldHint: false,
222
- },
223
- },
224
- async ({ wallet, ...body }) => {
225
- const data = await client.updateTrader(wallet, body);
226
- return {
227
- content: [
228
- {
229
- type: "text",
230
- text: JSON.stringify(data ?? { success: true }, null, 2),
231
- },
232
- ],
233
- };
234
- },
235
- );
236
-
237
- server.registerTool(
238
- "unfollow_trader",
239
- {
240
- title: "Unfollow Trader",
241
- description:
242
- "Stop copy-trading a trader and remove them from your follow list.",
243
- inputSchema: z.object({
244
- wallet: z
245
- .string()
246
- .describe("The Polymarket wallet address of the trader to unfollow."),
247
- }),
248
- annotations: {
249
- readOnlyHint: false,
250
- destructiveHint: true,
251
- openWorldHint: false,
252
- },
253
- },
254
- async ({ wallet }) => {
255
- const data = await client.unfollowTrader(wallet);
256
- return {
257
- content: [
258
- {
259
- type: "text",
260
- text: JSON.stringify(data ?? { success: true }, null, 2),
261
- },
262
- ],
263
- };
264
- },
265
- );
266
-
267
- server.registerTool(
268
- "pause_trader",
269
- {
270
- title: "Pause Trader",
271
- description:
272
- "Pause copy-trading for a specific trader without unfollowing them.",
273
- inputSchema: z.object({
274
- wallet: z
275
- .string()
276
- .describe("The Polymarket wallet address of the trader to pause."),
277
- }),
278
- annotations: {
279
- readOnlyHint: false,
280
- idempotentHint: true,
281
- openWorldHint: false,
282
- },
283
- },
284
- async ({ wallet }) => {
285
- const data = await client.pauseTrader(wallet);
286
- return {
287
- content: [
288
- {
289
- type: "text",
290
- text: JSON.stringify(data ?? { success: true }, null, 2),
291
- },
292
- ],
293
- };
294
- },
295
- );
296
-
297
- server.registerTool(
298
- "resume_trader",
299
- {
300
- title: "Resume Trader",
301
- description: "Resume copy-trading for a previously paused trader.",
302
- inputSchema: z.object({
303
- wallet: z
304
- .string()
305
- .describe("The Polymarket wallet address of the trader to resume."),
306
- }),
307
- annotations: {
308
- readOnlyHint: false,
309
- idempotentHint: true,
310
- openWorldHint: false,
311
- },
312
- },
313
- async ({ wallet }) => {
314
- const data = await client.resumeTrader(wallet);
315
- return {
316
- content: [
317
- {
318
- type: "text",
319
- text: JSON.stringify(data ?? { success: true }, null, 2),
320
- },
321
- ],
322
- };
323
- },
324
- );
325
-
326
- server.registerTool(
327
- "batch_update_traders",
328
- {
329
- title: "Batch Update Traders",
330
- description:
331
- "Update settings across multiple followed traders in one request.",
332
- inputSchema: z.object({
333
- updates: z
334
- .array(
335
- z.object({
336
- wallet: z
337
- .string()
338
- .describe("The Polymarket wallet address of the trader."),
339
- copyPercentage: z.number().min(0).max(100).optional(),
340
- maxCopyAmount: z.number().positive().optional(),
341
- notificationsEnabled: z.boolean().optional(),
342
- copyTradingEnabled: z.boolean().optional(),
343
- }),
344
- )
345
- .min(1),
346
- }),
347
- annotations: {
348
- readOnlyHint: false,
349
- idempotentHint: true,
350
- openWorldHint: false,
351
- },
352
- },
353
- async ({ updates }) => {
354
- const mapped = updates.map(({ wallet, ...rest }) => ({
355
- walletAddress: wallet,
356
- ...rest,
357
- }));
358
- const data = await client.batchUpdateTraders(mapped);
359
- return {
360
- content: [
361
- {
362
- type: "text",
363
- text: JSON.stringify(data ?? { success: true }, null, 2),
364
- },
365
- ],
366
- };
367
- },
368
- );
369
- }
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "dist",
7
- "rootDir": "src",
8
- "strict": true,
9
- "skipLibCheck": true,
10
- "declaration": true,
11
- "declarationMap": true,
12
- "sourceMap": true,
13
- "esModuleInterop": true
14
- },
15
- "include": ["src/**/*"],
16
- "exclude": ["node_modules", "dist"]
17
- }
package/vitest.config.ts DELETED
@@ -1,9 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- environment: "node",
7
- exclude: ["dist/**", "node_modules/**"],
8
- },
9
- });