UNPKG

cotiv2-mcp

Version:

> A plug-and-play MCP tool server to **send COTI**, **transfer BEP-20 tokens**, **deploy tokens**, and **interact with smart contracts** on the **COTI v2 Network (COTI)** — built for **Claude Desktop**, **AI agents**, and **developers.**

110 lines (109 loc) • 3.74 kB
import prompts from "prompts"; import figlet from "figlet"; import chalk from "chalk"; import path from "path"; import fs from "fs-extra"; import { encryptPrivateKey } from "./PrivateAES.js"; import dotenv from "dotenv"; import { privateKeyToAccount } from "viem/accounts"; import { blue } from "./config.js"; import { configureStorage } from "./lib/storage.js"; import { configureClaude } from "./lib/claude.js"; import { fileURLToPath } from "url"; dotenv.config(); 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("COTI v2 Network MCP ", { font: "Big" }); console.log(blue(banner)); console.log(blue("šŸš€ Welcome to the COTI v2 Network MCP Configurator\n")); }; // Ask for credentials const getInputs = async () => { const questions = [ { type: "password", name: "walletPassword", message: "šŸ” Enter your Wallet Password (must be exactly 8 characters):", validate: (val) => { if (val.trim() === "") return "Wallet Password is required!"; if (val.length !== 8) return "Wallet Password must be exactly 8 characters!"; return true; }, }, { type: "password", name: "privateKey", message: "šŸ”‘ Enter your Wallet Private Key:", validate: (val) => val.trim() === "" ? "Private key is required!" : true, }, ]; return (await prompts(questions, { onCancel })); }; // Generate .env file const generateEnvFile = async (privateKey, address) => { const envContent = ` WALLET_PRIVATE_KEY=${privateKey} WALLET_ADDRESS=${address} `.trim(); await fs.writeFile(".env", envContent); console.log(blue("āœ… .env file generated.")); }; // Generate config object const generateConfig = async (privateKey, address) => { return { WALLET_PRIVATE_KEY: privateKey, WALLET_ADDRESS: address, }; }; // Save fallback config file const saveFallbackConfig = async (config) => { await fs.writeJSON("config.json", config, { spaces: 2 }); console.log(blue("šŸ“ Saved config.json in root project folder.")); }; // Generate config object const generateClaudeConfig = async () => { const indexPath = path.resolve(__dirname, "..", "build", "index.js"); // one level up from cli/ return { "coti-mcp": { command: "node", args: [indexPath], disabled: false, autoApprove: [], }, }; }; // Main logic const init = async () => { showBanner(); const { privateKey, walletPassword } = await getInputs(); const _0xPrivateKey = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`; const account = privateKeyToAccount(_0xPrivateKey); const privateKeyEncrypt = await encryptPrivateKey(_0xPrivateKey, walletPassword); await generateEnvFile(privateKeyEncrypt, account.address); const config = await generateConfig(privateKeyEncrypt, account.address); const success = await configureStorage(config); if (!success) { await saveFallbackConfig(config); } const { setupClaude } = await prompts({ type: "confirm", name: "setupClaude", message: "🧠 Do you want to configure in Claude Desktop?", initial: true, }, { onCancel }); if (setupClaude) { await configureClaude(await generateClaudeConfig()); } }; init();