@tongateway/mcp 0.19.2 → 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 +57 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -209,10 +209,15 @@ server.tool('transfer.request', 'Send a TON transfer. The user approves in their
|
|
|
209
209
|
}
|
|
210
210
|
try {
|
|
211
211
|
const body = { to, amount };
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
212
|
+
// Encode comment as BOC payload using @ton/core
|
|
213
|
+
if (comment && !payload) {
|
|
214
|
+
const { beginCell } = await import('@ton/core');
|
|
215
|
+
const commentCell = beginCell().storeUint(0, 32).storeStringTail(comment).endCell();
|
|
216
|
+
body.payload = commentCell.toBoc().toString('base64');
|
|
217
|
+
}
|
|
218
|
+
else if (payload) {
|
|
215
219
|
body.payload = payload;
|
|
220
|
+
}
|
|
216
221
|
if (stateInit)
|
|
217
222
|
body.stateInit = stateInit;
|
|
218
223
|
const result = await apiCall('/v1/safe/tx/transfer', {
|
|
@@ -316,7 +321,7 @@ server.tool('transfer.pending', 'List all transfer requests waiting for wallet o
|
|
|
316
321
|
}
|
|
317
322
|
});
|
|
318
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.', {
|
|
319
|
-
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.'),
|
|
320
325
|
}, { title: 'Batch Transfer', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, async ({ transfers: transfersJson }) => {
|
|
321
326
|
if (!TOKEN) {
|
|
322
327
|
return { content: [{ type: 'text', text: 'No token configured. Use auth.request first.' }], isError: true };
|
|
@@ -327,11 +332,14 @@ server.tool('transfer.batch', 'Send multiple TON transfers in a SINGLE wallet ap
|
|
|
327
332
|
throw new Error('No transfers provided');
|
|
328
333
|
if (transfers.length > 4)
|
|
329
334
|
throw new Error('Max 4 transfers per batch (v4 wallet). Use agent_wallet.batch_transfer for more.');
|
|
330
|
-
// Encode comments as payloads
|
|
335
|
+
// Encode comments as payloads (payload field takes precedence)
|
|
331
336
|
const processed = [];
|
|
332
337
|
for (const t of transfers) {
|
|
333
338
|
const entry = { to: t.to, amountNano: t.amountNano };
|
|
334
|
-
if (t.
|
|
339
|
+
if (t.payload) {
|
|
340
|
+
entry.payload = t.payload;
|
|
341
|
+
}
|
|
342
|
+
else if (t.comment) {
|
|
335
343
|
const { beginCell } = await import('@ton/core');
|
|
336
344
|
const commentCell = beginCell().storeUint(0, 32).storeStringTail(t.comment).endCell();
|
|
337
345
|
entry.payload = commentCell.toBoc().toString('base64');
|
|
@@ -354,7 +362,7 @@ server.tool('transfer.batch', 'Send multiple TON transfers in a SINGLE wallet ap
|
|
|
354
362
|
`Total: ${totalTon} TON`,
|
|
355
363
|
`Request ID: ${result.id}`,
|
|
356
364
|
'',
|
|
357
|
-
...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}"` : ''}`),
|
|
358
366
|
'',
|
|
359
367
|
'Approve in your wallet app — one signature for all transfers.',
|
|
360
368
|
].join('\n'),
|
|
@@ -495,35 +503,56 @@ server.tool('lookup.price', 'Get the current TON price in USD, EUR, or other cur
|
|
|
495
503
|
return { content: [{ type: 'text', text: `Error: ${e.message}` }], isError: true };
|
|
496
504
|
}
|
|
497
505
|
});
|
|
498
|
-
server.tool('dex.create_order', 'Place
|
|
499
|
-
fromToken: z.string().describe('Token to sell, e.g. "NOT", "TON", "USDT"'),
|
|
500
|
-
toToken: z.string().describe('Token to buy, e.g. "TON", "NOT", "AGNT"'),
|
|
501
|
-
amount: z.string().describe('Human-readable amount to sell, e.g. "10000"
|
|
502
|
-
price: z.number().describe('Human-readable price: how many toToken per 1 fromToken
|
|
503
|
-
|
|
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 }) => {
|
|
504
518
|
if (!TOKEN) {
|
|
505
519
|
return { content: [{ type: 'text', text: 'No token configured. Use auth.request first.' }], isError: true };
|
|
506
520
|
}
|
|
507
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
|
+
}
|
|
508
533
|
const result = await apiCall('/v1/dex/order', {
|
|
509
534
|
method: 'POST',
|
|
510
|
-
body:
|
|
535
|
+
body: requestBody,
|
|
511
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.`);
|
|
512
554
|
return {
|
|
513
|
-
content: [{
|
|
514
|
-
type: 'text',
|
|
515
|
-
text: [
|
|
516
|
-
`Order placed on open4dev DEX!`,
|
|
517
|
-
``,
|
|
518
|
-
`${fromToken} → ${toToken}`,
|
|
519
|
-
`Amount: ${amount}`,
|
|
520
|
-
`Price: ${price} ${toToken} per ${fromToken}`,
|
|
521
|
-
`Slippage: ${result.swap?.slippage ?? 4}% (includes fees)`,
|
|
522
|
-
`Request ID: ${result.id}`,
|
|
523
|
-
``,
|
|
524
|
-
`Approve the order in your wallet app.`,
|
|
525
|
-
].join('\n'),
|
|
526
|
-
}],
|
|
555
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
527
556
|
};
|
|
528
557
|
}
|
|
529
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",
|