Skip to main content
Glama

VeChain MCP Server

server.ts4.87 kB
import express, { type Request, type Response } from "express"; import cors from "cors"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { z, type ZodRawShape } from "zod"; import { vechainConfig } from "./config.js"; import { toolsPromise, vechainTools } from "./tools.js"; import { buildToolZodMap, parseToolInput } from "./utils.js"; async function createVechainServer() { const server = new McpServer( { name: vechainConfig.mcpServer.name, version: vechainConfig.mcpServer.version, }, { capabilities: { tools: {}, }, }, ); // Goat SDK On-Chain Tools const { listOfTools, toolHandler } = await toolsPromise(); const vechainGoatSdkTools = listOfTools(); const toolSchemaMap = buildToolZodMap(vechainGoatSdkTools); for (const t of vechainGoatSdkTools) { const zodSchema = toolSchemaMap.get(t.name) ?? z.object({}); let inputShape: ZodRawShape = {}; try { const def = (zodSchema as any)?._def; if (def && def.typeName === "ZodObject") { const shapeFnOrObj = def.shape; const shape = typeof shapeFnOrObj === "function" ? shapeFnOrObj() : shapeFnOrObj; inputShape = shape as ZodRawShape; } else { inputShape = {}; } } catch (e) { console.error(e) inputShape = {}; } server.registerTool( t.name, { title: t.name, description: t.description ?? "", inputSchema: inputShape, }, async (args) => { const parsedArgs = parseToolInput(toolSchemaMap, t.name, args); const result = await toolHandler(t.name, parsedArgs); return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] }; } ); } // Thorest API Tools & Custom Tools for (const t of vechainTools) { server.registerTool( t.name, { title: t.name, description: t.description, inputSchema: t.inputSchema }, async (args) => { const result = await t.callback(args); return { content: result.content.map(item => ({ ...item, type: "text" as const })) }; } ); } return server; } export async function start() { const useStreamHttp = process.env.USE_STREAMABLE_HTTP === "true"; const useStdIO = !useStreamHttp; const port = Number(process.env.PORT || 3000); const host = process.env.HOST || "0.0.0.0"; const server = await createVechainServer(); if (useStdIO) { const transport = new StdioServerTransport(); await server.connect(transport); console.log("VeChain MCP Server running on stdio"); console.log(`Mode: ${process.env.ENVIRONMENT === "MAINNET" ? "Mainnet" : "Testnet"}`); return; } const app = express(); app.use(express.json()); app.use( cors({ origin: "*", allowedHeaders: ["Content-Type", "mcp-session-id"], }) ); app.post("/mcp", async (req: Request, res: Response) => { try { const transport: StreamableHTTPServerTransport = new StreamableHTTPServerTransport({ enableDnsRebindingProtection: true, sessionIdGenerator: undefined, }); res.on('close', () => { console.log('Request closed'); transport.close(); server.close(); }); await server.connect(transport); await transport.handleRequest(req, res, req.body); } catch (error) { console.error('Error handling MCP request:', error); if (!res.headersSent) { res.status(500).json({ jsonrpc: '2.0', error: { code: -32603, message: 'Internal server error', }, id: null, }); } } }); app.get('/mcp', async (req: Request, res: Response) => { console.log('Received GET MCP request'); res.writeHead(405).end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed." }, id: null })); }); app.delete('/mcp', async (req: Request, res: Response) => { console.log('Received DELETE MCP request'); res.writeHead(405).end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed." }, id: null })); }); app.get("/health", (_req, res) => res.status(200).send("ok")); app.listen(port, host, () => { console.log(`MCP Stateless Streamable HTTP listening on http://${host}:${port}`); console.log(`Mode: ${process.env.ENVIRONMENT === "MAINNET" ? "Mainnet" : "Testnet"}`); }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/leandrogavidia/vechain-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server