@codespar/mcp-bitso 0.1.2 → 0.2.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/dist/index.js CHANGED
@@ -13,6 +13,16 @@
13
13
  * - list_trades: List executed trades
14
14
  * - list_funding_sources: List available funding sources
15
15
  * - create_withdrawal: Create a withdrawal request
16
+ * - list_ledger: List account ledger entries (trades, fees, fundings, withdrawals)
17
+ * - list_open_orders: List currently open orders
18
+ * - lookup_order: Look up an order by origin_id / client_id
19
+ * - cancel_all_orders: Cancel all open orders
20
+ * - list_fundings: List account fundings (deposits)
21
+ * - list_withdrawals: List account withdrawals
22
+ * - get_withdrawal: Retrieve a specific withdrawal by ID
23
+ * - list_fees: List applicable fees for the authenticated user
24
+ * - get_account_status: Retrieve account KYC and verification status
25
+ * - list_funding_destinations: Get funding destination info for a currency
16
26
  *
17
27
  * Environment:
18
28
  * BITSO_API_KEY — API key from https://bitso.com/
@@ -49,7 +59,7 @@ async function bitsoRequest(method, path, body) {
49
59
  }
50
60
  return res.json();
51
61
  }
52
- const server = new Server({ name: "mcp-bitso", version: "0.1.0" }, { capabilities: { tools: {} } });
62
+ const server = new Server({ name: "mcp-bitso", version: "0.2.0" }, { capabilities: { tools: {} } });
53
63
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
54
64
  tools: [
55
65
  {
@@ -166,6 +176,110 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
166
176
  required: ["currency", "amount"],
167
177
  },
168
178
  },
179
+ {
180
+ name: "list_ledger",
181
+ description: "List account ledger entries (trades, fees, fundings, withdrawals)",
182
+ inputSchema: {
183
+ type: "object",
184
+ properties: {
185
+ operation: { type: "string", enum: ["trade", "fee", "funding", "withdrawal"], description: "Filter by operation type" },
186
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
187
+ marker: { type: "string", description: "Pagination marker" },
188
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
189
+ },
190
+ },
191
+ },
192
+ {
193
+ name: "list_open_orders",
194
+ description: "List currently open orders for the authenticated user",
195
+ inputSchema: {
196
+ type: "object",
197
+ properties: {
198
+ book: { type: "string", description: "Filter by order book symbol (e.g. btc_mxn)" },
199
+ marker: { type: "string", description: "Pagination marker" },
200
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
201
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
202
+ },
203
+ },
204
+ },
205
+ {
206
+ name: "lookup_order",
207
+ description: "Look up one or more orders by origin_id (client_id)",
208
+ inputSchema: {
209
+ type: "object",
210
+ properties: {
211
+ origin_ids: { type: "string", description: "Comma-separated origin_id values (client IDs)" },
212
+ },
213
+ required: ["origin_ids"],
214
+ },
215
+ },
216
+ {
217
+ name: "cancel_all_orders",
218
+ description: "Cancel all open orders for the authenticated user",
219
+ inputSchema: { type: "object", properties: {} },
220
+ },
221
+ {
222
+ name: "list_fundings",
223
+ description: "List account fundings (deposits)",
224
+ inputSchema: {
225
+ type: "object",
226
+ properties: {
227
+ fids: { type: "string", description: "Comma-separated funding IDs to filter" },
228
+ status: { type: "string", enum: ["pending", "complete", "cancelled"], description: "Filter by status" },
229
+ method: { type: "string", description: "Funding method (e.g. spei, bitcoin)" },
230
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
231
+ marker: { type: "string", description: "Pagination marker" },
232
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
233
+ },
234
+ },
235
+ },
236
+ {
237
+ name: "list_withdrawals",
238
+ description: "List account withdrawals",
239
+ inputSchema: {
240
+ type: "object",
241
+ properties: {
242
+ wids: { type: "string", description: "Comma-separated withdrawal IDs to filter" },
243
+ status: { type: "string", enum: ["pending", "processing", "complete", "failed"], description: "Filter by status" },
244
+ method: { type: "string", description: "Withdrawal method (e.g. spei, bitcoin)" },
245
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
246
+ marker: { type: "string", description: "Pagination marker" },
247
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
248
+ },
249
+ },
250
+ },
251
+ {
252
+ name: "get_withdrawal",
253
+ description: "Retrieve a specific withdrawal by its ID",
254
+ inputSchema: {
255
+ type: "object",
256
+ properties: {
257
+ wid: { type: "string", description: "Withdrawal ID" },
258
+ },
259
+ required: ["wid"],
260
+ },
261
+ },
262
+ {
263
+ name: "list_fees",
264
+ description: "List applicable fees for the authenticated user across trading pairs",
265
+ inputSchema: { type: "object", properties: {} },
266
+ },
267
+ {
268
+ name: "get_account_status",
269
+ description: "Retrieve account KYC and verification status (tier, limits, required docs)",
270
+ inputSchema: { type: "object", properties: {} },
271
+ },
272
+ {
273
+ name: "list_funding_destinations",
274
+ description: "Get funding destination details (address/CLABE) for a given currency",
275
+ inputSchema: {
276
+ type: "object",
277
+ properties: {
278
+ fund_currency: { type: "string", description: "Currency code (e.g. btc, mxn, ars)" },
279
+ },
280
+ required: ["fund_currency"],
281
+ },
282
+ },
169
283
  ],
