getProfile
Retrieve a Nostr user profile using a public key (hex or npub format) with optional relay queries. The tool fetches profile details for interaction within the MCP server environment.
Instructions
Get a Nostr profile by public key
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pubkey | Yes | Public key of the Nostr user (hex format or npub format) | |
| relays | No | Optional list of relays to query |
Implementation Reference
- index.ts:72-147 (handler)Registration and inline handler implementation for the 'getProfile' MCP tool. Fetches Nostr profile (kind 0 metadata event) from specified relays using snstr pool, formats it using formatProfile helper, and returns formatted text content or error.server.tool( "getProfile", "Get a Nostr profile by public key", getProfileToolConfig, async ({ pubkey, relays }, extra) => { // Convert npub to hex if needed const hexPubkey = npubToHex(pubkey); if (!hexPubkey) { return { content: [ { type: "text", text: "Invalid public key format. Please provide a valid hex pubkey or npub.", }, ], }; } // Generate a friendly display version of the pubkey const displayPubkey = formatPubkey(hexPubkey); const relaysToUse = relays || DEFAULT_RELAYS; // Create a fresh pool for this request const pool = getFreshPool(relaysToUse); try { console.error(`Fetching profile for ${hexPubkey} from ${relaysToUse.join(", ")}`); // Query for profile (kind 0) - snstr handles timeout internally const profile = await pool.get( relaysToUse, { kinds: [KINDS.Metadata], authors: [hexPubkey], } as NostrFilter ); if (!profile) { return { content: [ { type: "text", text: `No profile found for ${displayPubkey}`, }, ], }; } const formatted = formatProfile(profile); return { content: [ { type: "text", text: `Profile for ${displayPubkey}:\n\n${formatted}`, }, ], }; } catch (error) { console.error("Error fetching profile:", error); return { content: [ { type: "text", text: `Error fetching profile for ${displayPubkey}: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } finally { // Clean up any subscriptions and close the pool await pool.close(); } } );
- note/note-tools.ts:10-14 (schema)Zod schema defining input parameters for the getProfile tool: pubkey (required string) and optional relays array.// Schema for getProfile tool export const getProfileToolConfig = { pubkey: z.string().describe("Public key of the Nostr user (hex format or npub format)"), relays: z.array(z.string()).optional().describe("Optional list of relays to query"), };
- note/note-tools.ts:71-92 (helper)Helper function formatProfile used by the getProfile handler to parse and format Nostr profile metadata from kind 0 event into readable text.export function formatProfile(profile: NostrEvent): string { if (!profile) return "No profile found"; let metadata: any = {}; try { metadata = profile.content ? JSON.parse(profile.content) : {}; } catch (e) { console.error("Error parsing profile metadata:", e); } return [ `Name: ${metadata.name || "Unknown"}`, `Display Name: ${metadata.display_name || metadata.displayName || metadata.name || "Unknown"}`, `About: ${metadata.about || "No about information"}`, `NIP-05: ${metadata.nip05 || "Not set"}`, `Lightning Address (LUD-16): ${metadata.lud16 || "Not set"}`, `LNURL (LUD-06): ${metadata.lud06 || "Not set"}`, `Picture: ${metadata.picture || "No picture"}`, `Website: ${metadata.website || "No website"}`, `Created At: ${new Date(profile.created_at * 1000).toISOString()}`, ].join("\n"); }