Public leaderboard

Public assessment

jorgenclaw/nostr-mcp-server (nostr-mcp-server)

nostr-mcp-server · v1.0.0 · scanned

What changed in the harness

Selection accuracy 93→91, token cost up 14%, unconfirmed writes 0%→0%.

Category breakdown

Where the score comes from.

Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.

01Safety

0.0 / 30

0.0 out of 30
02Legibility

16.8 / 30

16.8 out of 30
03Economics

13.9 / 20

13.9 out of 20
04Discoverability

12.7 / 20

12.7 out of 20

Highest-impact fix

Estimated gain +30 points

Add explicit identity and permission preflight tools

Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.

Description evidence

Defects and rewrites.

40 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.

Tool Defect types Suggested rewrite
getProfile
name_restates_behavior no_return_description
Fetch the Nostr profile metadata (kind 0 event) for a public key from relays, returning the user's relayed metadata fields such as name, about, picture, and NIP-05. Use a pubkey in hex or npub format; optionally restrict which relays are queried to speed up retrieval or reach relays where the user is active.
getKind1Notes
no_return_description
Fetch text notes (kind 1 events) authored by a public key, returning the note events with their content, ids, and timestamps, newest first. Optionally cap the number of notes returned (default 10), filter by a since/until time range in unix seconds, and restrict which relays are queried.
getReceivedZaps
name_restates_behavior no_return_description
Fetch zaps received by a public key from relays, returning the matching zap events with amounts, senders, and comments so you can total or display incoming lightning payments. Optionally limit results, filter by a since/until time range, validate zap receipts according to NIP-57, and enable verbose debug logging.
getSentZaps
name_restates_behavior no_return_description
Fetch zaps sent by a public key from relays, returning the matching zap events with amounts, recipients, and comments so you can total or display outgoing lightning payments. Optionally limit results, filter by a since/until time range, validate zap receipts according to NIP-57, and enable verbose debug logging.
getAllZaps
no_return_description
Fetch both zaps sent and zaps received by a public key, returning the combined zap events so you can summarize an account's lightning activity. Optionally cap the total number of zaps returned (default 20), filter by a since/until time range, validate receipts per NIP-57, and enable verbose debug logging.
getLongFormNotes
name_restates_behavior no_return_description
Fetch long-form articles (kind 30023 events) authored by a public key, returning each article's content, title/topic tags, and timestamps. Optionally limit the number of notes, filter by a since/until time range in unix seconds, and restrict which relays are queried.
queryEvents
name_restates_behavior no_return_description
Run a generic Nostr event search across relays using a filter of event kinds, authors, event ids, tag values (e.g., { p: [pubkey] }), and a since/until time range, returning the matching signed events with their full content and metadata. Useful as a fallback when no dedicated get* tool fits. Optionally cap results (default 25), provide a NIP-50 search string (relay support varies), and authenticate to relays that require NIP-42.
getContactList
name_restates_behavior no_return_description
Fetch a user's contact list (kind 3 event) from relays, returning the pubkeys they follow together with any stored relay hints and petnames for each contact. Optionally restrict which relays are queried.
getFollowing
no_return_description
Return the list of followed pubkeys for a user (the contact entry pubkeys from their kind 3 contact list; alias of getContactList). Optionally restrict which relays are queried.
getRelayList
name_restates_behavior no_return_description
Fetch a user's relay preferences published as a NIP-65 kind 10002 event, returning the relay URLs along with their read and write flags. Optionally restrict which relays are queried, and authenticate to relays that require NIP-42 using a private key.
setRelayList
no_return_description
Publish a NIP-65 kind 10002 relay list for an account, declaring which relays the user reads from and writes to, and return a confirmation of the published event. Provide the signing private key and the relay entries (URL with optional read/write flags); entries with neither flag default to both.
follow
no_return_description
Add a pubkey to an account's follow list by publishing an updated kind 3 contact list, optionally storing a relay hint and petname for that contact, and return a confirmation of the published event. Takes the account's private key and the target pubkey.
unfollow
no_return_description
Remove a pubkey from an account's follow list by publishing an updated kind 3 contact list, and return a confirmation of the published event. Takes the account's private key and the target pubkey.
reactToEvent
name_restates_behavior no_return_description
Publish a kind 7 reaction to a target event under a specific account's identity, allowing '+', '-', or an emoji as the reaction content, and return the published reaction event (including its id). Useful to signal approval or acknowledgment of a note.
repostEvent
name_restates_behavior no_return_description
Share a target event to your followers by publishing a kind 6 repost under a specific account's identity, referencing the original event id, and return the published repost event (including its id). Takes the account's private key and the target event id.
deleteEvent
name_restates_behavior no_return_description
Publish a kind 5 deletion request for one or more events the account created, asking relays to treat them as deleted, optionally with a reason, and return a confirmation of the published request. Takes the account's private key and the target event ids.
replyToEvent
name_restates_behavior no_return_description
Post a kind 1 reply to a target event under a specific account's identity, automatically adding the correct NIP-10 thread tags so the reply is threaded to the root and parent, and return the published reply event (including its id). Provide the private key, target event id (hex, note, or nevent), and the reply text.
encryptNip04
no_return_description
Encrypt a plaintext message for a recipient using NIP-04 (AES-CBC), returning the ciphertext in the '<cipher>?iv=<iv>' format that can be sent as a kind 4 DM. Takes the sender's private key and the recipient's public key (hex or npub).
decryptNip04
no_return_description
Decrypt a NIP-04 (AES-CBC) encrypted message using the recipient's private key, returning the original plaintext. Provide the sender's public key and the ciphertext in the '<cipher>?iv=<iv>' format.
sendDmNip04
name_restates_behavior no_return_description
Publish a kind 4 direct message to a recipient, encrypting the content with NIP-04 (AES-CBC) using the sender's private key, and return a confirmation of the published event. Optionally set the created_at timestamp, choose publish relays, and authenticate to relays that require NIP-42.
getDmConversationNip04
no_return_description
Fetch kind 4 direct messages exchanged between your account and a peer from relays, and by default decrypt them with your private key to return the plaintext conversation messages. Optionally limit the number of messages (default 50), filter by a since/until time range, disable decryption to return ciphertext, and authenticate to relays that require NIP-42.
encryptNip44
no_return_description
Encrypt a plaintext message for a recipient using NIP-44 (ChaCha20 + HMAC), returning the encrypted base64 ciphertext payload. Takes the sender's private key and the recipient's public key; optionally specify the NIP-44 version to use.
decryptNip44
no_return_description
Decrypt a NIP-44 (ChaCha20 + HMAC) encrypted payload using the recipient's private key, returning the original plaintext. Provide the sender's public key and the NIP-44 base64 ciphertext.
sendDmNip44
name_restates_behavior no_return_description
Publish a NIP-44 encrypted direct message wrapped as a NIP-17 gift wrap event (kind 1059) so only the recipient can unwrap it, and return a confirmation of the published event. Takes the sender's private key, the recipient's public key, and the plaintext content; optionally choose publish relays and authenticate to relays requiring NIP-42.
decryptDmNip44
name_restates_behavior no_return_description
Unwrap a NIP-17 gift wrapped direct message (kind 1059 event) using the receiver's private key, returning the inner kind 14 rumor including its plaintext content and metadata (author, timestamp, tags). Provide the receiver's private key and the gift wrap event object.
getDmInboxNip44
no_return_description
Fetch the kind 1059 NIP-17 gift wrap events addressed to your account from relays and decrypt them with your private key, returning your received DM messages in plaintext. Optionally limit how many wraps are fetched/decrypted (default 25), filter by a since/until time range, and authenticate to relays that require NIP-42.
sendAnonymousZap
no_return_description
Prepare an anonymous zap (lightning payment with an optional comment) targeting a profile pubkey or a specific event, returning the zap request/bolt11 data needed to complete the payment. Accepts a target in hex, npub, nevent, note, or naddr form and an amount in satoshis (minimum 1).
convertNip19
no_return_description
Convert a NIP-19 entity or hex string between formats (npub, nsec, note, hex, nprofile, nevent, naddr), returning the converted value. Provide the input and target type; supply optional relays, author, kind, or identifier when converting complex entities such as nprofile, nevent, or naddr.
analyzeNip19
no_return_description
Decode a NIP-19 entity or hex string and return its type plus decoded contents (such as the pubkey, event id, relays, or kind), so you can inspect what an npub, nsec, note, nprofile, nevent, or naddr refers to.
postAnonymousNote
name_restates_behavior no_return_description
Publish a kind 1 note to relays under a freshly generated temporary keypair so the post is not linked to an existing account, returning the published event (including its id) and the temporary keypair used. Optionally attach tags or choose which relays to publish to.
createKeypair
no_return_description
Generate a new Nostr keypair, returning the private and public keys in the requested format (hex only, npub only, or both, default both). Useful for creating throwaway accounts or testing without exposing your main keys.
createProfile
name_restates_behavior no_return_description
Create and publish a kind 0 profile event for an account, signing with the provided private key, and return the published event (including its id). Optionally set the display name, about/bio, picture URL, NIP-05 identifier, lightning address (lud16/lud06), and website; choose relays to publish to.
updateProfile
name_restates_behavior no_return_description
Publish an updated kind 0 profile event for an existing account, signing with the provided private key, and return the published event (including its id). Replaces the profile with the fields provided (name, about, picture, nip05, lud16, lud06, website); choose relays to publish to.
postNote
name_restates_behavior no_return_description
Publish a kind 1 text note signed with an existing account's private key (authenticated posting), and return the published note event including its id and the relays it was sent to. Optionally attach tags or choose which relays to publish to.
createNote
name_restates_behavior no_return_description
Create a new kind 1 note event (unsigned) from the provided content and optional tags, returning the event object ready to be signed and then published. Provide the author's private key and the note content.
signNote
name_restates_behavior no_return_description
Sign an unsigned kind 1 note event with a private key, returning the fully signed event with its id and sig populated, ready to publish. Provide the private key and the unsigned note event (kind, content, tags, created_at, pubkey).
publishNote
name_restates_behavior no_return_description
Publish an already-signed kind 1 note event to the specified Nostr relays (or a default set), returning a confirmation of where it was published. Provide the signed note (id, pubkey, created_at, kind, tags, content, sig); optionally choose the relays.
createNostrEvent
name_restates_behavior no_return_description
Create an unsigned Nostr event of any kind, returning the event object ready to sign and publish. Requires the author pubkey (or a private key to derive it) and the event kind; optionally set content, tags, and created_at.
signNostrEvent
name_restates_behavior no_return_description
Sign an unsigned Nostr event with a private key, returning the signed event including its id and sig, ready to publish. Provide the private key and the unsigned event's pubkey, created_at, kind, tags, and content.
publishNostrEvent
name_restates_behavior no_return_description
Publish a signed Nostr event to the specified relays (or a default set), returning confirmation that it was accepted. Provide the signed event (with id and sig); optionally choose publish relays and authenticate to relays that require NIP-42.

