Skip to main content
Glama

BSC MCP Server

init.ts6.54 kB
import prompts, { PromptObject } from 'prompts'; import figlet from 'figlet'; import chalk from 'chalk'; import path from 'path'; import fs from 'fs-extra'; import os from 'os'; import { fileURLToPath } from 'url'; import { encryptPrivateKey } from './PrivateAES.js'; import dotenv from "dotenv"; import { Hex } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; dotenv.config(); // Binance Gold Color const yellow = chalk.hex('#F0B90B'); // ESModule __dirname workaround const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Cancel handler const onCancel = () => { console.log(chalk.red('\n❌ Configuration cancelled by user (Ctrl+C or ESC). Exiting...')); process.exit(0); }; // Show Banner const showBanner = () => { const banner = figlet.textSync('BNB Chain MCP ', { font: 'Big' }); console.log(yellow(banner)); console.log(yellow('🚀 Welcome to the BNB Chain MCP Configurator\n')); }; // User Input Types interface UserInputs { walletPassword: string; privateKey: string; rpcUrl?: string; } function validatePassword(password: string) { // At least 8 characters if (password.trim() === '') return 'Wallet Password is required!'; if (password.length < 8 || password.length > 128) return 'Wallet Password must be between 8 and 128 characters!'; // Check if it contains at least one lowercase letter if (!/[a-z]/.test(password)) return 'Wallet Password must contain at least one lowercase letter!'; // Check if it contains at least one uppercase letter if (!/[A-Z]/.test(password)) return 'Wallet Password must contain at least one uppercase letter!'; // Check if it contains at least one number if (!/[0-9]/.test(password)) return 'Wallet Password must contain at least one number!'; // Check if it contains at least one special character if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) return 'Wallet Password must contain at least one special character! (!@#$%^&*()_+-=[]{};\':\\"|,.<>\/?)'; return true; } // Ask for credentials const getInputs = async (): Promise<UserInputs> => { const questions: PromptObject[] = [ { type: 'password', name: 'walletPassword', message: '🔐 Enter your Wallet Password (The password must be between 8 and 128 characters):', validate: (val: string) => { return validatePassword(val); }, }, { type: 'password', name: 'privateKey', message: '🔑 Enter your BNB Chain Wallet Private Key:', validate: (val: string) => val.trim() === '' ? 'Private key is required!' : true, }, { type: 'text', name: 'rpcUrl', message: '🌐 Enter your BNB Chain RPC URL (optional):', }, ]; return await prompts(questions, { onCancel }) as UserInputs; }; // Generate .env file const generateEnvFile = async (privateKey: string, address: string, rpcUrl?: string, ): Promise<void> => { const envContent = ` BSC_WALLET_PRIVATE_KEY=${privateKey} BSC_WALLET_ADDRESS=${address} BSC_RPC_URL=${rpcUrl || ''} `.trim(); await fs.writeFile('.env', envContent); console.log(yellow('✅ .env file generated.')); }; // Generate config object const generateConfig = async (privateKey: string, address: string, rpcUrl?: string, ): Promise<any> => { const indexPath = path.resolve(__dirname, '..', 'build', 'index.js'); // one level up from cli/ return { 'bsc-mcp': { command: 'node', args: [indexPath], env: { BSC_WALLET_PRIVATE_KEY: privateKey, BSC_WALLET_ADDRESS: address, BSC_RPC_URL: rpcUrl || '', }, disabled: false, autoApprove: [] } }; }; // Configure Claude Desktop const configureClaude = async (config: object): Promise<boolean> => { const userHome = os.homedir(); let claudePath; const platform = os.platform(); if (platform == "darwin") { claudePath = path.join(userHome, 'Library/Application Support/Claude/claude_desktop_config.json'); } else if (platform == "win32") { claudePath = path.join(userHome, 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json'); } else { console.log(chalk.red('❌ Unsupported platform.')); return false; } if (!fs.existsSync(claudePath)) { console.log(chalk.yellow('⚠️ Claude config file not found. Creating a new one with default configuration.')); // Create a default configuration object const defaultConfig = { mcpServers: {} }; // Write the default configuration to the file await fs.writeJSON(claudePath, defaultConfig, { spaces: 2 }); } const jsonData = fs.readFileSync(claudePath, 'utf8'); const data = JSON.parse(jsonData); data.mcpServers = { ...data.mcpServers, ...config, }; await fs.writeJSON(claudePath, data, { spaces: 2 }); console.log(yellow('✅ BNB Chain MCP configured for Claude Desktop. Please RESTART your Claude to enjoy it 🎉')); return true; }; // Save fallback config file const saveFallbackConfig = async (config: object): Promise<void> => { await fs.writeJSON('config.json', config, { spaces: 2 }); console.log(yellow('📁 Saved config.json in root project folder.')); }; // Main logic const init = async () => { showBanner(); const { privateKey, rpcUrl, walletPassword } = await getInputs(); const _0xPrivateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}` const account = privateKeyToAccount( _0xPrivateKey as Hex ); const privateKeyEncrypt = await encryptPrivateKey(_0xPrivateKey, walletPassword); await generateEnvFile(privateKeyEncrypt, account.address, rpcUrl); const config = await generateConfig(privateKeyEncrypt, account.address, rpcUrl); const { setupClaude } = await prompts({ type: 'confirm', name: 'setupClaude', message: '🧠 Do you want to configure in Claude Desktop?', initial: true }, { onCancel }); if (setupClaude) { const success = await configureClaude(config); if (!success) { await saveFallbackConfig(config); } } else { await saveFallbackConfig(config); } }; init();

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/TermiX-official/bsc-mcp'

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