Skip to main content
Glama

Solana MCP Server

index.ts4.14 kB
#!/usr/bin/env node import { ACTIONS, SolanaAgentKit, startMcpServer, createMcpServer } from "ping-agent-kit"; import * as dotenv from "dotenv"; import express, { Request, Response } from "express"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; import cors from "cors"; dotenv.config(); // Validate required environment variables function validateEnvironment() { const requiredEnvVars = { SOLANA_PRIVATE_KEY: process.env.SOLANA_PRIVATE_KEY, RPC_URL: process.env.RPC_URL, }; const missingVars = Object.entries(requiredEnvVars) .filter(([_, value]) => !value) .map(([key]) => key); if (missingVars.length > 0) { throw new Error( `Missing required environment variables: ${missingVars.join(", ")}` ); } } // New function to start MCP server with SSE support async function startMcpServerWithSse( actions: Record<string, any>, agent: SolanaAgentKit, options: { name: string; version: string; }, port: number = 3000 ) { const app = express(); app.use(cors()); // Store active transport instances const transports: { [sessionId: string]: SSEServerTransport } = {}; // SSE endpoint for client connections app.get("/sse", async (_req: Request, res: Response) => { console.log("Received connection on /sse"); const transport = new SSEServerTransport('/messages', res); // Store the transport for this session transports[transport.sessionId] = transport; res.on("close", () => { console.log(`Connection closed for session ${transport.sessionId}`); delete transports[transport.sessionId]; }); // Create the server and connect it to this transport const server = createMcpServer(actions, agent, options); await server.connect(transport); }); // Message endpoint for client-to-server communication app.post("/messages", async (req: Request, res: Response) => { const sessionId = req.query.sessionId as string; console.log(`Received message for session ${sessionId}`); const transport = transports[sessionId]; if (transport) { await transport.handlePostMessage(req, res); } else { res.status(400).send('No transport found for sessionId'); } }); // Start the Express server app.listen(port, () => { console.log(`MCP SSE server listening on port ${port}`); }); return app; } async function main() { try { // Validate environment before proceeding validateEnvironment(); // Initialize the agent with error handling const agent = new SolanaAgentKit( process.env.SOLANA_PRIVATE_KEY as string, process.env.RPC_URL as string, { OPENAI_API_KEY: process.env.OPENAI_API_KEY || "", } ); const mcp_actions = { GET_ASSET: ACTIONS.GET_ASSET_ACTION, DEPLOY_TOKEN: ACTIONS.DEPLOY_TOKEN_ACTION, GET_PRICE: ACTIONS.FETCH_PRICE_ACTION, WALLET_ADDRESS: ACTIONS.WALLET_ADDRESS_ACTION, BALANCE: ACTIONS.BALANCE_ACTION, TOKEN_BALANCES: ACTIONS.TOKEN_BALANCES_ACTION, TRANSFER: ACTIONS.TRANSFER_ACTION, MINT_NFT: ACTIONS.MINT_NFT_ACTION, TRADE: ACTIONS.TRADE_ACTION, REQUEST_FUNDS: ACTIONS.REQUEST_FUNDS_ACTION, RESOLVE_DOMAIN: ACTIONS.RESOLVE_SOL_DOMAIN_ACTION, GET_TPS: ACTIONS.GET_TPS_ACTION, }; const serverOptions = { name: "solana-agent", version: "0.0.1", }; // Check if PORT environment variable exists to determine whether to use SSE if (process.env.PORT) { const port = parseInt(process.env.PORT, 10); console.log(`Starting MCP server with SSE on port ${port}`); await startMcpServerWithSse(mcp_actions, agent, serverOptions, port); } else { // Start the MCP server with stdio transport (original behavior) console.log("Starting MCP server with stdio transport"); await startMcpServer(mcp_actions, agent, serverOptions); } } catch (error) { console.error( "Failed to start MCP server:", error instanceof Error ? error.message : String(error) ); process.exit(1); } } main();

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/PingAIFun/ping-mcp'

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