Selection evidence

Confusable tool pairs.

50 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.

Tool A Tool B Confidence Why they collide
postAnonymousNote postNote high Both post notes; a task like 'post this anonymously without using my key' vs 'post this note' could pick the wrong one if the agent doesn't notice the anonymous/dedicated-key distinction.
sendDmNip04 sendDmNip44 medium Both send encrypted DMs; 'send an encrypted DM' without specifying NIP leaves the choice ambiguous between NIP-04 and NIP-44/NIP-17.
sendDmNip44 decryptDmNip44 medium Both handle NIP-44 gift-wrapped DMs; a task like 'handle this DM' or 'process my inbox' could pick send instead of decrypt.
getReceivedZaps getAllZaps medium Both fetch zaps for a pubkey; 'show me the zaps for this user' is ambiguous between sent-only, received-only, or all.
getSentZaps getAllZaps medium Same ambiguity: 'get all zaps for this key' could be matched to getAllZaps or, if the agent only recalls a per-direction function, to getSentZaps.
getReceivedZaps getSentZaps medium The descriptions differ only by 'received by' vs 'sent by'; tasks like 'get the zaps of this user' don't make direction clear, though 'received'/'sent' wording helps disambiguate.
getRelayList setRelayList low Get vs set is usually explicit in tasks ('what relays does X use' vs 'publish my relay list'), so confusion is unlikely despite shared kind/token overlap.
sendDmNip44 getDmInboxNip44 medium Both relate to NIP-44 DMs and share gift-wrap/kind tokens; 'deal with my NIP-44 DMs' could route to reading the inbox instead of sending a message.
createNostrEvent publishNostrEvent medium Generic 'Nostr event' tasks ('create this event', 'publish this event') may pick the wrong pipeline stage; create takes content and produces unsigned, publish requires a signed event.
createNostrEvent signNostrEvent medium Both operate on unsigned events with keys; 'sign this event' and 'create this event' are plausibly conflated since create also accepts privateKey.
decryptDmNip44 getDmInboxNip44 medium Both decrypt NIP-44 DMs; 'decrypt my DMs' could route to getDmInboxNip44 (fetch+decrypt) instead of decryptDmNip44 for a specific event.
decryptNip44 decryptDmNip44 medium Both decrypt NIP-44 content; a task 'decrypt this NIP-44 message' is ambiguous between raw ciphertext (decryptNip44) and a gift-wrapped DM event (decryptDmNip44).
getContactList getRelayList low Both are 'get list' tools but for different resources (contacts vs relays); tasks usually name the entity, so confusion is unlikely.
sendDmNip04 getDmConversationNip04 medium Both concern NIP-04 DMs; 'handle my NIP-04 DM conversation' could pick send vs fetch-the-conversation.
signNostrEvent publishNostrEvent low Sign vs publish are distinct pipeline steps explicit in typical tasks; shared 'event/nostr' tokens alone are not enough.
getKind1Notes getLongFormNotes medium Tasks like 'get this user's notes' don't specify kind; agent could pick kind 1 notes when long-form or both were intended.
getDmConversationNip04 getDmInboxNip44 medium Both fetch/decrypt DM conversations but under different NIPs; a task 'get my DMs' is ambiguous regarding NIP-04 vs NIP-44, though NIP is usually stated.
encryptNip04 decryptNip04 low Encrypt vs decrypt tasks are explicit; cipher or plaintext orientation in the input makes the choice clear.
encryptNip44 decryptNip44 low Same as NIP-04: encrypt/decrypt wording in the task resolves ambiguity.
follow unfollow low Follow and unfollow are directly requested in natural-language tasks; semantic opposites are reliably distinguished.
createProfile createNote medium 'Create a profile/note' are distinct nouns, but both are 'create a kind event with content'; a generic 'create a profile post' or 'create a new kind-0 note' could misfire.
createProfile updateProfile medium Both write kind 0 profiles with identical schemas; 'set up my profile' versus 'change my profile' can be ambiguous about create vs update.
reactToEvent repostEvent low Reaction (kind 7) vs repost (kind 6) are clearly different user intents; only fail on a vague phrase like 'interact with this event'.
publishNote publishNostrEvent low Both publish signed events but one is note-specific; tasks usually say 'note' vs generic 'event', so confusion is unlikely.
signNote signNostrEvent low Signing a note vs an arbitrary event is distinguished by 'note' in the task; low risk.
getContactList getFollowing low getFollowing is explicitly documented as an alias of getContactList, so either choice yields the same result.
convertNip19 analyzeNip19 medium Both handle any NIP-19 entity; a task like 'tell me about this npub' could route to analyze, while 'convert this' is mostly explicit.
createKeypair createNote low 'Create a keypair' vs 'create a note' are explicit in the noun; low ambiguity.
createKeypair createProfile low Different artifacts (keys vs profile event); task wording distinguishes them.
createNote publishNote medium Both create/publish a kind-1 note with same content params; a task 'create a note and post it' could stop at createNote (unsigned) instead of publishNote.
createNote signNote medium Both take an unsigned note and a key; 'create the note event' vs 'sign the note' stages may be conflated.
decryptNip04 decryptNip44 low NIP-04 vs NIP-44 is typically mentioned in the task or implied by the ciphertext format; decrypt of raw payload is unambiguous directionally.
deleteEvent replyToEvent low Delete vs reply are distinct actions with different requirements; low ambiguity.
encryptNip04 encryptNip44 low Encrypt direction is explicit; only the NIP version may be unstated, which is usually specified.
getProfile createProfile low Get vs create profile is explicit; task verbs disambiguate.
getProfile getFollowing low One tool returns profile metadata, the other following lists; task nouns distinguish them.
getProfile updateProfile low Read vs write profile is explicit in task language.
postNote publishNote medium Both get a note onto relays but differ in input (privateKey+content vs signedNote); 'publish my note' could pick postNote (which also publishes) rather than publishNote.
postNote signNote low Posting vs signing are distinct stages; 'sign and post' tasks usually list both.
queryEvents deleteEvent low Query vs delete are opposite actions; low ambiguity.
queryEvents reactToEvent low Read vs react; distinct intents.
queryEvents replyToEvent low Read vs reply; distinct intents.
queryEvents repostEvent low Read vs repost; distinct intents.
reactToEvent deleteEvent low Distinct actions; low ambiguity.
reactToEvent replyToEvent low React vs reply are distinct intents; only 'respond to this note' could be ambiguous, which is rare.
repostEvent deleteEvent low Distinct actions; low ambiguity.
repostEvent replyToEvent low Distinct actions; low ambiguity.
sendDmNip04 decryptDmNip44 low Send vs decrypt, and NIP-04 vs NIP-44, are both explicit distinctions in the task.
signNote publishNote low Sign vs publish stages are explicit; inputs differ (unsigned vs signed).
getProfile getReceivedZaps low Profile vs zaps are different entity types; task nouns disambiguate.

Compare the field

One score is useful.
The evidence makes it actionable.

Back to the leaderboard