postAnonymousNote
Post anonymous notes to the Nostr network using temporary keypairs to share content without revealing identity.
Instructions
Post an anonymous note to the Nostr network using a temporary keypair
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Content of the note to post | |
| relays | No | Optional list of relays to publish to | |
| tags | No | Optional tags to include with the note |
Implementation Reference
- note/note-tools.ts:112-189 (handler)The core handler function that generates a temporary keypair, creates a kind 1 note event, signs it, and publishes it anonymously to the specified Nostr relays.export async function postAnonymousNote( content: string, relays: string[] = DEFAULT_RELAYS, tags: string[][] = [] ): Promise<{ success: boolean, message: string, noteId?: string, publicKey?: string }> { try { // console.error(`Preparing to post anonymous note to ${relays.join(", ")}`); // Create a fresh pool for this request const pool = getFreshPool(relays); try { // Generate a one-time keypair for anonymous posting const keys = await generateKeypair(); // Create the note event template const noteTemplate = createEvent({ kind: 1, // kind 1 is a text note content, tags }, keys.publicKey); // Get event hash and sign it const eventId = await getEventHash(noteTemplate); const signature = await signEvent(eventId, keys.privateKey); // Create complete signed event const signedNote = { ...noteTemplate, id: eventId, sig: signature }; const publicKey = keys.publicKey; // Publish to relays and wait for actual relay OK responses const pubPromises = pool.publish(relays, signedNote); // Wait for all publish attempts to complete or timeout const results = await Promise.allSettled(pubPromises); // Check if at least one relay actually accepted the event // A fulfilled promise means relay responded, but we need to check if it accepted const successCount = results.filter(r => r.status === 'fulfilled' && r.value.success === true ).length; if (successCount === 0) { return { success: false, message: 'Failed to publish note to any relay', }; } return { success: true, message: `Note published to ${successCount}/${relays.length} relays`, noteId: signedNote.id, publicKey: publicKey, }; } catch (error) { console.error("Error posting anonymous note:", error); return { success: false, message: `Error posting anonymous note: ${error instanceof Error ? error.message : "Unknown error"}`, }; } finally { // Clean up any subscriptions and close the pool await pool.close(); } } catch (error) { return { success: false, message: `Fatal error: ${error instanceof Error ? error.message : "Unknown error"}`, }; } }
- note/note-tools.ts:31-35 (schema)Zod schema defining the input parameters for the postAnonymousNote tool: content (required string), relays (optional array of strings), tags (optional array of tag arrays).export const postAnonymousNoteToolConfig = { content: z.string().describe("Content of the note to post"), relays: z.array(z.string()).optional().describe("Optional list of relays to publish to"), tags: z.array(z.array(z.string())).optional().describe("Optional tags to include with the note"), };
- index.ts:1097-1153 (registration)MCP server tool registration that wraps the postAnonymousNote handler, handles input validation via the schema, formats success/error responses, and integrates with the MCP protocol.server.tool( "postAnonymousNote", "Post an anonymous note to the Nostr network using a temporary keypair", postAnonymousNoteToolConfig, async ({ content, relays, tags }) => { try { const result = await postAnonymousNote(content, relays, tags); if (result.success) { let response = `Anonymous note posted successfully!\n\n`; response += `${result.message}\n`; if (result.noteId) { response += `Note ID: ${result.noteId}\n`; } if (result.publicKey) { response += `Anonymous Author: ${formatPubkey(result.publicKey)}\n`; } response += `Content: "${content}"\n`; if (tags && tags.length > 0) { response += `Tags: ${JSON.stringify(tags)}\n`; } if (relays && relays.length > 0) { response += `Relays: ${relays.join(", ")}\n`; } return { content: [ { type: "text", text: response, }, ], }; } else { return { content: [ { type: "text", text: `Failed to post anonymous note: ${result.message}`, }, ], }; } } catch (error) { console.error("Error in postAnonymousNote tool:", error); return { content: [ { type: "text", text: `Error posting anonymous note: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } }, );