@codespar/mcp-foxbit 0.1.0 → 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 +169 -13
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/index.ts +169 -13
package/dist/index.js
CHANGED
|
@@ -3,16 +3,19 @@
|
|
|
3
3
|
* MCP Server for Foxbit — Brazilian cryptocurrency exchange.
|
|
4
4
|
*
|
|
5
5
|
* Tools:
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
* - get_orderbook
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
6
|
+
* Public market data:
|
|
7
|
+
* - list_markets, list_currencies, get_currency, list_pairs
|
|
8
|
+
* - get_ticker, get_orderbook, get_market_trades, get_candles
|
|
9
|
+
* Account & balances:
|
|
10
|
+
* - get_account_balances, get_balance
|
|
11
|
+
* Orders & trades:
|
|
12
|
+
* - create_order, get_order, list_orders, cancel_order, list_trades
|
|
13
|
+
* Pix (BR instant payments):
|
|
14
|
+
* - create_pix_deposit, list_pix_deposits, create_pix_withdrawal, list_pix_withdrawals
|
|
15
|
+
* Crypto withdrawals & transactions:
|
|
16
|
+
* - create_crypto_withdrawal, list_deposits_withdrawals
|
|
17
|
+
* Fees:
|
|
18
|
+
* - get_trading_fees
|
|
16
19
|
*
|
|
17
20
|
* Environment:
|
|
18
21
|
* FOXBIT_API_KEY — API key from https://app.foxbit.com.br/
|
|
@@ -59,7 +62,7 @@ async function foxbitRequest(method, path, query, body) {
|
|
|
59
62
|
}
|
|
60
63
|
return res.json();
|
|
61
64
|
}
|
|
62
|
-
const server = new Server({ name: "mcp-foxbit", version: "0.
|
|
65
|
+
const server = new Server({ name: "mcp-foxbit", version: "0.2.0" }, { capabilities: { tools: {} } });
|
|
63
66
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
64
67
|
tools: [
|
|
65
68
|
{
|
|
@@ -67,6 +70,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
67
70
|
description: "List all available trading pairs / markets on Foxbit",
|
|
68
71
|
inputSchema: { type: "object", properties: {} },
|
|
69
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: "list_currencies",
|
|
75
|
+
description: "List all supported currencies (crypto and fiat) on Foxbit",
|
|
76
|
+
inputSchema: { type: "object", properties: {} },
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "get_currency",
|
|
80
|
+
description: "Get details of a specific currency (precision, min/max amounts, type)",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
symbol: { type: "string", description: "Currency symbol (e.g. btc, brl, eth)" },
|
|
85
|
+
},
|
|
86
|
+
required: ["symbol"],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
70
89
|
{
|
|
71
90
|
name: "get_ticker",
|
|
72
91
|
description: "Get 24h ticker data for a market (price, volume, high/low)",
|
|
@@ -90,11 +109,50 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
90
109
|
required: ["symbol"],
|
|
91
110
|
},
|
|
92
111
|
},
|
|
112
|
+
{
|
|
113
|
+
name: "get_market_trades",
|
|
114
|
+
description: "Get recent public trades for a market (trade history / tape)",
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: "object",
|
|
117
|
+
properties: {
|
|
118
|
+
symbol: { type: "string", description: "Market symbol (e.g. btcbrl)" },
|
|
119
|
+
page_size: { type: "number", description: "Results per page (max 100)" },
|
|
120
|
+
page: { type: "number", description: "Page number" },
|
|
121
|
+
},
|
|
122
|
+
required: ["symbol"],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "get_candles",
|
|
127
|
+
description: "Get OHLC candlestick data for a market",
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
symbol: { type: "string", description: "Market symbol (e.g. btcbrl)" },
|
|
132
|
+
interval: { type: "string", enum: ["1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d", "1w"], description: "Candle interval" },
|
|
133
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
134
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
135
|
+
limit: { type: "number", description: "Max number of candles to return" },
|
|
136
|
+
},
|
|
137
|
+
required: ["symbol", "interval"],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
93
140
|
{
|
|
94
141
|
name: "get_account_balances",
|
|
95
142
|
description: "Get account balances for all currencies",
|
|
96
143
|
inputSchema: { type: "object", properties: {} },
|
|
97
144
|
},
|
|
145
|
+
{
|
|
146
|
+
name: "get_balance",
|
|
147
|
+
description: "Get account balance for a single currency",
|
|
148
|
+
inputSchema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
currency_symbol: { type: "string", description: "Currency symbol (e.g. brl, btc, eth)" },
|
|
152
|
+
},
|
|
153
|
+
required: ["currency_symbol"],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
98
156
|
{
|
|
99
157
|
name: "create_order",
|
|
100
158
|
description: "Create a buy or sell order (limit or market)",
|
|
@@ -152,7 +210,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
152
210
|
},
|
|
153
211
|
{
|
|
154
212
|
name: "list_trades",
|
|
155
|
-
description: "List user's executed trades",
|
|
213
|
+
description: "List user's executed trades (private trade history)",
|
|
156
214
|
inputSchema: {
|
|
157
215
|
type: "object",
|
|
158
216
|
properties: {
|
|
@@ -180,6 +238,76 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
180
238
|
required: ["currency_symbol"],
|
|
181
239
|
},
|
|
182
240
|
},
|
|
241
|
+
{
|
|
242
|
+
name: "create_pix_deposit",
|
|
243
|
+
description: "Create a Pix instant deposit (BRL). Returns Pix QR code / copy-paste payload.",
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
amount: { type: "string", description: "Deposit amount in BRL (e.g. \"100.00\")" },
|
|
248
|
+
},
|
|
249
|
+
required: ["amount"],
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "list_pix_deposits",
|
|
254
|
+
description: "List Pix deposit history (BRL instant deposits)",
|
|
255
|
+
inputSchema: {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
259
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
260
|
+
page_size: { type: "number", description: "Results per page" },
|
|
261
|
+
page: { type: "number", description: "Page number" },
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: "create_pix_withdrawal",
|
|
267
|
+
description: "Create a Pix withdrawal (BRL) to a Pix key",
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: "object",
|
|
270
|
+
properties: {
|
|
271
|
+
amount: { type: "string", description: "Withdrawal amount in BRL (e.g. \"100.00\")" },
|
|
272
|
+
pix_key: { type: "string", description: "Destination Pix key (CPF, CNPJ, email, phone, or random key)" },
|
|
273
|
+
pix_key_type: { type: "string", enum: ["CPF", "CNPJ", "EMAIL", "PHONE", "EVP"], description: "Pix key type" },
|
|
274
|
+
},
|
|
275
|
+
required: ["amount", "pix_key", "pix_key_type"],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "list_pix_withdrawals",
|
|
280
|
+
description: "List Pix withdrawal history (BRL fiat withdrawals)",
|
|
281
|
+
inputSchema: {
|
|
282
|
+
type: "object",
|
|
283
|
+
properties: {
|
|
284
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
285
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
286
|
+
page_size: { type: "number", description: "Results per page" },
|
|
287
|
+
page: { type: "number", description: "Page number" },
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
name: "create_crypto_withdrawal",
|
|
293
|
+
description: "Create a crypto withdrawal to an external wallet address",
|
|
294
|
+
inputSchema: {
|
|
295
|
+
type: "object",
|
|
296
|
+
properties: {
|
|
297
|
+
currency_symbol: { type: "string", description: "Currency symbol (e.g. btc, eth, usdt)" },
|
|
298
|
+
amount: { type: "string", description: "Withdrawal amount in base units" },
|
|
299
|
+
address: { type: "string", description: "Destination wallet address" },
|
|
300
|
+
network: { type: "string", description: "Blockchain network (e.g. BTC, ERC20, TRC20, POLYGON)" },
|
|
301
|
+
tag: { type: "string", description: "Memo / tag / destination tag (for XRP, XLM, etc.)" },
|
|
302
|
+
},
|
|
303
|
+
required: ["currency_symbol", "amount", "address"],
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "get_trading_fees",
|
|
308
|
+
description: "Get current trading fees and limits (maker/taker per pair, withdrawal limits)",
|
|
309
|
+
inputSchema: { type: "object", properties: {} },
|
|
310
|
+
},
|
|
183
311
|
],
|
|
184
312
|
}));
|
|
185
313
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
@@ -188,12 +316,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
188
316
|
switch (name) {
|
|
189
317
|
case "list_markets":
|
|
190
318
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/markets"), null, 2) }] };
|
|
319
|
+
case "list_currencies":
|
|
320
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/currencies"), null, 2) }] };
|
|
321
|
+
case "get_currency":
|
|
322
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/currencies/${args?.symbol}`), null, 2) }] };
|
|
191
323
|
case "get_ticker":
|
|
192
324
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${args?.symbol}/ticker/24hr`), null, 2) }] };
|
|
193
325
|
case "get_orderbook":
|
|
194
326
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${args?.symbol}/orderbook`, { depth: args?.depth }), null, 2) }] };
|
|
327
|
+
case "get_market_trades": {
|
|
328
|
+
const { symbol, ...rest } = (args || {});
|
|
329
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${symbol}/trades`, rest), null, 2) }] };
|
|
330
|
+
}
|
|
331
|
+
case "get_candles": {
|
|
332
|
+
const { symbol, ...rest } = (args || {});
|
|
333
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${symbol}/candlesticks`, rest), null, 2) }] };
|
|
334
|
+
}
|
|
195
335
|
case "get_account_balances":
|
|
196
336
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts"), null, 2) }] };
|
|
337
|
+
case "get_balance":
|
|
338
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/accounts/${args?.currency_symbol}`), null, 2) }] };
|
|
197
339
|
case "create_order":
|
|
198
340
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/orders", undefined, args), null, 2) }] };
|
|
199
341
|
case "get_order":
|
|
@@ -208,6 +350,20 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
208
350
|
const { currency_symbol, ...rest } = (args || {});
|
|
209
351
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/accounts/${currency_symbol}/transactions`, rest), null, 2) }] };
|
|
210
352
|
}
|
|
353
|
+
case "create_pix_deposit":
|
|
354
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/accounts/brl/pix/deposits", undefined, args), null, 2) }] };
|
|
355
|
+
case "list_pix_deposits":
|
|
356
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts/brl/pix/deposits", args), null, 2) }] };
|
|
357
|
+
case "create_pix_withdrawal":
|
|
358
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/accounts/brl/pix/withdrawals", undefined, args), null, 2) }] };
|
|
359
|
+
case "list_pix_withdrawals":
|
|
360
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts/brl/pix/withdrawals", args), null, 2) }] };
|
|
361
|
+
case "create_crypto_withdrawal": {
|
|
362
|
+
const { currency_symbol, ...rest } = (args || {});
|
|
363
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", `/accounts/${currency_symbol}/withdrawals`, undefined, rest), null, 2) }] };
|
|
364
|
+
}
|
|
365
|
+
case "get_trading_fees":
|
|
366
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/system/fees-and-limits"), null, 2) }] };
|
|
211
367
|
default:
|
|
212
368
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
213
369
|
}
|
|
@@ -234,7 +390,7 @@ async function main() {
|
|
|
234
390
|
const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
|
|
235
391
|
t.onclose = () => { if (t.sessionId)
|
|
236
392
|
transports.delete(t.sessionId); };
|
|
237
|
-
const s = new Server({ name: "mcp-foxbit", version: "0.
|
|
393
|
+
const s = new Server({ name: "mcp-foxbit", version: "0.2.0" }, { capabilities: { tools: {} } });
|
|
238
394
|
server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v));
|
|
239
395
|
server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v));
|
|
240
396
|
await s.connect(t);
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/crypto/foxbit"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.2.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "@codespar/mcp-foxbit",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.2.0",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
package/src/index.ts
CHANGED
|
@@ -4,16 +4,19 @@
|
|
|
4
4
|
* MCP Server for Foxbit — Brazilian cryptocurrency exchange.
|
|
5
5
|
*
|
|
6
6
|
* Tools:
|
|
7
|
-
*
|
|
8
|
-
* -
|
|
9
|
-
* - get_orderbook
|
|
10
|
-
*
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
* -
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
*
|
|
7
|
+
* Public market data:
|
|
8
|
+
* - list_markets, list_currencies, get_currency, list_pairs
|
|
9
|
+
* - get_ticker, get_orderbook, get_market_trades, get_candles
|
|
10
|
+
* Account & balances:
|
|
11
|
+
* - get_account_balances, get_balance
|
|
12
|
+
* Orders & trades:
|
|
13
|
+
* - create_order, get_order, list_orders, cancel_order, list_trades
|
|
14
|
+
* Pix (BR instant payments):
|
|
15
|
+
* - create_pix_deposit, list_pix_deposits, create_pix_withdrawal, list_pix_withdrawals
|
|
16
|
+
* Crypto withdrawals & transactions:
|
|
17
|
+
* - create_crypto_withdrawal, list_deposits_withdrawals
|
|
18
|
+
* Fees:
|
|
19
|
+
* - get_trading_fees
|
|
17
20
|
*
|
|
18
21
|
* Environment:
|
|
19
22
|
* FOXBIT_API_KEY — API key from https://app.foxbit.com.br/
|
|
@@ -75,7 +78,7 @@ async function foxbitRequest(
|
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
const server = new Server(
|
|
78
|
-
{ name: "mcp-foxbit", version: "0.
|
|
81
|
+
{ name: "mcp-foxbit", version: "0.2.0" },
|
|
79
82
|
{ capabilities: { tools: {} } },
|
|
80
83
|
);
|
|
81
84
|
|
|
@@ -86,6 +89,22 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
86
89
|
description: "List all available trading pairs / markets on Foxbit",
|
|
87
90
|
inputSchema: { type: "object", properties: {} },
|
|
88
91
|
},
|
|
92
|
+
{
|
|
93
|
+
name: "list_currencies",
|
|
94
|
+
description: "List all supported currencies (crypto and fiat) on Foxbit",
|
|
95
|
+
inputSchema: { type: "object", properties: {} },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "get_currency",
|
|
99
|
+
description: "Get details of a specific currency (precision, min/max amounts, type)",
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: "object",
|
|
102
|
+
properties: {
|
|
103
|
+
symbol: { type: "string", description: "Currency symbol (e.g. btc, brl, eth)" },
|
|
104
|
+
},
|
|
105
|
+
required: ["symbol"],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
89
108
|
{
|
|
90
109
|
name: "get_ticker",
|
|
91
110
|
description: "Get 24h ticker data for a market (price, volume, high/low)",
|
|
@@ -109,11 +128,50 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
109
128
|
required: ["symbol"],
|
|
110
129
|
},
|
|
111
130
|
},
|
|
131
|
+
{
|
|
132
|
+
name: "get_market_trades",
|
|
133
|
+
description: "Get recent public trades for a market (trade history / tape)",
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: "object",
|
|
136
|
+
properties: {
|
|
137
|
+
symbol: { type: "string", description: "Market symbol (e.g. btcbrl)" },
|
|
138
|
+
page_size: { type: "number", description: "Results per page (max 100)" },
|
|
139
|
+
page: { type: "number", description: "Page number" },
|
|
140
|
+
},
|
|
141
|
+
required: ["symbol"],
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "get_candles",
|
|
146
|
+
description: "Get OHLC candlestick data for a market",
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: "object",
|
|
149
|
+
properties: {
|
|
150
|
+
symbol: { type: "string", description: "Market symbol (e.g. btcbrl)" },
|
|
151
|
+
interval: { type: "string", enum: ["1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d", "1w"], description: "Candle interval" },
|
|
152
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
153
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
154
|
+
limit: { type: "number", description: "Max number of candles to return" },
|
|
155
|
+
},
|
|
156
|
+
required: ["symbol", "interval"],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
112
159
|
{
|
|
113
160
|
name: "get_account_balances",
|
|
114
161
|
description: "Get account balances for all currencies",
|
|
115
162
|
inputSchema: { type: "object", properties: {} },
|
|
116
163
|
},
|
|
164
|
+
{
|
|
165
|
+
name: "get_balance",
|
|
166
|
+
description: "Get account balance for a single currency",
|
|
167
|
+
inputSchema: {
|
|
168
|
+
type: "object",
|
|
169
|
+
properties: {
|
|
170
|
+
currency_symbol: { type: "string", description: "Currency symbol (e.g. brl, btc, eth)" },
|
|
171
|
+
},
|
|
172
|
+
required: ["currency_symbol"],
|
|
173
|
+
},
|
|
174
|
+
},
|
|
117
175
|
{
|
|
118
176
|
name: "create_order",
|
|
119
177
|
description: "Create a buy or sell order (limit or market)",
|
|
@@ -171,7 +229,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
171
229
|
},
|
|
172
230
|
{
|
|
173
231
|
name: "list_trades",
|
|
174
|
-
description: "List user's executed trades",
|
|
232
|
+
description: "List user's executed trades (private trade history)",
|
|
175
233
|
inputSchema: {
|
|
176
234
|
type: "object",
|
|
177
235
|
properties: {
|
|
@@ -199,6 +257,76 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
199
257
|
required: ["currency_symbol"],
|
|
200
258
|
},
|
|
201
259
|
},
|
|
260
|
+
{
|
|
261
|
+
name: "create_pix_deposit",
|
|
262
|
+
description: "Create a Pix instant deposit (BRL). Returns Pix QR code / copy-paste payload.",
|
|
263
|
+
inputSchema: {
|
|
264
|
+
type: "object",
|
|
265
|
+
properties: {
|
|
266
|
+
amount: { type: "string", description: "Deposit amount in BRL (e.g. \"100.00\")" },
|
|
267
|
+
},
|
|
268
|
+
required: ["amount"],
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "list_pix_deposits",
|
|
273
|
+
description: "List Pix deposit history (BRL instant deposits)",
|
|
274
|
+
inputSchema: {
|
|
275
|
+
type: "object",
|
|
276
|
+
properties: {
|
|
277
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
278
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
279
|
+
page_size: { type: "number", description: "Results per page" },
|
|
280
|
+
page: { type: "number", description: "Page number" },
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: "create_pix_withdrawal",
|
|
286
|
+
description: "Create a Pix withdrawal (BRL) to a Pix key",
|
|
287
|
+
inputSchema: {
|
|
288
|
+
type: "object",
|
|
289
|
+
properties: {
|
|
290
|
+
amount: { type: "string", description: "Withdrawal amount in BRL (e.g. \"100.00\")" },
|
|
291
|
+
pix_key: { type: "string", description: "Destination Pix key (CPF, CNPJ, email, phone, or random key)" },
|
|
292
|
+
pix_key_type: { type: "string", enum: ["CPF", "CNPJ", "EMAIL", "PHONE", "EVP"], description: "Pix key type" },
|
|
293
|
+
},
|
|
294
|
+
required: ["amount", "pix_key", "pix_key_type"],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "list_pix_withdrawals",
|
|
299
|
+
description: "List Pix withdrawal history (BRL fiat withdrawals)",
|
|
300
|
+
inputSchema: {
|
|
301
|
+
type: "object",
|
|
302
|
+
properties: {
|
|
303
|
+
start_time: { type: "string", description: "Start time (ISO 8601)" },
|
|
304
|
+
end_time: { type: "string", description: "End time (ISO 8601)" },
|
|
305
|
+
page_size: { type: "number", description: "Results per page" },
|
|
306
|
+
page: { type: "number", description: "Page number" },
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "create_crypto_withdrawal",
|
|
312
|
+
description: "Create a crypto withdrawal to an external wallet address",
|
|
313
|
+
inputSchema: {
|
|
314
|
+
type: "object",
|
|
315
|
+
properties: {
|
|
316
|
+
currency_symbol: { type: "string", description: "Currency symbol (e.g. btc, eth, usdt)" },
|
|
317
|
+
amount: { type: "string", description: "Withdrawal amount in base units" },
|
|
318
|
+
address: { type: "string", description: "Destination wallet address" },
|
|
319
|
+
network: { type: "string", description: "Blockchain network (e.g. BTC, ERC20, TRC20, POLYGON)" },
|
|
320
|
+
tag: { type: "string", description: "Memo / tag / destination tag (for XRP, XLM, etc.)" },
|
|
321
|
+
},
|
|
322
|
+
required: ["currency_symbol", "amount", "address"],
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: "get_trading_fees",
|
|
327
|
+
description: "Get current trading fees and limits (maker/taker per pair, withdrawal limits)",
|
|
328
|
+
inputSchema: { type: "object", properties: {} },
|
|
329
|
+
},
|
|
202
330
|
],
|
|
203
331
|
}));
|
|
204
332
|
|
|
@@ -209,12 +337,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
209
337
|
switch (name) {
|
|
210
338
|
case "list_markets":
|
|
211
339
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/markets"), null, 2) }] };
|
|
340
|
+
case "list_currencies":
|
|
341
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/currencies"), null, 2) }] };
|
|
342
|
+
case "get_currency":
|
|
343
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/currencies/${args?.symbol}`), null, 2) }] };
|
|
212
344
|
case "get_ticker":
|
|
213
345
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${args?.symbol}/ticker/24hr`), null, 2) }] };
|
|
214
346
|
case "get_orderbook":
|
|
215
347
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${args?.symbol}/orderbook`, { depth: args?.depth as number | undefined }), null, 2) }] };
|
|
348
|
+
case "get_market_trades": {
|
|
349
|
+
const { symbol, ...rest } = (args || {}) as Record<string, string | number | undefined>;
|
|
350
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${symbol}/trades`, rest), null, 2) }] };
|
|
351
|
+
}
|
|
352
|
+
case "get_candles": {
|
|
353
|
+
const { symbol, ...rest } = (args || {}) as Record<string, string | number | undefined>;
|
|
354
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/markets/${symbol}/candlesticks`, rest), null, 2) }] };
|
|
355
|
+
}
|
|
216
356
|
case "get_account_balances":
|
|
217
357
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts"), null, 2) }] };
|
|
358
|
+
case "get_balance":
|
|
359
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/accounts/${args?.currency_symbol}`), null, 2) }] };
|
|
218
360
|
case "create_order":
|
|
219
361
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/orders", undefined, args), null, 2) }] };
|
|
220
362
|
case "get_order":
|
|
@@ -229,6 +371,20 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
229
371
|
const { currency_symbol, ...rest } = (args || {}) as Record<string, string | number | undefined>;
|
|
230
372
|
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", `/accounts/${currency_symbol}/transactions`, rest), null, 2) }] };
|
|
231
373
|
}
|
|
374
|
+
case "create_pix_deposit":
|
|
375
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/accounts/brl/pix/deposits", undefined, args), null, 2) }] };
|
|
376
|
+
case "list_pix_deposits":
|
|
377
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts/brl/pix/deposits", args as Record<string, string | number | undefined>), null, 2) }] };
|
|
378
|
+
case "create_pix_withdrawal":
|
|
379
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", "/accounts/brl/pix/withdrawals", undefined, args), null, 2) }] };
|
|
380
|
+
case "list_pix_withdrawals":
|
|
381
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/accounts/brl/pix/withdrawals", args as Record<string, string | number | undefined>), null, 2) }] };
|
|
382
|
+
case "create_crypto_withdrawal": {
|
|
383
|
+
const { currency_symbol, ...rest } = (args || {}) as Record<string, unknown>;
|
|
384
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("POST", `/accounts/${currency_symbol}/withdrawals`, undefined, rest), null, 2) }] };
|
|
385
|
+
}
|
|
386
|
+
case "get_trading_fees":
|
|
387
|
+
return { content: [{ type: "text", text: JSON.stringify(await foxbitRequest("GET", "/system/fees-and-limits"), null, 2) }] };
|
|
232
388
|
default:
|
|
233
389
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
234
390
|
}
|
|
@@ -251,7 +407,7 @@ async function main() {
|
|
|
251
407
|
if (!sid && isInitializeRequest(req.body)) {
|
|
252
408
|
const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } });
|
|
253
409
|
t.onclose = () => { if (t.sessionId) transports.delete(t.sessionId); };
|
|
254
|
-
const s = new Server({ name: "mcp-foxbit", version: "0.
|
|
410
|
+
const s = new Server({ name: "mcp-foxbit", 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);
|
|
255
411
|
await t.handleRequest(req, res, req.body); return;
|
|
256
412
|
}
|
|
257
413
|
res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null });
|