@tongateway/mcp 0.11.1 → 0.13.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 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
4
5
|
import { z } from 'zod';
|
|
6
|
+
import { createServer } from 'node:http';
|
|
5
7
|
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
6
8
|
import { join } from 'node:path';
|
|
7
9
|
import { homedir } from 'node:os';
|
|
@@ -411,19 +413,19 @@ server.tool('get_ton_price', 'Get the current TON price in USD, EUR, or other cu
|
|
|
411
413
|
return { content: [{ type: 'text', text: `Error: ${e.message}` }], isError: true };
|
|
412
414
|
}
|
|
413
415
|
});
|
|
414
|
-
server.tool('create_dex_order', 'Place a limit order on the open4dev DEX order book. Provide the token pair
|
|
416
|
+
server.tool('create_dex_order', 'Place a limit order on the open4dev DEX order book. Provide the token pair, amount in smallest units, and price in human-readable format (e.g. price=20 means "1 fromToken = 20 toToken"). The API handles all decimal conversions and slippage automatically. The order requires wallet approval.', {
|
|
415
417
|
fromToken: z.string().describe('Token to sell, e.g. "NOT", "TON", "USDT"'),
|
|
416
|
-
toToken: z.string().describe('Token to buy, e.g. "TON", "NOT"'),
|
|
417
|
-
amount: z.string().describe('Amount to sell in smallest unit (
|
|
418
|
-
|
|
419
|
-
}, async ({ fromToken, toToken, amount,
|
|
418
|
+
toToken: z.string().describe('Token to buy, e.g. "TON", "NOT", "AGNT"'),
|
|
419
|
+
amount: z.string().describe('Amount to sell in smallest unit. TON/NOT/DOGS/BUILD/AGNT use 9 decimals (1 TON = 10^9). USDT/XAUT0 use 6 decimals (1 USDT = 10^6).'),
|
|
420
|
+
price: z.number().describe('Human-readable price: how many toToken per 1 fromToken. E.g. price=20 means "1 USDT = 20 AGNT". price=0.05 means "1 AGNT = 0.05 USDT".'),
|
|
421
|
+
}, async ({ fromToken, toToken, amount, price }) => {
|
|
420
422
|
if (!TOKEN) {
|
|
421
423
|
return { content: [{ type: 'text', text: 'No token configured. Use request_auth first.' }], isError: true };
|
|
422
424
|
}
|
|
423
425
|
try {
|
|
424
426
|
const result = await apiCall('/v1/dex/order', {
|
|
425
427
|
method: 'POST',
|
|
426
|
-
body: JSON.stringify({ fromToken, toToken, amount,
|
|
428
|
+
body: JSON.stringify({ fromToken, toToken, amount, price }),
|
|
427
429
|
});
|
|
428
430
|
return {
|
|
429
431
|
content: [{
|
|
@@ -433,8 +435,8 @@ server.tool('create_dex_order', 'Place a limit order on the open4dev DEX order b
|
|
|
433
435
|
``,
|
|
434
436
|
`${fromToken} → ${toToken}`,
|
|
435
437
|
`Amount: ${amount}`,
|
|
436
|
-
`Price
|
|
437
|
-
`
|
|
438
|
+
`Price: ${price} ${toToken} per ${fromToken}`,
|
|
439
|
+
`Slippage: ${result.swap?.slippage ?? 4}% (includes fees)`,
|
|
438
440
|
`Request ID: ${result.id}`,
|
|
439
441
|
``,
|
|
440
442
|
`Approve the order in your wallet app.`,
|
|
@@ -682,5 +684,42 @@ server.tool('get_agent_wallet_info', 'Get info about Agent Wallets — balance,
|
|
|
682
684
|
return { content: [{ type: 'text', text: `Error: ${e.message}` }], isError: true };
|
|
683
685
|
}
|
|
684
686
|
});
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
+
const httpPort = process.env.MCP_HTTP_PORT || (process.argv.includes('--http') ? '3100' : '');
|
|
688
|
+
if (httpPort) {
|
|
689
|
+
// HTTP transport for Smithery and remote clients
|
|
690
|
+
const httpServer = createServer(async (req, res) => {
|
|
691
|
+
// CORS
|
|
692
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
693
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
694
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
695
|
+
if (req.method === 'OPTIONS') {
|
|
696
|
+
res.writeHead(204);
|
|
697
|
+
res.end();
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
// Health check
|
|
701
|
+
if (req.method === 'GET' && req.url === '/health') {
|
|
702
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
703
|
+
res.end(JSON.stringify({ ok: true, version: '0.12.0' }));
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
// MCP endpoint
|
|
707
|
+
if (req.url === '/mcp' || req.url === '/') {
|
|
708
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
709
|
+
res.on('close', () => { transport.close(); });
|
|
710
|
+
await server.connect(transport);
|
|
711
|
+
await transport.handleRequest(req, res);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
res.writeHead(404);
|
|
715
|
+
res.end('Not found');
|
|
716
|
+
});
|
|
717
|
+
httpServer.listen(Number(httpPort), () => {
|
|
718
|
+
console.error(`MCP HTTP server listening on port ${httpPort}`);
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
// Default: stdio transport for local MCP clients
|
|
723
|
+
const transport = new StdioServerTransport();
|
|
724
|
+
await server.connect(transport);
|
|
725
|
+
}
|