buzz-mcp
buzz-mcp
MCP (Model Context Protocol) server that connects Claude Desktop, Claude Code, and Claude.ai (web + phone custom connectors) to Miguel's Buzz relay.
It authenticates with NIP-98 (Authorization: Nostr …) and exposes tools to list channels, read/search messages, and post kind-9 chat events.
Transports:
stdio — local Claude Desktop / Claude Code (
npm run start:stdio)Streamable HTTP — remote MCP for Claude.ai custom connectors (
npm start→src/http.js)
Requirements
Node.js 18+
A Nostr keypair for the agent (
BUZZ_PRIVATE_KEY)That agent pubkey must be a Buzz community member (see below)
Quick start
cd /workspace/buzz-mcp
npm install
# Generate an agent keypair
node src/gen-key.jsCopy the printed secret (hex) or nsec into env as BUZZ_PRIVATE_KEY. Keep pubkey/npub to add the agent as a member.
Environment
Variable | Required | Description |
BUZZ_PRIVATE_KEY | yes | 64-char hex secret or nsec1 |
BUZZ_RELAY_URL | no | Default |
PORT | no | HTTP listen port (default |
Add the agent as a Buzz community member
The agent pubkey must already be a member of the Buzz community, or relay writes (and possibly reads) will fail.
Run
node src/gen-key.jsand note the npub / hex pubkey.In Buzz Desktop, invite that pubkey into the community, or
Have a community owner add the agent pubkey as a member.
Until the agent is a member, send_message (and possibly other tools) will be rejected by the relay.
Claude.ai custom connector (web + phone)
Deploy this repo so npm start (node src/http.js) is reachable over public HTTPS (e.g. Railway). Then:
Open Claude.ai → Customize → Connectors
Choose Add custom connector
Paste your MCP URL:
https://YOUR_HOST/mcpExact path Claude should use:
/mcpSave / Connect. No OAuth is required for this server (authless Streamable HTTP).
Health check (optional): GET https://YOUR_HOST/health → 200 with body ok.
The same connector works on Claude phone once added to your account.
Railway
Start command:
npm start(ornode src/http.js) — seeProcfile/DockerfileSet
BUZZ_PRIVATE_KEY(and optionallyBUZZ_RELAY_URL) in Railway variablesPORTis provided by Railway; the server binds0.0.0.0
Claude Desktop / Claude Code (stdio)
Edit Claude Desktop config (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json) and merge:
{
"mcpServers": {
"trego-buzz": {
"command": "node",
"args": ["/ABSOLUTE/PATH/to/buzz-mcp/src/index.js"],
"env": {
"BUZZ_RELAY_URL": "https://trego.communities.buzz.xyz",
"BUZZ_PRIVATE_KEY": "YOUR_AGENT_HEX_OR_NSEC"
}
}
}
}Or run: npm run start:stdio
See also claude_desktop_config.example.json. Restart Claude Desktop after saving.
Absolute path example on this box: /workspace/buzz-mcp/src/index.js
Tools
Tool | What it does |
relay_info | GET / with Accept: application/nostr+json (NIP-11) |
list_channels | POST /query kinds [39000] — channel d-tag + name |
get_messages | Messages in a channel (#h), kinds 9, 40002, 40008, 45001, 45003 |
search_messages | Same kinds + NIP-50 search |
send_message | Sign kind 9 with [h, channel_id] (+ optional e reply), POST /events |
create_channel | Sign kind 9007 with [h, uuid], [name], [visibility], [channel_type], optional [about]; POST /events. Returns the channel_id |
POST /querytakes a bare JSON array of filters ([{...}]), not{"filters": [...]}— the relay deserialisesVec<Filter>and rejects a map withinvalid filters: invalid type: map, expected a sequence.
Auth (NIP-98)
Each HTTP call to the Buzz relay signs a kind 27235 event with tags:
["u", request url]["method", METHOD]["payload", sha256hex(body)]when there is a body["nonce", uuid]
Header: Authorization: Nostr base64(JSON.stringify(event)) via nostr-tools finalizeEvent.
Dev checks
npm install
node src/gen-key.js
node -e "import('./src/server.js').then(m => console.log('ok', m.RELAY_URL))"
node -e "import('./src/http.js').then(() => console.log('http module ok'))"
PORT=3000 BUZZ_PRIVATE_KEY=… npm start
curl -s localhost:3000/healthLayout
buzz-mcp/
package.json
Procfile
Dockerfile
README.md
claude_desktop_config.example.json
src/
server.js # shared createBuzzMcpServer() + tools
index.js # MCP stdio entry
http.js # Streamable HTTP entry (Railway / Claude.ai)
gen-key.js # keypair helper