@guiie/buda-mcp 1.4.2 → 1.5.1
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/.cursor/rules/marketplace-docs-sync.mdc +32 -0
- package/CHANGELOG.md +79 -0
- package/PUBLISH_CHECKLIST.md +40 -88
- package/README.md +446 -78
- package/dist/cache.d.ts +1 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +18 -1
- package/dist/http.js +97 -6
- package/dist/index.js +42 -3
- package/dist/tools/account.d.ts +19 -0
- package/dist/tools/account.d.ts.map +1 -0
- package/dist/tools/account.js +49 -0
- package/dist/tools/balance.d.ts +29 -0
- package/dist/tools/balance.d.ts.map +1 -0
- package/dist/tools/balance.js +72 -0
- package/dist/tools/banks.d.ts +28 -0
- package/dist/tools/banks.d.ts.map +1 -0
- package/dist/tools/banks.js +68 -0
- package/dist/tools/batch_orders.d.ts +82 -0
- package/dist/tools/batch_orders.d.ts.map +1 -0
- package/dist/tools/batch_orders.js +188 -0
- package/dist/tools/cancel_all_orders.d.ts +34 -0
- package/dist/tools/cancel_all_orders.d.ts.map +1 -0
- package/dist/tools/cancel_all_orders.js +89 -0
- package/dist/tools/cancel_order.js +1 -1
- package/dist/tools/cancel_order_by_client_id.d.ts +34 -0
- package/dist/tools/cancel_order_by_client_id.d.ts.map +1 -0
- package/dist/tools/cancel_order_by_client_id.js +102 -0
- package/dist/tools/dead_mans_switch.d.ts +1 -1
- package/dist/tools/dead_mans_switch.d.ts.map +1 -1
- package/dist/tools/dead_mans_switch.js +33 -3
- package/dist/tools/deposits.d.ts +83 -0
- package/dist/tools/deposits.d.ts.map +1 -0
- package/dist/tools/deposits.js +174 -0
- package/dist/tools/fees.d.ts +34 -0
- package/dist/tools/fees.d.ts.map +1 -0
- package/dist/tools/fees.js +72 -0
- package/dist/tools/lightning.d.ts +68 -0
- package/dist/tools/lightning.d.ts.map +1 -0
- package/dist/tools/lightning.js +185 -0
- package/dist/tools/order_lookup.d.ts +50 -0
- package/dist/tools/order_lookup.d.ts.map +1 -0
- package/dist/tools/order_lookup.js +112 -0
- package/dist/tools/place_order.d.ts +30 -0
- package/dist/tools/place_order.d.ts.map +1 -1
- package/dist/tools/place_order.js +131 -2
- package/dist/tools/quotation.d.ts +44 -0
- package/dist/tools/quotation.d.ts.map +1 -0
- package/dist/tools/quotation.js +99 -0
- package/dist/tools/receive_addresses.d.ts +83 -0
- package/dist/tools/receive_addresses.d.ts.map +1 -0
- package/dist/tools/receive_addresses.js +185 -0
- package/dist/tools/remittance_recipients.d.ts +54 -0
- package/dist/tools/remittance_recipients.d.ts.map +1 -0
- package/dist/tools/remittance_recipients.js +106 -0
- package/dist/tools/remittances.d.ts +120 -0
- package/dist/tools/remittances.d.ts.map +1 -0
- package/dist/tools/remittances.js +261 -0
- package/dist/tools/simulate_order.d.ts.map +1 -1
- package/dist/tools/simulate_order.js +2 -1
- package/dist/tools/technical_indicators.d.ts.map +1 -1
- package/dist/tools/technical_indicators.js +2 -1
- package/dist/tools/withdrawals.d.ts +93 -0
- package/dist/tools/withdrawals.d.ts.map +1 -0
- package/dist/tools/withdrawals.js +225 -0
- package/dist/types.d.ts +155 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +4 -1
- package/dist/validation.d.ts +11 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +38 -0
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +8 -1
- package/marketplace/README.md +1 -1
- package/marketplace/claude-listing.md +101 -2
- package/marketplace/gemini-tools.json +478 -1
- package/marketplace/openapi.yaml +160 -1
- package/package.json +2 -1
- package/server.json +2 -2
- package/src/cache.ts +1 -0
- package/src/client.ts +23 -1
- package/src/http.ts +105 -6
- package/src/index.ts +40 -3
- package/src/tools/account.ts +66 -0
- package/src/tools/balance.ts +94 -0
- package/src/tools/banks.ts +94 -0
- package/src/tools/batch_orders.ts +238 -0
- package/src/tools/cancel_all_orders.ts +117 -0
- package/src/tools/cancel_order.ts +1 -1
- package/src/tools/cancel_order_by_client_id.ts +132 -0
- package/src/tools/dead_mans_switch.ts +39 -3
- package/src/tools/deposits.ts +230 -0
- package/src/tools/fees.ts +91 -0
- package/src/tools/lightning.ts +247 -0
- package/src/tools/order_lookup.ts +139 -0
- package/src/tools/place_order.ts +151 -2
- package/src/tools/quotation.ts +124 -0
- package/src/tools/receive_addresses.ts +242 -0
- package/src/tools/remittance_recipients.ts +139 -0
- package/src/tools/remittances.ts +325 -0
- package/src/tools/simulate_order.ts +1 -0
- package/src/tools/technical_indicators.ts +2 -1
- package/src/tools/withdrawals.ts +287 -0
- package/src/types.ts +210 -0
- package/src/utils.ts +3 -1
- package/src/validation.ts +45 -0
- package/src/version.ts +11 -3
- package/test/run-all.ts +16 -0
- package/test/unit.ts +2149 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BudaApiError } from "../client.js";
|
|
3
|
+
import { flattenAmount } from "../utils.js";
|
|
4
|
+
export const getOrderToolSchema = {
|
|
5
|
+
name: "get_order",
|
|
6
|
+
description: "Returns a single order by its numeric ID on Buda.com. " +
|
|
7
|
+
"Fetches full detail including state, amounts, fees, and timestamps. " +
|
|
8
|
+
"All monetary amounts are floats with separate _currency fields. " +
|
|
9
|
+
"Requires BUDA_API_KEY and BUDA_API_SECRET. " +
|
|
10
|
+
"Example: 'Show me the details of order 987654.'",
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: "object",
|
|
13
|
+
properties: {
|
|
14
|
+
order_id: {
|
|
15
|
+
type: "number",
|
|
16
|
+
description: "The numeric ID of the order.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ["order_id"],
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export const getOrderByClientIdToolSchema = {
|
|
23
|
+
name: "get_order_by_client_id",
|
|
24
|
+
description: "Returns an order by the client-assigned ID you set at placement on Buda.com. " +
|
|
25
|
+
"All monetary amounts are floats with separate _currency fields. " +
|
|
26
|
+
"Requires BUDA_API_KEY and BUDA_API_SECRET. " +
|
|
27
|
+
"Example: 'Find my order with client ID my-bot-order-42.'",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
client_id: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "The client ID string assigned when placing the order.",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
required: ["client_id"],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
function normalizeOrder(o) {
|
|
40
|
+
const amount = flattenAmount(o.amount);
|
|
41
|
+
const originalAmount = flattenAmount(o.original_amount);
|
|
42
|
+
const tradedAmount = flattenAmount(o.traded_amount);
|
|
43
|
+
const totalExchanged = flattenAmount(o.total_exchanged);
|
|
44
|
+
const paidFee = flattenAmount(o.paid_fee);
|
|
45
|
+
const limitPrice = o.limit ? flattenAmount(o.limit) : null;
|
|
46
|
+
return {
|
|
47
|
+
id: o.id,
|
|
48
|
+
type: o.type,
|
|
49
|
+
state: o.state,
|
|
50
|
+
created_at: o.created_at,
|
|
51
|
+
market_id: o.market_id,
|
|
52
|
+
fee_currency: o.fee_currency,
|
|
53
|
+
price_type: o.price_type,
|
|
54
|
+
order_type: o.order_type,
|
|
55
|
+
client_id: o.client_id,
|
|
56
|
+
limit_price: limitPrice ? limitPrice.value : null,
|
|
57
|
+
limit_price_currency: limitPrice ? limitPrice.currency : null,
|
|
58
|
+
amount: amount.value,
|
|
59
|
+
amount_currency: amount.currency,
|
|
60
|
+
original_amount: originalAmount.value,
|
|
61
|
+
original_amount_currency: originalAmount.currency,
|
|
62
|
+
traded_amount: tradedAmount.value,
|
|
63
|
+
traded_amount_currency: tradedAmount.currency,
|
|
64
|
+
total_exchanged: totalExchanged.value,
|
|
65
|
+
total_exchanged_currency: totalExchanged.currency,
|
|
66
|
+
paid_fee: paidFee.value,
|
|
67
|
+
paid_fee_currency: paidFee.currency,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export async function handleGetOrder(args, client) {
|
|
71
|
+
try {
|
|
72
|
+
const data = await client.get(`/orders/${args.order_id}`);
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text", text: JSON.stringify(normalizeOrder(data.order), null, 2) }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const msg = err instanceof BudaApiError
|
|
79
|
+
? { error: err.message, code: err.status, path: err.path }
|
|
80
|
+
: { error: String(err), code: "UNKNOWN" };
|
|
81
|
+
return {
|
|
82
|
+
content: [{ type: "text", text: JSON.stringify(msg) }],
|
|
83
|
+
isError: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function handleGetOrderByClientId(args, client) {
|
|
88
|
+
try {
|
|
89
|
+
const data = await client.get(`/orders/by-client-id/${encodeURIComponent(args.client_id)}`);
|
|
90
|
+
return {
|
|
91
|
+
content: [{ type: "text", text: JSON.stringify(normalizeOrder(data.order), null, 2) }],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
const msg = err instanceof BudaApiError
|
|
96
|
+
? { error: err.message, code: err.status, path: err.path }
|
|
97
|
+
: { error: String(err), code: "UNKNOWN" };
|
|
98
|
+
return {
|
|
99
|
+
content: [{ type: "text", text: JSON.stringify(msg) }],
|
|
100
|
+
isError: true,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export function register(server, client) {
|
|
105
|
+
server.tool(getOrderToolSchema.name, getOrderToolSchema.description, {
|
|
106
|
+
order_id: z.number().int().positive().describe("The numeric ID of the order."),
|
|
107
|
+
}, (args) => handleGetOrder(args, client));
|
|
108
|
+
server.tool(getOrderByClientIdToolSchema.name, getOrderByClientIdToolSchema.description, {
|
|
109
|
+
client_id: z.string().min(1).describe("The client ID string assigned when placing the order."),
|
|
110
|
+
}, (args) => handleGetOrderByClientId(args, client));
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=order_lookup.js.map
|
|
@@ -26,6 +26,30 @@ export declare const toolSchema: {
|
|
|
26
26
|
type: string;
|
|
27
27
|
description: string;
|
|
28
28
|
};
|
|
29
|
+
ioc: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
fok: {
|
|
34
|
+
type: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
post_only: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
gtd_timestamp: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
stop_price: {
|
|
46
|
+
type: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
stop_type: {
|
|
50
|
+
type: string;
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
29
53
|
confirmation_token: {
|
|
30
54
|
type: string;
|
|
31
55
|
description: string;
|
|
@@ -40,6 +64,12 @@ type PlaceOrderArgs = {
|
|
|
40
64
|
price_type: "limit" | "market";
|
|
41
65
|
amount: number;
|
|
42
66
|
limit_price?: number;
|
|
67
|
+
ioc?: boolean;
|
|
68
|
+
fok?: boolean;
|
|
69
|
+
post_only?: boolean;
|
|
70
|
+
gtd_timestamp?: string;
|
|
71
|
+
stop_price?: number;
|
|
72
|
+
stop_type?: ">=" | "<=";
|
|
43
73
|
confirmation_token: string;
|
|
44
74
|
};
|
|
45
75
|
export declare function handlePlaceOrder(args: PlaceOrderArgs, client: BudaClient): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"place_order.d.ts","sourceRoot":"","sources":["../../src/tools/place_order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AAIxD,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"place_order.d.ts","sourceRoot":"","sources":["../../src/tools/place_order.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AAIxD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEtB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;IACpB,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqKhF;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA4DpE"}
|
|
@@ -4,6 +4,7 @@ import { validateMarketId } from "../validation.js";
|
|
|
4
4
|
export const toolSchema = {
|
|
5
5
|
name: "place_order",
|
|
6
6
|
description: "Place a limit or market order on Buda.com. " +
|
|
7
|
+
"Supports optional time-in-force flags (ioc, fok, post_only, gtd_timestamp) and stop orders. " +
|
|
7
8
|
"IMPORTANT: To prevent accidental execution from ambiguous prompts, you must pass " +
|
|
8
9
|
"confirmation_token='CONFIRM' to execute the order. " +
|
|
9
10
|
"Requires BUDA_API_KEY and BUDA_API_SECRET environment variables. " +
|
|
@@ -32,6 +33,30 @@ export const toolSchema = {
|
|
|
32
33
|
description: "Limit price in quote currency. Required when price_type is 'limit'. " +
|
|
33
34
|
"For Bid orders: highest price you will pay. For Ask orders: lowest price you will accept.",
|
|
34
35
|
},
|
|
36
|
+
ioc: {
|
|
37
|
+
type: "boolean",
|
|
38
|
+
description: "Immediate-or-cancel: fill as much as possible, cancel the rest. Mutually exclusive with fok, post_only, gtd_timestamp.",
|
|
39
|
+
},
|
|
40
|
+
fok: {
|
|
41
|
+
type: "boolean",
|
|
42
|
+
description: "Fill-or-kill: fill the entire order or cancel it entirely. Mutually exclusive with ioc, post_only, gtd_timestamp.",
|
|
43
|
+
},
|
|
44
|
+
post_only: {
|
|
45
|
+
type: "boolean",
|
|
46
|
+
description: "Post-only: rejected if it would execute immediately as a taker. Mutually exclusive with ioc, fok, gtd_timestamp.",
|
|
47
|
+
},
|
|
48
|
+
gtd_timestamp: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Good-till-date: ISO 8601 datetime after which the order is canceled. Mutually exclusive with ioc, fok, post_only.",
|
|
51
|
+
},
|
|
52
|
+
stop_price: {
|
|
53
|
+
type: "number",
|
|
54
|
+
description: "Stop trigger price. Must be paired with stop_type.",
|
|
55
|
+
},
|
|
56
|
+
stop_type: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "Stop trigger direction: '>=' triggers when price rises to stop_price, '<=' when it falls. Must be paired with stop_price.",
|
|
59
|
+
},
|
|
35
60
|
confirmation_token: {
|
|
36
61
|
type: "string",
|
|
37
62
|
description: "Safety confirmation. Must equal exactly 'CONFIRM' (case-sensitive) to execute the order. " +
|
|
@@ -42,7 +67,7 @@ export const toolSchema = {
|
|
|
42
67
|
},
|
|
43
68
|
};
|
|
44
69
|
export async function handlePlaceOrder(args, client) {
|
|
45
|
-
const { market_id, type, price_type, amount, limit_price, confirmation_token } = args;
|
|
70
|
+
const { market_id, type, price_type, amount, limit_price, ioc, fok, post_only, gtd_timestamp, stop_price, stop_type, confirmation_token, } = args;
|
|
46
71
|
if (confirmation_token !== "CONFIRM") {
|
|
47
72
|
return {
|
|
48
73
|
content: [
|
|
@@ -66,6 +91,39 @@ export async function handlePlaceOrder(args, client) {
|
|
|
66
91
|
isError: true,
|
|
67
92
|
};
|
|
68
93
|
}
|
|
94
|
+
// Validate TIF mutual exclusivity
|
|
95
|
+
const tifFlags = [ioc, fok, post_only, gtd_timestamp !== undefined].filter(Boolean);
|
|
96
|
+
if (tifFlags.length > 1) {
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: "text",
|
|
101
|
+
text: JSON.stringify({
|
|
102
|
+
error: "ioc, fok, post_only, and gtd_timestamp are mutually exclusive. Specify at most one.",
|
|
103
|
+
code: "VALIDATION_ERROR",
|
|
104
|
+
}),
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Validate stop_price / stop_type must both be present or both absent
|
|
111
|
+
const hasStopPrice = stop_price !== undefined;
|
|
112
|
+
const hasStopType = stop_type !== undefined;
|
|
113
|
+
if (hasStopPrice !== hasStopType) {
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
text: JSON.stringify({
|
|
119
|
+
error: "stop_price and stop_type must both be provided together.",
|
|
120
|
+
code: "VALIDATION_ERROR",
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
isError: true,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
69
127
|
try {
|
|
70
128
|
const payload = {
|
|
71
129
|
type,
|
|
@@ -87,7 +145,53 @@ export async function handlePlaceOrder(args, client) {
|
|
|
87
145
|
isError: true,
|
|
88
146
|
};
|
|
89
147
|
}
|
|
90
|
-
|
|
148
|
+
if (gtd_timestamp !== undefined) {
|
|
149
|
+
const ts = new Date(gtd_timestamp).getTime();
|
|
150
|
+
if (isNaN(ts)) {
|
|
151
|
+
return {
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: "text",
|
|
155
|
+
text: JSON.stringify({
|
|
156
|
+
error: "gtd_timestamp must be a valid ISO 8601 datetime string.",
|
|
157
|
+
code: "VALIDATION_ERROR",
|
|
158
|
+
}),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
isError: true,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (ts <= Date.now()) {
|
|
165
|
+
return {
|
|
166
|
+
content: [
|
|
167
|
+
{
|
|
168
|
+
type: "text",
|
|
169
|
+
text: JSON.stringify({
|
|
170
|
+
error: "gtd_timestamp must be a future datetime.",
|
|
171
|
+
code: "VALIDATION_ERROR",
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
isError: true,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
let limitType = "gtc";
|
|
180
|
+
if (ioc)
|
|
181
|
+
limitType = "ioc";
|
|
182
|
+
else if (fok)
|
|
183
|
+
limitType = "fok";
|
|
184
|
+
else if (post_only)
|
|
185
|
+
limitType = "post_only";
|
|
186
|
+
else if (gtd_timestamp !== undefined)
|
|
187
|
+
limitType = "gtd";
|
|
188
|
+
const limitObj = { price: limit_price, type: limitType };
|
|
189
|
+
if (gtd_timestamp !== undefined)
|
|
190
|
+
limitObj.expiration = gtd_timestamp;
|
|
191
|
+
payload.limit = limitObj;
|
|
192
|
+
}
|
|
193
|
+
if (hasStopPrice && hasStopType) {
|
|
194
|
+
payload.stop = { price: stop_price, type: stop_type };
|
|
91
195
|
}
|
|
92
196
|
const data = await client.post(`/markets/${market_id.toLowerCase()}/orders`, payload);
|
|
93
197
|
return {
|
|
@@ -125,6 +229,31 @@ export function register(server, client) {
|
|
|
125
229
|
.optional()
|
|
126
230
|
.describe("Limit price in quote currency. Required when price_type is 'limit'. " +
|
|
127
231
|
"For Bid orders: highest price you will pay. For Ask orders: lowest price you will accept."),
|
|
232
|
+
ioc: z
|
|
233
|
+
.boolean()
|
|
234
|
+
.optional()
|
|
235
|
+
.describe("Immediate-or-cancel: fill as much as possible, cancel the rest. Mutually exclusive with fok, post_only, gtd_timestamp."),
|
|
236
|
+
fok: z
|
|
237
|
+
.boolean()
|
|
238
|
+
.optional()
|
|
239
|
+
.describe("Fill-or-kill: fill the entire order or cancel it entirely. Mutually exclusive with ioc, post_only, gtd_timestamp."),
|
|
240
|
+
post_only: z
|
|
241
|
+
.boolean()
|
|
242
|
+
.optional()
|
|
243
|
+
.describe("Post-only: rejected if it would execute immediately as a taker. Mutually exclusive with ioc, fok, gtd_timestamp."),
|
|
244
|
+
gtd_timestamp: z
|
|
245
|
+
.string()
|
|
246
|
+
.optional()
|
|
247
|
+
.describe("Good-till-date: ISO 8601 datetime after which the order is canceled. Mutually exclusive with ioc, fok, post_only."),
|
|
248
|
+
stop_price: z
|
|
249
|
+
.number()
|
|
250
|
+
.positive()
|
|
251
|
+
.optional()
|
|
252
|
+
.describe("Stop trigger price. Must be paired with stop_type."),
|
|
253
|
+
stop_type: z
|
|
254
|
+
.enum([">=", "<="])
|
|
255
|
+
.optional()
|
|
256
|
+
.describe("Stop trigger direction: '>=' triggers when price rises to stop_price, '<=' when it falls. Must be paired with stop_price."),
|
|
128
257
|
confirmation_token: z
|
|
129
258
|
.string()
|
|
130
259
|
.describe("Safety confirmation. Must equal exactly 'CONFIRM' (case-sensitive) to execute the order. " +
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { BudaClient } from "../client.js";
|
|
3
|
+
export declare const toolSchema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object";
|
|
8
|
+
properties: {
|
|
9
|
+
market_id: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
type: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
amount: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
limit: {
|
|
22
|
+
type: string;
|
|
23
|
+
description: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
required: string[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
type GetRealQuotationArgs = {
|
|
30
|
+
market_id: string;
|
|
31
|
+
type: "Bid" | "Ask";
|
|
32
|
+
amount: number;
|
|
33
|
+
limit?: number;
|
|
34
|
+
};
|
|
35
|
+
export declare function handleGetRealQuotation(args: GetRealQuotationArgs, client: BudaClient): Promise<{
|
|
36
|
+
content: Array<{
|
|
37
|
+
type: "text";
|
|
38
|
+
text: string;
|
|
39
|
+
}>;
|
|
40
|
+
isError?: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
export declare function register(server: McpServer, client: BudaClient): void;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=quotation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotation.d.ts","sourceRoot":"","sources":["../../src/tools/quotation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AAKxD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;CA+BtB,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CA2DhF;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAYpE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BudaApiError } from "../client.js";
|
|
3
|
+
import { validateMarketId } from "../validation.js";
|
|
4
|
+
import { flattenAmount } from "../utils.js";
|
|
5
|
+
export const toolSchema = {
|
|
6
|
+
name: "get_real_quotation",
|
|
7
|
+
description: "Gets a server-side price quotation for a buy or sell on Buda.com. " +
|
|
8
|
+
"Calls the Buda quotation API to compute an accurate fill estimate including fees, " +
|
|
9
|
+
"based on live order book state. Prefer this over simulate_order for accurate fee-tier-aware quotes. " +
|
|
10
|
+
"This is a POST (not idempotent) but does not place an order. Public endpoint — no API key required. " +
|
|
11
|
+
"Parameters: market_id, type ('Bid'|'Ask'), amount, optional limit price. " +
|
|
12
|
+
"Example: 'Get an accurate quote to sell 0.05 BTC on BTC-CLP.'",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
market_id: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Market ID (e.g. 'BTC-CLP', 'ETH-BTC').",
|
|
19
|
+
},
|
|
20
|
+
type: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "'Bid' to buy base currency, 'Ask' to sell base currency.",
|
|
23
|
+
},
|
|
24
|
+
amount: {
|
|
25
|
+
type: "number",
|
|
26
|
+
description: "Order size (positive number).",
|
|
27
|
+
},
|
|
28
|
+
limit: {
|
|
29
|
+
type: "number",
|
|
30
|
+
description: "Optional limit price in quote currency.",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
required: ["market_id", "type", "amount"],
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export async function handleGetRealQuotation(args, client) {
|
|
37
|
+
const { market_id, type, amount, limit } = args;
|
|
38
|
+
const validationError = validateMarketId(market_id);
|
|
39
|
+
if (validationError) {
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: "text", text: JSON.stringify({ error: validationError, code: "INVALID_MARKET_ID" }) }],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const id = market_id.toLowerCase();
|
|
46
|
+
const payload = { type, amount: String(amount) };
|
|
47
|
+
if (limit !== undefined)
|
|
48
|
+
payload.limit = String(limit);
|
|
49
|
+
try {
|
|
50
|
+
const data = await client.post(`/markets/${id}/quotations`, {
|
|
51
|
+
quotation: payload,
|
|
52
|
+
});
|
|
53
|
+
const q = data.quotation;
|
|
54
|
+
const flatAmount = flattenAmount(q.amount);
|
|
55
|
+
const flatLimit = q.limit ? flattenAmount(q.limit) : null;
|
|
56
|
+
const flatBase = flattenAmount(q.base_balance_change);
|
|
57
|
+
const flatQuote = flattenAmount(q.quote_balance_change);
|
|
58
|
+
const flatFee = flattenAmount(q.fee_amount);
|
|
59
|
+
const flatOrder = flattenAmount(q.order_amount);
|
|
60
|
+
const result = {
|
|
61
|
+
id: q.id ?? null,
|
|
62
|
+
type: q.type,
|
|
63
|
+
market_id: q.market_id,
|
|
64
|
+
amount: flatAmount.value,
|
|
65
|
+
amount_currency: flatAmount.currency,
|
|
66
|
+
limit: flatLimit ? flatLimit.value : null,
|
|
67
|
+
limit_currency: flatLimit ? flatLimit.currency : null,
|
|
68
|
+
base_balance_change: flatBase.value,
|
|
69
|
+
base_balance_change_currency: flatBase.currency,
|
|
70
|
+
quote_balance_change: flatQuote.value,
|
|
71
|
+
quote_balance_change_currency: flatQuote.currency,
|
|
72
|
+
fee_amount: flatFee.value,
|
|
73
|
+
fee_currency: flatFee.currency,
|
|
74
|
+
order_amount: flatOrder.value,
|
|
75
|
+
order_amount_currency: flatOrder.currency,
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const msg = err instanceof BudaApiError
|
|
83
|
+
? { error: err.message, code: err.status, path: err.path }
|
|
84
|
+
: { error: String(err), code: "UNKNOWN" };
|
|
85
|
+
return {
|
|
86
|
+
content: [{ type: "text", text: JSON.stringify(msg) }],
|
|
87
|
+
isError: true,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export function register(server, client) {
|
|
92
|
+
server.tool(toolSchema.name, toolSchema.description, {
|
|
93
|
+
market_id: z.string().describe("Market ID (e.g. 'BTC-CLP', 'ETH-BTC')."),
|
|
94
|
+
type: z.enum(["Bid", "Ask"]).describe("'Bid' to buy base currency, 'Ask' to sell base currency."),
|
|
95
|
+
amount: z.number().positive().describe("Order size (positive number)."),
|
|
96
|
+
limit: z.number().positive().optional().describe("Optional limit price in quote currency."),
|
|
97
|
+
}, (args) => handleGetRealQuotation(args, client));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=quotation.js.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { BudaClient } from "../client.js";
|
|
3
|
+
export declare const createReceiveAddressToolSchema: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object";
|
|
8
|
+
properties: {
|
|
9
|
+
currency: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
confirmation_token: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
required: string[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare const listReceiveAddressesToolSchema: {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
inputSchema: {
|
|
25
|
+
type: "object";
|
|
26
|
+
properties: {
|
|
27
|
+
currency: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
required: string[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare const getReceiveAddressToolSchema: {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
inputSchema: {
|
|
39
|
+
type: "object";
|
|
40
|
+
properties: {
|
|
41
|
+
currency: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
id: {
|
|
46
|
+
type: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
required: string[];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export declare function handleListReceiveAddresses(args: {
|
|
54
|
+
currency: string;
|
|
55
|
+
}, client: BudaClient): Promise<{
|
|
56
|
+
content: Array<{
|
|
57
|
+
type: "text";
|
|
58
|
+
text: string;
|
|
59
|
+
}>;
|
|
60
|
+
isError?: boolean;
|
|
61
|
+
}>;
|
|
62
|
+
export declare function handleGetReceiveAddress(args: {
|
|
63
|
+
currency: string;
|
|
64
|
+
id: number;
|
|
65
|
+
}, client: BudaClient): Promise<{
|
|
66
|
+
content: Array<{
|
|
67
|
+
type: "text";
|
|
68
|
+
text: string;
|
|
69
|
+
}>;
|
|
70
|
+
isError?: boolean;
|
|
71
|
+
}>;
|
|
72
|
+
export declare function handleCreateReceiveAddress(args: {
|
|
73
|
+
currency: string;
|
|
74
|
+
confirmation_token: string;
|
|
75
|
+
}, client: BudaClient): Promise<{
|
|
76
|
+
content: Array<{
|
|
77
|
+
type: "text";
|
|
78
|
+
text: string;
|
|
79
|
+
}>;
|
|
80
|
+
isError?: boolean;
|
|
81
|
+
}>;
|
|
82
|
+
export declare function register(server: McpServer, client: BudaClient): void;
|
|
83
|
+
//# sourceMappingURL=receive_addresses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receive_addresses.d.ts","sourceRoot":"","sources":["../../src/tools/receive_addresses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAgB,MAAM,cAAc,CAAC;AAIxD,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;CAwB1C,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;CAiB1C,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;CAoBvC,CAAC;AAYF,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC1B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqChF;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACtC,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CA4BhF;AAED,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,EACtD,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CA+ChF;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+BpE"}
|