@tongateway/mcp 0.20.0 → 0.21.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 +49 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -321,7 +321,7 @@ server.tool('transfer.pending', 'List all transfer requests waiting for wallet o
|
|
|
321
321
|
}
|
|
322
322
|
});
|
|
323
323
|
server.tool('transfer.batch', 'Send multiple TON transfers in a SINGLE wallet approval. Up to 4 transfers per batch (v4 wallet). All transfers appear as one transaction to sign. Use for batch payments, multi-recipient sends, or multiple DEX orders at once.', {
|
|
324
|
-
transfers: z.string().describe('JSON array of transfers: [{"to":"addr","amountNano":"1000000000","comment":"optional text"},...]'),
|
|
324
|
+
transfers: z.string().describe('JSON array of transfers: [{"to":"addr","amountNano":"1000000000","comment":"optional text","payload":"base64 BOC"},...]. Use payload for custom BOC (e.g. DEX close order), comment for text messages. payload takes precedence over comment.'),
|
|
325
325
|
}, { title: 'Batch Transfer', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async ({ transfers: transfersJson }) => {
|
|
326
326
|
if (!TOKEN) {
|
|
327
327
|
return { content: [{ type: 'text', text: 'No token configured. Use auth.request first.' }], isError: true };
|
|
@@ -332,11 +332,14 @@ server.tool('transfer.batch', 'Send multiple TON transfers in a SINGLE wallet ap
|
|
|
332
332
|
throw new Error('No transfers provided');
|
|
333
333
|
if (transfers.length > 4)
|
|
334
334
|
throw new Error('Max 4 transfers per batch (v4 wallet). Use agent_wallet.batch_transfer for more.');
|
|
335
|
-
// Encode comments as payloads
|
|
335
|
+
// Encode comments as payloads (payload field takes precedence)
|
|
336
336
|
const processed = [];
|
|
337
337
|
for (const t of transfers) {
|
|
338
338
|
const entry = { to: t.to, amountNano: t.amountNano };
|
|
339
|
-
if (t.
|
|
339
|
+
if (t.payload) {
|
|
340
|
+
entry.payload = t.payload;
|
|
341
|
+
}
|
|
342
|
+
else if (t.comment) {
|
|
340
343
|
const { beginCell } = await import('@ton/core');
|
|
341
344
|
const commentCell = beginCell().storeUint(0, 32).storeStringTail(t.comment).endCell();
|
|
342
345
|
entry.payload = commentCell.toBoc().toString('base64');
|
|
@@ -359,7 +362,7 @@ server.tool('transfer.batch', 'Send multiple TON transfers in a SINGLE wallet ap
|
|
|
359
362
|
`Total: ${totalTon} TON`,
|
|
360
363
|
`Request ID: ${result.id}`,
|
|
361
364
|
'',
|
|
362
|
-
...transfers.map((t, i) => ` ${i + 1}. ${t.amountNano} nanoTON → ${t.to.slice(0, 16)}...${t.comment ? ` "${t.comment}"` : ''}`),
|
|
365
|
+
...transfers.map((t, i) => ` ${i + 1}. ${t.amountNano} nanoTON → ${t.to.slice(0, 16)}...${t.payload ? ' [payload]' : t.comment ? ` "${t.comment}"` : ''}`),
|
|
363
366
|
'',
|
|
364
367
|
'Approve in your wallet app — one signature for all transfers.',
|
|
365
368
|
].join('\n'),
|
|
@@ -500,35 +503,56 @@ server.tool('lookup.price', 'Get the current TON price in USD, EUR, or other cur
|
|
|
500
503
|
return { content: [{ type: 'text', text: `Error: ${e.message}` }], isError: true };
|
|
501
504
|
}
|
|
502
505
|
});
|
|
503
|
-
server.tool('dex.create_order', 'Place
|
|
504
|
-
fromToken: z.string().describe('Token to sell, e.g. "NOT", "TON", "USDT"'),
|
|
505
|
-
toToken: z.string().describe('Token to buy, e.g. "TON", "NOT", "AGNT"'),
|
|
506
|
-
amount: z.string().describe('Human-readable amount to sell, e.g. "10000"
|
|
507
|
-
price: z.number().describe('Human-readable price: how many toToken per 1 fromToken
|
|
508
|
-
|
|
506
|
+
server.tool('dex.create_order', 'Place one or more limit orders on the open4dev DEX order book. For a single order, provide fromToken/toToken/amount/price directly. For multiple orders, provide an orders array. All orders are batched into one wallet transaction. Both amount and price are human-readable. Slippage (4% including fees) is applied automatically.', {
|
|
507
|
+
fromToken: z.string().optional().describe('Token to sell (single order), e.g. "NOT", "TON", "USDT"'),
|
|
508
|
+
toToken: z.string().optional().describe('Token to buy (single order), e.g. "TON", "NOT", "AGNT"'),
|
|
509
|
+
amount: z.string().optional().describe('Human-readable amount to sell (single order), e.g. "10000"'),
|
|
510
|
+
price: z.number().optional().describe('Human-readable price (single order): how many toToken per 1 fromToken'),
|
|
511
|
+
orders: z.array(z.object({
|
|
512
|
+
fromToken: z.string().describe('Token to sell'),
|
|
513
|
+
toToken: z.string().describe('Token to buy'),
|
|
514
|
+
amount: z.string().describe('Human-readable amount to sell'),
|
|
515
|
+
price: z.number().describe('Human-readable price: how many toToken per 1 fromToken'),
|
|
516
|
+
})).optional().describe('Array of orders for batch creation. If provided, flat params are ignored.'),
|
|
517
|
+
}, { title: 'Create DEX Order', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async ({ fromToken, toToken, amount, price, orders }) => {
|
|
509
518
|
if (!TOKEN) {
|
|
510
519
|
return { content: [{ type: 'text', text: 'No token configured. Use auth.request first.' }], isError: true };
|
|
511
520
|
}
|
|
512
521
|
try {
|
|
522
|
+
// Build request body: batch or single
|
|
523
|
+
let requestBody;
|
|
524
|
+
if (orders && orders.length > 0) {
|
|
525
|
+
requestBody = JSON.stringify({ orders });
|
|
526
|
+
}
|
|
527
|
+
else if (fromToken && toToken && amount && price) {
|
|
528
|
+
requestBody = JSON.stringify({ fromToken, toToken, amount, price });
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
return { content: [{ type: 'text', text: 'Provide either orders array or fromToken/toToken/amount/price.' }], isError: true };
|
|
532
|
+
}
|
|
513
533
|
const result = await apiCall('/v1/dex/order', {
|
|
514
534
|
method: 'POST',
|
|
515
|
-
body:
|
|
535
|
+
body: requestBody,
|
|
516
536
|
});
|
|
537
|
+
// Format output
|
|
538
|
+
const orderList = result.orders || [result.swap];
|
|
539
|
+
const lines = [];
|
|
540
|
+
if (orderList.length === 1) {
|
|
541
|
+
const s = orderList[0];
|
|
542
|
+
lines.push(`Order placed on open4dev DEX!`, ``, `${s.fromToken} → ${s.toToken}`, `Amount: ${s.amount}`, `Price: ${s.price} ${s.toToken} per ${s.fromToken}`, `Slippage: ${s.slippage ?? 4}% (includes fees)`);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
lines.push(`${orderList.length} orders placed on open4dev DEX!`, ``);
|
|
546
|
+
for (let i = 0; i < orderList.length; i++) {
|
|
547
|
+
const s = orderList[i];
|
|
548
|
+
lines.push(`Order ${i + 1}: ${s.fromToken} → ${s.toToken} | Amount: ${s.amount} | Price: ${s.price}`);
|
|
549
|
+
}
|
|
550
|
+
lines.push(``);
|
|
551
|
+
lines.push(`Slippage: 4% (includes fees)`);
|
|
552
|
+
}
|
|
553
|
+
lines.push(`Request ID: ${result.id}`, ``, `Approve in your wallet app.`);
|
|
517
554
|
return {
|
|
518
|
-
content: [{
|
|
519
|
-
type: 'text',
|
|
520
|
-
text: [
|
|
521
|
-
`Order placed on open4dev DEX!`,
|
|
522
|
-
``,
|
|
523
|
-
`${fromToken} → ${toToken}`,
|
|
524
|
-
`Amount: ${amount}`,
|
|
525
|
-
`Price: ${price} ${toToken} per ${fromToken}`,
|
|
526
|
-
`Slippage: ${result.swap?.slippage ?? 4}% (includes fees)`,
|
|
527
|
-
`Request ID: ${result.id}`,
|
|
528
|
-
``,
|
|
529
|
-
`Approve the order in your wallet app.`,
|
|
530
|
-
].join('\n'),
|
|
531
|
-
}],
|
|
555
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
532
556
|
};
|
|
533
557
|
}
|
|
534
558
|
catch (e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tongateway/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "TON blockchain gateway for AI agents — 16 MCP tools: wallet info, transfers, jettons, NFTs, DNS, prices, DEX orders, agent wallets",
|
|
5
5
|
"homepage": "https://tongateway.ai",
|
|
6
6
|
"license": "MIT",
|