170
284
  }));
171
285
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -218,6 +332,78 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
218
332
  return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/funding_destination"), null, 2) }] };
219
333
  case "create_withdrawal":
220
334
  return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("POST", "/withdrawals", args), null, 2) }] };
335
+ case "list_ledger": {
336
+ const params = new URLSearchParams();
337
+ if (args?.limit)
338
+ params.set("limit", String(args.limit));
339
+ if (args?.marker)
340
+ params.set("marker", String(args.marker));
341
+ if (args?.sort)
342
+ params.set("sort", String(args.sort));
343
+ const op = args?.operation ? `/${args.operation}s` : "";
344
+ const qs = params.toString();
345
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/ledger${op}${qs ? `?${qs}` : ""}`), null, 2) }] };
346
+ }
347
+ case "list_open_orders": {
348
+ const params = new URLSearchParams();
349
+ if (args?.book)
350
+ params.set("book", String(args.book));
351
+ if (args?.limit)
352
+ params.set("limit", String(args.limit));
353
+ if (args?.marker)
354
+ params.set("marker", String(args.marker));
355
+ if (args?.sort)
356
+ params.set("sort", String(args.sort));
357
+ const qs = params.toString();
358
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/open_orders${qs ? `?${qs}` : ""}`), null, 2) }] };
359
+ }
360
+ case "lookup_order":
361
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/orders/${args?.origin_ids}`), null, 2) }] };
362
+ case "cancel_all_orders":
363
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("DELETE", "/orders/all"), null, 2) }] };
364
+ case "list_fundings": {
365
+ const params = new URLSearchParams();
366
+ if (args?.status)
367
+ params.set("status", String(args.status));
368
+ if (args?.method)
369
+ params.set("method", String(args.method));
370
+ if (args?.limit)
371
+ params.set("limit", String(args.limit));
372
+ if (args?.marker)
373
+ params.set("marker", String(args.marker));
374
+ if (args?.sort)
375
+ params.set("sort", String(args.sort));
376
+ const suffix = args?.fids ? `/${args.fids}` : "";
377
+ const qs = params.toString();
378
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/fundings${suffix}${qs ? `?${qs}` : ""}`), null, 2) }] };
379
+ }
380
+ case "list_withdrawals": {
381
+ const params = new URLSearchParams();
382
+ if (args?.status)
383
+ params.set("status", String(args.status));
384
+ if (args?.method)
385
+ params.set("method", String(args.method));
386
+ if (args?.limit)
387
+ params.set("limit", String(args.limit));
388
+ if (args?.marker)
389
+ params.set("marker", String(args.marker));
390
+ if (args?.sort)
391
+ params.set("sort", String(args.sort));
392
+ const suffix = args?.wids ? `/${args.wids}` : "";
393
+ const qs = params.toString();
394
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/withdrawals${suffix}${qs ? `?${qs}` : ""}`), null, 2) }] };
395
+ }
396
+ case "get_withdrawal":
397
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/withdrawals/${args?.wid}`), null, 2) }] };
398
+ case "list_fees":
399
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/fees"), null, 2) }] };
400
+ case "get_account_status":
401
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/account_status"), null, 2) }] };
402
+ case "list_funding_destinations": {
403
+ const params = new URLSearchParams();
404
+ params.set("fund_currency", String(args?.fund_currency));
405
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/funding_destination?${params}`), null, 2) }] };
406
+ }
221
407
  default:
222
408
  return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
223
409
  }
@@ -244,7 +430,7 @@ async function main() {
244
430
  const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
245
431
  t.onclose = () => { if (t.sessionId)
246
432
  transports.delete(t.sessionId); };
247
- const s = new Server({ name: "mcp-bitso", version: "0.1.0" }, { capabilities: { tools: {} } });
433
+ const s = new Server({ name: "mcp-bitso", version: "0.2.0" }, { capabilities: { tools: {} } });
248
434
  server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
249
435
  server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
250
436
  await s.connect(t);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codespar/mcp-bitso",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for Bitso — Latin American crypto exchange, trading, funding, withdrawals",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/crypto/bitso"
9
9
  },
10
- "version": "0.1.2",
10
+ "version": "0.2.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@codespar/mcp-bitso",
15
- "version": "0.1.2",
15
+ "version": "0.2.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
package/src/index.ts CHANGED
@@ -14,6 +14,16 @@
14
14
  * - list_trades: List executed trades
15
15
  * - list_funding_sources: List available funding sources
16
16
  * - create_withdrawal: Create a withdrawal request
17
+ * - list_ledger: List account ledger entries (trades, fees, fundings, withdrawals)
18
+ * - list_open_orders: List currently open orders
19
+ * - lookup_order: Look up an order by origin_id / client_id
20
+ * - cancel_all_orders: Cancel all open orders
21
+ * - list_fundings: List account fundings (deposits)
22
+ * - list_withdrawals: List account withdrawals
23
+ * - get_withdrawal: Retrieve a specific withdrawal by ID
24
+ * - list_fees: List applicable fees for the authenticated user
25
+ * - get_account_status: Retrieve account KYC and verification status
26
+ * - list_funding_destinations: Get funding destination info for a currency
17
27
  *
18
28
  * Environment:
19
29
  * BITSO_API_KEY — API key from https://bitso.com/
@@ -59,7 +69,7 @@ async function bitsoRequest(method: string, path: string, body?: unknown): Promi
59
69
  }
60
70
 
61
71
  const server = new Server(
62
- { name: "mcp-bitso", version: "0.1.0" },
72
+ { name: "mcp-bitso", version: "0.2.0" },
63
73
  { capabilities: { tools: {} } }
64
74
  );
65
75
 
@@ -179,6 +189,110 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
179
189
  required: ["currency", "amount"],
180
190
  },
181
191
  },
192
+ {
193
+ name: "list_ledger",
194
+ description: "List account ledger entries (trades, fees, fundings, withdrawals)",
195
+ inputSchema: {
196
+ type: "object",
197
+ properties: {
198
+ operation: { type: "string", enum: ["trade", "fee", "funding", "withdrawal"], description: "Filter by operation type" },
199
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
200
+ marker: { type: "string", description: "Pagination marker" },
201
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
202
+ },
203
+ },
204
+ },
205
+ {
206
+ name: "list_open_orders",
207
+ description: "List currently open orders for the authenticated user",
208
+ inputSchema: {
209
+ type: "object",
210
+ properties: {
211
+ book: { type: "string", description: "Filter by order book symbol (e.g. btc_mxn)" },
212
+ marker: { type: "string", description: "Pagination marker" },
213
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
214
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
215
+ },
216
+ },
217
+ },
218
+ {
219
+ name: "lookup_order",
220
+ description: "Look up one or more orders by origin_id (client_id)",
221
+ inputSchema: {
222
+ type: "object",
223
+ properties: {
224
+ origin_ids: { type: "string", description: "Comma-separated origin_id values (client IDs)" },
225
+ },
226
+ required: ["origin_ids"],
227
+ },
228
+ },
229
+ {
230
+ name: "cancel_all_orders",
231
+ description: "Cancel all open orders for the authenticated user",
232
+ inputSchema: { type: "object", properties: {} },
233
+ },
234
+ {
235
+ name: "list_fundings",
236
+ description: "List account fundings (deposits)",
237
+ inputSchema: {
238
+ type: "object",
239
+ properties: {
240
+ fids: { type: "string", description: "Comma-separated funding IDs to filter" },
241
+ status: { type: "string", enum: ["pending", "complete", "cancelled"], description: "Filter by status" },
242
+ method: { type: "string", description: "Funding method (e.g. spei, bitcoin)" },
243
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
244
+ marker: { type: "string", description: "Pagination marker" },
245
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
246
+ },
247
+ },
248
+ },
249
+ {
250
+ name: "list_withdrawals",
251
+ description: "List account withdrawals",
252
+ inputSchema: {
253
+ type: "object",
254
+ properties: {
255
+ wids: { type: "string", description: "Comma-separated withdrawal IDs to filter" },
256
+ status: { type: "string", enum: ["pending", "processing", "complete", "failed"], description: "Filter by status" },
257
+ method: { type: "string", description: "Withdrawal method (e.g. spei, bitcoin)" },
258
+ limit: { type: "number", description: "Number of results (default 25, max 100)" },
259
+ marker: { type: "string", description: "Pagination marker" },
260
+ sort: { type: "string", enum: ["asc", "desc"], description: "Sort direction" },
261
+ },
262
+ },
263
+ },
264
+ {
265
+ name: "get_withdrawal",
266
+ description: "Retrieve a specific withdrawal by its ID",
267
+ inputSchema: {
268
+ type: "object",
269
+ properties: {
270
+ wid: { type: "string", description: "Withdrawal ID" },
271
+ },
272
+ required: ["wid"],
273
+ },
274
+ },
275
+ {
276
+ name: "list_fees",
277
+ description: "List applicable fees for the authenticated user across trading pairs",
278
+ inputSchema: { type: "object", properties: {} },
279
+ },
280
+ {
281
+ name: "get_account_status",
282
+ description: "Retrieve account KYC and verification status (tier, limits, required docs)",
283
+ inputSchema: { type: "object", properties: {} },
284
+ },
285
+ {
286
+ name: "list_funding_destinations",
287
+ description: "Get funding destination details (address/CLABE) for a given currency",
288
+ inputSchema: {
289
+ type: "object",
290
+ properties: {
291
+ fund_currency: { type: "string", description: "Currency code (e.g. btc, mxn, ars)" },
292
+ },
293
+ required: ["fund_currency"],
294
+ },
295
+ },
182
296
  ],
183
297
  }));
184
298
 
@@ -224,6 +338,61 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
224
338
  return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/funding_destination"), null, 2) }] };
225
339
  case "create_withdrawal":
226
340
  return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("POST", "/withdrawals", args), null, 2) }] };
341
+ case "list_ledger": {
342
+ const params = new URLSearchParams();
343
+ if (args?.limit) params.set("limit", String(args.limit));
344
+ if (args?.marker) params.set("marker", String(args.marker));
345
+ if (args?.sort) params.set("sort", String(args.sort));
346
+ const op = args?.operation ? `/${args.operation}s` : "";
347
+ const qs = params.toString();
348
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/ledger${op}${qs ? `?${qs}` : ""}`), null, 2) }] };
349
+ }
350
+ case "list_open_orders": {
351
+ const params = new URLSearchParams();
352
+ if (args?.book) params.set("book", String(args.book));
353
+ if (args?.limit) params.set("limit", String(args.limit));
354
+ if (args?.marker) params.set("marker", String(args.marker));
355
+ if (args?.sort) params.set("sort", String(args.sort));
356
+ const qs = params.toString();
357
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/open_orders${qs ? `?${qs}` : ""}`), null, 2) }] };
358
+ }
359
+ case "lookup_order":
360
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/orders/${args?.origin_ids}`), null, 2) }] };
361
+ case "cancel_all_orders":
362
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("DELETE", "/orders/all"), null, 2) }] };
363
+ case "list_fundings": {
364
+ const params = new URLSearchParams();
365
+ if (args?.status) params.set("status", String(args.status));
366
+ if (args?.method) params.set("method", String(args.method));
367
+ if (args?.limit) params.set("limit", String(args.limit));
368
+ if (args?.marker) params.set("marker", String(args.marker));
369
+ if (args?.sort) params.set("sort", String(args.sort));
370
+ const suffix = args?.fids ? `/${args.fids}` : "";
371
+ const qs = params.toString();
372
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/fundings${suffix}${qs ? `?${qs}` : ""}`), null, 2) }] };
373
+ }
374
+ case "list_withdrawals": {
375
+ const params = new URLSearchParams();
376
+ if (args?.status) params.set("status", String(args.status));
377
+ if (args?.method) params.set("method", String(args.method));
378
+ if (args?.limit) params.set("limit", String(args.limit));
379
+ if (args?.marker) params.set("marker", String(args.marker));
380
+ if (args?.sort) params.set("sort", String(args.sort));
381
+ const suffix = args?.wids ? `/${args.wids}` : "";
382
+ const qs = params.toString();
383
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/withdrawals${suffix}${qs ? `?${qs}` : ""}`), null, 2) }] };
384
+ }
385
+ case "get_withdrawal":
386
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/withdrawals/${args?.wid}`), null, 2) }] };
387
+ case "list_fees":
388
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/fees"), null, 2) }] };
389
+ case "get_account_status":
390
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", "/account_status"), null, 2) }] };
391
+ case "list_funding_destinations": {
392
+ const params = new URLSearchParams();
393
+ params.set("fund_currency", String(args?.fund_currency));
394
+ return { content: [{ type: "text", text: JSON.stringify(await bitsoRequest("GET", `/funding_destination?${params}`), null, 2) }] };
395
+ }
227
396
  default:
228
397
  return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
229
398
  }
@@ -246,7 +415,7 @@ async function main() {
246
415
  if (!sid && isInitializeRequest(req.body)) {
247
416
  const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
248
417
  t.onclose = () => { if (t.sessionId) transports.delete(t.sessionId); };
249
- const s = new Server({ name: "mcp-bitso", version: "0.1.0" }, { capabilities: { tools: {} } }); (server as any)._requestHandlers.forEach((v: any, k: any) => (s as any)._requestHandlers.set(k, v)); (server as any)._notificationHandlers?.forEach((v: any, k: any) => (s as any)._notificationHandlers.set(k, v)); await s.connect(t);
418
+ const s = new Server({ name: "mcp-bitso", version: "0.2.0" }, { capabilities: { tools: {} } }); (server as any)._requestHandlers.forEach((v: any, k: any) => (s as any)._requestHandlers.set(k, v)); (server as any)._notificationHandlers?.forEach((v: any, k: any) => (s as any)._notificationHandlers.set(k, v)); await s.connect(t);
250
419
  await t.handleRequest(req, res, req.body); return;
251
420
  }
252
421
  res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null });