nostr-mcp-auth
A Nostr-based authentication gate for MCP servers that requires agents to sign HTTP requests with a Nostr key, verifying signatures offline to secure tool access.
README
nostr-mcp-auth
Lock MCP tools to a Nostr key
No proof, no tools. Agents sign every HTTP call with a Nostr secret. The server checks the signature offline. Wrong key, bad sig, stale event, or body swap: 401. Tool code never runs.
pip install -e .
nostr-mcp-auth quickstart
nostr-mcp-auth serve
# other terminal:
nostr-mcp-auth call --tool whoami
Crypto identity for agent tool access. No OAuth dance required for the lab or fleet path.
What is Nostr?
Nostr is a simple open protocol for signed messages. Each user (or agent) has:
| Piece | What it is |
|---|---|
| nsec | Private key. Signs. Keep offline / in a vault. |
| npub | Public key. Identity. Safe to put on an allowlist. |
Messages (events) are JSON objects with a BIP-340 Schnorr signature. Anyone can verify who signed without a central account server.
Common uses: social apps, relays, Lightning wallet connect. The part we care about for MCP is pure crypto identity: prove key possession.
You do not need Damus, a public relay, or a social profile for this package. Verification is local.
NIP-98 (HTTP auth)
NIP-98 defines how to authorize an HTTP request with a short-lived signed event:
- Kind 27235
- Tags bind the request: URL (
u), method (method), optional body hash (payload) - Header:
Authorization: Nostr <base64-encoded event>
That is the protocol. This repo turns it into a gate in front of MCP tools.
How we use Nostr for MCP
MCP (Model Context Protocol) is how agents call tools over stdio or HTTP. Network MCP needs auth. We put NIP-98 on POST /mcp.
| Step | What happens |
|---|---|
| 1 | Agent (or sidecar) builds a NIP-98 event for this exact URL, method, and body. |
| 2 | Signs with nsec. |
| 3 | Sends JSON-RPC (tools/list / tools/call) plus Authorization: Nostr …. |
| 4 | Server verifies: kind, signature, time window, URL/method match, body hash, allowlist, optional roles, replay. |
| 5 | Only then does the tool run. |
Agent / sidecar MCP server (this package)
| |
| POST /mcp |
| Authorization: Nostr <signed event> |
| tools/call { name, arguments } |
|----------------------------------------->|
| | verify NIP-98 (offline)
| | allowlist + roles
| | run tool OR 401/403
|<-----------------------------------------|
What we take from Nostr
- Keypair identity (
npub/nsec) - Event shape + Schnorr signatures
- NIP-98 request binding
What we do not need
- Public relays for auth
- Social graph, follows, or notes
- Publishing the auth event anywhere
What we add
- Fail-closed HTTP MCP surface (
tools/list,tools/call) - Allow / deny lists and optional tool roles
- Process-local replay defense
- Operator CLI:
quickstart,serve,call,doctor - Red-team tested gate (see
docs/)
Plug in
Install
git clone https://github.com/SamsonCyber/nostr-mcp-auth.git
cd nostr-mcp-auth
pip install -e .
Bootstrap
nostr-mcp-auth quickstart
| File | Purpose |
|---|---|
caller.nsec |
Agent secret (never commit) |
caller.npub |
Public identity |
mcp-auth.yaml |
Server config; npub already allowlisted |
Serve
nostr-mcp-auth serve
# http://127.0.0.1:8787/mcp
# http://127.0.0.1:8787/health (public)
serve refuses auth.open=true and auth.trust_proxy=true unless you pass
--force-open or --force-trust-proxy (lab / reverse-proxy only).
Call
nostr-mcp-auth call --tool whoami
nostr-mcp-auth call --tool protected_echo --arg text=hello
nostr-mcp-auth list-tools
nostr-mcp-auth doctor
Python
from nostr_mcp_auth.client import call_tool
print(call_tool("http://127.0.0.1:8787/mcp", "caller.nsec", "whoami"))
See examples/python_agent.py.
Agent UIs that cannot sign (Claude Desktop, etc.)
Most hosts do not implement NIP-98. Options:
- Local signing sidecar that holds
nsecand forwards signed HTTP. - Keep high-risk tools on this HTTP gate; use stdio only where local trust is enough.
Unsigned or plain Bearer clients get 401. That is the gate doing its job.
Endpoints and demo tools
| Path | Auth |
|---|---|
GET /health |
Public |
GET /ready |
Public |
POST /mcp |
Required |
| Tool | Access |
|---|---|
whoami |
Allowlisted identity |
protected_echo |
Allowlisted identity |
admin_ping |
Role tools:admin |
Wire real tools behind the same pattern, or terminate network MCP at this process.
Fail-closed checks
| Check | Result |
|---|---|
| Missing / wrong auth | 401, no tool side effects |
| Bad signature / wrong kind | 401 |
| Clock skew outside window | 401 |
| URL or method mismatch | 401 |
| Body hash mismatch | 401 |
| Empty allowlist | 401 for everyone |
| Deny list | Wins over allow |
| Replay (same event id) | 401 (process-local) |
| Missing tool role | 403 |
| Auth failure body | Generic unauthorized (no fine reason oracle) |
| MCP responses | Cache-Control: no-store (not shared-cacheable) |
Defaults: open: false, trust_proxy: false. Auth logs never print nsec or full
Authorization tokens. Multi-instance shared replay and stolen allowlisted nsec
remain residual (see residual risks).
More: SPEC · residual risks · red-team · wave 2
Config
auth:
open: false
allow_npubs:
- npub1...
roles:
npub1...: [tools:admin]
tools:
admin_ping:
roles: [tools:admin]
server:
host: 127.0.0.1
port: 8787
Add agents by generating keys and appending npubs. Example: examples/mcp-auth.example.yaml.
CLI
| Command | Job |
|---|---|
quickstart |
Identity + config |
serve |
Authenticated MCP HTTP (--force-open / --force-trust-proxy if needed) |
call / list-tools |
Signed client |
doctor |
Config + nsec + allowlist check |
gen-key / init |
Manual pieces |
Dev
pip install -e ".[dev]"
pytest -q
Python 3.10+. Uses coincurve for BIP-340.
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。