Nostrbook Extension
This tutorial covers how to add the Nostrbook MCP Server as a Goose extension to provide access to a comprehensive registry of Nostr documentation that helps users understand the decentralized social protocol, its implementation possibilities, and technical specifications.
Command
npx -y xjsr @nostrbook/mcp
Configuration
Note that you'll need Node.js installed on your system to run this command, as it uses npx
.
- Goose Desktop
- Goose CLI
- Launch the installer
- Press
Yes
to confirm the installation - Click
Save Configuration
- Scroll to the top and click
Exit
from the upper left corner
- Run the
configure
command:
goose configure
- Choose to add a
Command-line Extension
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◆ What type of extension would you like to add?
│ ○ Built-in Extension
│ ● Command-line Extension (Run a local command or script)
│ ○ Remote Extension
└
- Give your extension a name
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◆ What would you like to call this extension?
│ Nostrbook
└
- Enter the command
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ Nostrbook
│
◆ What command should be run?
│ npx -y xjsr @nostrbook/mcp
└
- Enter the number of seconds Goose should wait for actions to complete before timing out. Default is 300s
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ Nostrbook
│
◇ What command should be run?
│ npx -y xjsr @nostrbook/mcp
│
◆ Please set the timeout for this tool (in secs):
│ 300
│
└
- Choose to add a description. If you select "Yes" here, you will be prompted to enter a description for the extension.
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ Nostrbook
│
◇ What command should be run?
│ npx -y xjsr @nostrbook/mcp
│
◇ Please set the timeout for this tool (in secs):
│ 300
│
◇ Would you like to add a description?
│ No
│
└
- Choose No when asked to add environment variables
┌ goose-configure
│
◇ What would you like to configure?
│ Add Extension
│
◇ What type of extension would you like to add?
│ Command-line Extension
│
◇ What would you like to call this extension?
│ Nostrbook
│
◇ What command should be run?
│ npx -y xjsr @nostrbook/mcp
│
◇ Please set the timeout for this tool (in secs):
│ 300
│
◇ Would you like to add a description?
│ No
│
◆ Would you like to add environment variables?
│ No
│
└ Added Nostrbook extension
Example Usage
Goose Prompt
Goose, what is the NIP-61 and how can I implement it?.
Goose Output
Note that IDs have been changed to generic ones
Tool Calls
─── read_nip | nostrbook ──────────────────────────
nip: 61
NIP-61: Implementing Nutzaps
NIP-61 defines "Nutzaps," which are P2PK Cashu tokens where the payment itself acts as the receipt. This protocol allows for Bitcoin micropayments through the Nostr ecosystem using Cashu tokens.
Core Concept
Nutzaps enable users to send small Bitcoin payments to each other through Nostr events, with the tokens being locked to the recipient's specified public key.
Implementation Guide
Prerequisites
- Familiarize yourself with Cashu and P2PK token locking
- Understand NIP-60 for wallet functionality
- Ensure your implementation supports NUT-11 (P2PK) and NUT-12 (DLEQ proofs)
Step 1: Set Up Recipient Information (For Receiving Nutzaps)
Create and publish a kind:10019
event to inform others how to send you money:
{
"kind": 10019,
"tags": [
["relay", "wss://your-relay1.com"],
["relay", "wss://your-relay2.com"],
["mint", "https://your-trusted-mint.com", "sat"],
["pubkey", "<your-p2pk-pubkey>"]
]
}
- The
pubkey
should be a dedicated public key (NOT your Nostr identity key) - Store the corresponding private key safely in your NIP-60 wallet event
- List only mints you trust and monitor
Step 2: Building the Sender Functionality
To implement nutzapping:
-
Query recipient information:
// Fetch recipient's kind:10019 event
const recipientInfo = await relay.get({
kinds: [10019],
authors: [recipientPubkey]
}); -
Extract mint and P2PK information:
const recipientMints = recipientInfo.tags
.filter(tag => tag[0] === 'mint')
.map(tag => tag[1]);
const recipientLockKey = recipientInfo.tags
.find(tag => tag[0] === 'pubkey')?.[1]; -
Mint or swap tokens at one of the recipient's trusted mints, P2PK-locking them to their specified key
-
Publish the nutzap event:
{
"kind": 9321,
"content": "Thanks for your post!",
"tags": [
["proof", "{\"amount\":1,\"C\":\"02...3f\",\"id\":\"000...\",\"secret\":\"[\\\"P2PK\\\",...]\"}"],
["u", "https://recipient-specified-mint.com"],
["e", "<event-being-zapped>", "<relay-hint>"],
["p", "<recipient-pubkey>"]
]
}
Step 3: Building the Recipient Functionality
To implement nutzap receiving:
-
Query for incoming nutzaps:
// Subscribe to nutzap events
relay.subscribe([
{
kinds: [9321],
"#p": [myPubkey],
"#u": myTrustedMints,
since: lastCheckTimestamp
}
]); -
Validate incoming nutzaps:
- Verify the token is from a mint you've specified
- Verify the token is locked to your P2PK key
- Verify the DLEQ proof
-
Redeem the token:
- Swap the P2PK token into your wallet
- Create a
kind:7376
event to record redemption:
{
"kind": 7376,
"content": "<encrypted-content>",
"tags": [
["e", "<nutzap-event-id>", "", "redeemed"],
["p", "<sender-pubkey>"]
]
}
Important Implementation Details
- P2PK Key Prefixing: Always prefix the P2PK-lock public key with "02" for compatibility
- Token Verification: Implement local verification of DLEQ proofs
- Mint URL Normalization: Normalize mint URLs to avoid issues with slight URL variations
- User Guidance: Guide users to use only NUT-11 and NUT-12 compatible mints
- Publishing Locations: Publish nutzap events to the recipient's specified relays
Testing
When testing your implementation:
- Create test nutzaps with small amounts
- Verify token redemption works correctly
- Check that redemption records are properly created
- Test with multiple mints for compatibility
Security Considerations
- Never use the user's main Nostr key for P2PK operations
- Ensure proper encryption of sensitive wallet data
- Validate all proofs before attempting to redeem tokens
- Only interact with explicitly trusted mints
By following these steps, you can implement a complete nutzap solution that allows users to send and receive Bitcoin micropayments through the Nostr protocol using Cashu tokens.