publishNote
Publish signed notes to Nostr relays for secure and decentralized content sharing. Use structured event data including ID, author, timestamp, content, and signature for reliable distribution across the network.
Instructions
Publish a signed note to Nostr relays
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| relays | No | Optional list of relays to publish to | |
| signedNote | Yes | Signed note event to publish |
Implementation Reference
- note/note-tools.ts:297-366 (handler)Core handler function that publishes the signed Nostr note event to specified relays using a WebSocket pool, waits for confirmations, and returns success/failure status with details.export async function publishNote( signedNote: { id: string; pubkey: string; created_at: number; kind: number; tags: string[][]; content: string; sig: string; }, relays: string[] = DEFAULT_RELAYS ): Promise<{ success: boolean, message: string, noteId?: string }> { try { // console.error(`Preparing to publish note to ${relays.join(", ")}`); // If no relays specified, just return success with event validation if (relays.length === 0) { return { success: true, message: 'Note is valid and ready to publish (no relays specified)', noteId: signedNote.id, }; } // Create a fresh pool for this request const pool = getFreshPool(relays); try { // 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, }; } catch (error) { console.error("Error publishing note:", error); return { success: false, message: `Error publishing 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:57-68 (schema)Zod schema for input validation of the publishNote tool, defining the structure of the signedNote event and optional relays.export const publishNoteToolConfig = { signedNote: z.object({ id: z.string().describe("Event ID"), pubkey: z.string().describe("Public key of the author"), created_at: z.number().describe("Creation timestamp"), kind: z.number().describe("Event kind"), tags: z.array(z.array(z.string())).describe("Tags array"), content: z.string().describe("Content of the note"), sig: z.string().describe("Event signature") }).describe("Signed note event to publish"), relays: z.array(z.string()).optional().describe("Optional list of relays to publish to"), };
- index.ts:1508-1559 (registration)MCP server registration of the 'publishNote' tool, including description, schema, and thin wrapper handler that calls the core publishNote function and formats the response for the MCP protocol.server.tool( "publishNote", "Publish a signed note to Nostr relays", publishNoteToolConfig, async ({ signedNote, relays }) => { try { const result = await publishNote(signedNote, relays); if (result.success) { let response = `Note published successfully!\n\n`; response += `${result.message}\n`; if (result.noteId) { response += `Note ID: ${result.noteId}\n`; } response += `Content: "${signedNote.content}"\n`; response += `Author: ${formatPubkey(signedNote.pubkey)}\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 publish note: ${result.message}`, }, ], }; } } catch (error) { console.error("Error in publishNote tool:", error); return { content: [ { type: "text", text: `Error publishing note: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } }, );