Skip to main content
Glama

MCP-NOSTR

by pablof7z
wizard.ts5.82 kB
import inquirer from "inquirer"; import { NDKEvent, NDKPrivateKeySigner, serializeProfile, type NDKUserProfile } from "@nostr-dev-kit/ndk"; import { type ConfigData, writeConfig } from "./config.js"; import { ndk } from "./ndk.js"; import { commandMap } from "./commands/mcp.js"; /** * Create and publish a kind:0 metadata event * @param ndk NDK instance * @param signer NDKPrivateKeySigner * @param name Display name for the profile * @returns Promise that resolves when event is published */ async function publishMetadataEvent(signer: NDKPrivateKeySigner, name: string) { const event = new NDKEvent(ndk); event.kind = 0; const profile: NDKUserProfile = { name, displayName: name, about: "Hello, I'm new around here." }; event.content = serializeProfile(profile); await event.sign(signer); return event.publish(); } /** * Run the configuration wizard to guide the user through first-time setup * @param config Current configuration object * @returns Updated configuration object */ export async function runConfigWizard(config: ConfigData): Promise<ConfigData> { console.log("\n🔧 Welcome to TENEX Configuration Wizard 🔧\n"); console.log("Let's set up your configuration for first use.\n"); let signer: NDKPrivateKeySigner | undefined; // Step 0: Check if user has a Nostr key const { hasNostrKey } = await inquirer.prompt([ { type: "confirm", name: "hasNostrKey", message: "Do you have a nostr account?", default: false, }, ]); if (!hasNostrKey) { signer = NDKPrivateKeySigner.generate(); ndk.signer = signer; // Ask for display name const { name } = await inquirer.prompt([ { type: "input", name: "name", message: "What should I call you?", validate: (input) => input.trim().length > 0 || "Display name cannot be empty", }, ]); publishMetadataEvent(signer, name); console.log("Here is your private key (nsec)."); console.log(`\n${signer.nsec}\n`); console.log("Your public key (npub) is:"); console.log(`\n${signer.npub}\n`); config.privateKey = signer.nsec; } if (hasNostrKey) { const { wotFrom } = await inquirer.prompt([ { type: "input", name: "wotFrom", message: "Enter Web-of-trust entry point (NIP-05):", default: "pablo@f7z.io", }, ]); // Validate NIP-05 and show npub try { const user = await ndk.getUserFromNip05(wotFrom); if (!user) { console.log(`⚠️ Could not verify NIP-05: ${wotFrom}`); } } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`❌ Error validating NIP-05: ${errorMessage}`); } config.wotFrom = wotFrom; } else { config.wotFrom = "pablo@f7z.io"; } // Only ask for authentication method if user already had an account if (hasNostrKey) { console.log("🔑 Authentication Methods"); console.log("This is what will be used to publish code snippets and notes when you choose to publish without a dedicated profile."); // Step 2: Ask for authentication method const { authMethod } = await inquirer.prompt([ { type: "list", name: "authMethod", message: "Choose authentication method:", choices: [ { name: "Private Key (nsec)", value: "nsec" }, { name: "Bunker Connection (bunker://)", value: "bunker" }, ], }, ]); // Step 3: Ask for authentication value based on chosen method if (authMethod === "nsec") { const { privateKey } = await inquirer.prompt([ { type: "password", name: "privateKey", message: "Enter your private key (nsec):", mask: "*", }, ]); config.privateKey = privateKey; } else { const { bunker } = await inquirer.prompt([ { type: "input", name: "bunker", message: "Enter bunker connection string (bunker://):", validate: (input) => { return input.startsWith("bunker://") ? true : "Bunker connection string must start with 'bunker://'"; }, }, ]); config.bunker = bunker; } } // Step 5: Ask for MCP commands to enable const { enableAllCommands } = await inquirer.prompt([ { type: "confirm", name: "enableAllCommands", message: "Enable all MCP commands?", default: true, }, ]); if (enableAllCommands) { // All commands are enabled by default by setting an empty array or undefined config.mcpCommands = undefined; } else { const { selectedCommands } = await inquirer.prompt([ { type: "checkbox", name: "selectedCommands", message: "Enable MCP commands?", choices: Object.keys(commandMap), default: Object.keys(commandMap), }, ]); config.mcpCommands = selectedCommands; } // Save configuration writeConfig(config); return config; }

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/pablof7z/mcp-code'

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