@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.
Files changed (2) hide show
  1. package/dist/index.js +49 -10
  2. 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 (e.g. NOT→TON), amount, and price. The order is created as a safe transfer the user approves it in their wallet. Use get_ton_price or get_jetton_balances to determine current rates before swapping.', {
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 (nanoTON for TON, or raw jetton amount based on decimals)'),
418
- priceRateNano: z.string().describe('Price rate in nanoTON per unit'),
419
- }, async ({ fromToken, toToken, amount, priceRateNano }) => {
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, priceRateNano }),
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 Rate: ${priceRateNano} nanoTON`,
437
- `Pool: ${result.swap?.pool || 'unknown'}`,
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 transport = new StdioServerTransport();
686
- await server.connect(transport);
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tongateway/mcp",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "description": "MCP server for Agent Gateway — lets AI agents request TON blockchain transfers",
5
5
  "license": "MIT",
6
6
  "repository": {