Sign In

@tonnode/mcp

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tonnode/mcp - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+44
-43
dist/http.js

@@ -1,5 +0,4 @@

#!/usr/bin/env node
// Hosted mode: the same TON MCP server over Streamable HTTP.
//
// PORT=8808 TONNODE_KEYS=tn_live_abc,tn_live_def tonnode-mcp-http
// PORT=8808 TONNODE_KEYS=tn_live_abc,tn_live_def npx -y @tonnode/mcp --http
//

@@ -77,45 +76,47 @@ // Clients connect with:

// ---------- http server ----------
const httpServer = createHttpServer(async (req, res) => {
try {
const url = new URL(req.url ?? "/", "http://localhost");
if (req.method === "GET" && url.pathname === "/healthz") {
return reply(res, 200, { ok: true, sessions: transports.size });
}
if (url.pathname !== "/mcp") {
return reply(res, 404, { error: "not found — MCP endpoint is POST /mcp" });
}
const key = authenticate(req);
if (!key)
return reply(res, 401, { error: "invalid or missing API key" });
if (!allow(key))
return reply(res, 429, { error: `rate limit exceeded (${RATE_LIMIT_RPM}/min)` });
const sessionId = req.headers["mcp-session-id"];
if (req.method === "POST") {
const body = await readBody(req);
let transport = sessionId ? transports.get(sessionId) : undefined;
if (!transport) {
if (sessionId)
return reply(res, 404, { error: "unknown or expired session" });
transport = await newSession();
export function startHttp() {
const httpServer = createHttpServer(async (req, res) => {
try {
const url = new URL(req.url ?? "/", "http://localhost");
if (req.method === "GET" && url.pathname === "/healthz") {
return reply(res, 200, { ok: true, sessions: transports.size });
}
return void (await transport.handleRequest(req, res, body));
if (url.pathname !== "/mcp") {
return reply(res, 404, { error: "not found — MCP endpoint is POST /mcp" });
}
const key = authenticate(req);
if (!key)
return reply(res, 401, { error: "invalid or missing API key" });
if (!allow(key))
return reply(res, 429, { error: `rate limit exceeded (${RATE_LIMIT_RPM}/min)` });
const sessionId = req.headers["mcp-session-id"];
if (req.method === "POST") {
const body = await readBody(req);
let transport = sessionId ? transports.get(sessionId) : undefined;
if (!transport) {
if (sessionId)
return reply(res, 404, { error: "unknown or expired session" });
transport = await newSession();
}
return void (await transport.handleRequest(req, res, body));
}
// GET = server-initiated SSE stream, DELETE = session teardown
if (req.method === "GET" || req.method === "DELETE") {
const transport = sessionId ? transports.get(sessionId) : undefined;
if (!transport)
return reply(res, 400, { error: "mcp-session-id header required" });
return void (await transport.handleRequest(req, res));
}
return reply(res, 405, { error: "method not allowed" });
}
// GET = server-initiated SSE stream, DELETE = session teardown
if (req.method === "GET" || req.method === "DELETE") {
const transport = sessionId ? transports.get(sessionId) : undefined;
if (!transport)
return reply(res, 400, { error: "mcp-session-id header required" });
return void (await transport.handleRequest(req, res));
catch (err) {
const message = err instanceof Error ? err.message : String(err);
if (!res.headersSent)
reply(res, 500, { error: message });
}
return reply(res, 405, { error: "method not allowed" });
}
catch (err) {
const message = err instanceof Error ? err.message : String(err);
if (!res.headersSent)
reply(res, 500, { error: message });
}
});
httpServer.listen(PORT, () => {
const mode = KEYS.size > 0 ? `${KEYS.size} API key(s)` : "open access (no TONNODE_KEYS set)";
console.error(`tonnode-mcp http listening on :${PORT} — ${mode}, ${RATE_LIMIT_RPM} req/min per key`);
});
});
httpServer.listen(PORT, () => {
const mode = KEYS.size > 0 ? `${KEYS.size} API key(s)` : "open access (no TONNODE_KEYS set)";
console.error(`tonnode-mcp http listening on :${PORT} — ${mode}, ${RATE_LIMIT_RPM} req/min per key`);
});
}
#!/usr/bin/env node
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { createTonServer } from "./server.js";
await createTonServer().connect(new StdioServerTransport());
// open liteserver sockets keep the event loop alive — exit when the MCP
// client (or a closed pipe) ends stdin, so orphaned servers don't linger
process.stdin.on("end", () => process.exit(0));
process.stdin.on("close", () => process.exit(0));
// Default: stdio MCP server for local clients (Claude, ChatGPT, Cursor, Codex…).
// With --http: hosted Streamable-HTTP mode (API keys, rate limits) — see src/http.ts.
if (process.argv.includes("--http")) {
const { startHttp } = await import("./http.js");
startHttp();
}
else {
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
const { createTonServer } = await import("./server.js");
await createTonServer().connect(new StdioServerTransport());
// open liteserver sockets keep the event loop alive — exit when the MCP
// client (or a closed pipe) ends stdin, so orphaned servers don't linger
process.stdin.on("end", () => process.exit(0));
process.stdin.on("close", () => process.exit(0));
}
export {};
{
"name": "@tonnode/mcp",
"version": "0.1.0",
"version": "0.1.1",
"description": "MCP server that gives AI agents direct liteserver access to The Open Network (TON): balances, account state, transactions and contract get-methods.",
"type": "module",
"bin": {
"tonnode-mcp": "dist/index.js",
"tonnode-mcp-http": "dist/http.js"
"tonnode-mcp": "dist/index.js"
},

@@ -10,0 +9,0 @@ "main": "dist/index.js",

@@ -39,3 +39,3 @@ # @tonnode/mcp

```bash
TONNODE_KEYS=tn_live_abc,tn_live_def PORT=8808 npx -y -p @tonnode/mcp tonnode-mcp-http
TONNODE_KEYS=tn_live_abc,tn_live_def PORT=8808 npx -y @tonnode/mcp --http
```

@@ -42,0 +42,0 @@