Bearer keys. Stateless JSON-RPC. Family-scope read tools with an append-only audit log. A caregiver mints a key in the Nunabot app, pastes it into Claude Desktop or Cursor, and the assistant can immediately query their loved ones and recent care events — scoped to their own workspace, nothing more.
The Nunabot MCP server exposes a small, opinionated toolbelt to any AI assistant that speaks the Model Context Protocol. A caregiver mints a key in the Nunabot app, pastes it into Claude Desktop, Cursor, or a custom agent, and the assistant can immediately query their loved ones and recent care events — scoped to their own workspace, nothing more.
Caregivers sign into app.nunabot.com, open
Settings → MCP API keys, and mint a key. Keys look like
sk-nuna-<64 hex chars>, are stored server-side as SHA-256 hashes
(the plaintext is shown exactly once and never persisted), and can be revoked from the
same page. Revoked keys are rejected on the very next request — no cache to bust.
Authorization: Bearer sk-nuna-4c2fa8e1b7d9…
In-app agents running on app.nunabot.com or soft.nunabot.com
authenticate automatically via the __nunabot_session cookie — no key needed.
This page covers the external-agent case.
S256, and scope-gated tokens. Bearer keys stay supported indefinitely
for personal agents; OAuth is for third-party apps that want to onboard caregivers
without handling long-lived secrets.
One endpoint: POST https://app.nunabot.com/api/mcp. Standard MCP JSON-RPC 2.0
envelopes in the body, a single JSON-RPC response in the reply. Each POST is stateless —
no session handshake between requests — which keeps the server compatible with Vercel's
serverless routing and matches the
Streamable HTTP
transport. Server-initiated streaming is a roadmap item; v1 does not open long-lived
connections.
POST /api/mcp HTTP/1.1 Host: app.nunabot.com Authorization: Bearer sk-nuna-… Content-Type: application/json {"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"list_care_events", "arguments":{"limit":10}}}
Supported JSON-RPC methods:
initialize — server info and capabilities handshake.tools/list — discover the current tool registry.tools/call — invoke a tool by name with { name, arguments }.ping — protocol-level liveness probe (distinct from the ping tool).pong plus the verified caller's uid, tenant, and auth method. No side effects.lovedOneId is given, otherwise aggregated across the workspace. Capped at 50 events per call.
Each tool re-derives ownership from the verified caller. Passing a lovedOneId
that belongs to someone else's workspace returns a clean
not authorized error — Admin SDK reads on the server bypass Firestore rules, so the
tool layer is the enforcement point.
Retry-After and JSON-RPC error code -32029.
Every call writes one row to the internal mcp_audit_log with the verified
uid, tenant, method, tool name, success flag, and duration. Tool arguments and
tool results are not stored — sensitive data stays in the request and in short-term
Vercel / Cloud Run logs. Nunabot handles PHI under a BAA; agents that surface care events
to their own end users are responsible for their own BAA posture downstream.
Retry-After.error.message.{
"mcpServers": {
"nunabot": {
"url": "https://app.nunabot.com/api/mcp",
"headers": { "Authorization": "Bearer sk-nuna-…" }
}
}
}
In Cursor settings, add a new MCP server with the same URL and Authorization header.
# Expect: "pong from nunabot platform — uid=… tenant=… via=api-key" curl -s https://app.nunabot.com/api/mcp \ -H "Authorization: Bearer sk-nuna-…" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ping","arguments":{}}}'
# Nunabot MCP — family-scope read tools [mcp_servers.nunabot] url = "https://app.nunabot.com/api/mcp" auth_header = "Bearer sk-nuna-…"
Looking for the rest of the stack? NunaPipe · NunaSoft · All docs