@sonnylabs/mcp
v0.2.1
Published
Model Context Protocol server for the Sonny Labs AI firewall. Run it inside your agentic client (Claude Desktop, Cursor, Claude Code) to scan prompts and outputs for injection / PII / toxicity, manage API keys, and scaffold the firewall into your codebase
Readme
@sonnylabs/mcp
Model Context Protocol server for the Sonny Labs AI firewall. Run it locally next to your agentic client (Claude Desktop, Cursor, Claude Code, etc.) and your agent can:
- Scan prompts and model outputs for prompt-injection, PII, toxicity,
and policy violations via the
sonny_scantool. - Manage API keys and inspect past scans without leaving the chat.
- Integrate SonnyLabs into your codebase via guided MCP prompts (FastAPI, Express, Next.js App Router, LangChain.js) that drop the middleware into the chat ready to paste.
The package wraps @sonnylabs/sdk
and works identically against the SaaS endpoint and a self-hosted
deployment — only the SONNYLABS_BASE_URL env var changes.
Install
The MCP server runs as a stdio process spawned by your host. Most
hosts can npx it directly — no global install needed.
Configure your host
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
{
"mcpServers": {
"sonnylabs": {
"command": "npx",
"args": ["-y", "@sonnylabs/mcp"],
"env": {
"SONNYLABS_API_KEY": "sk_live_..."
}
}
}
}Claude Code / Cursor
Both read MCP server definitions from the same JSON shape.
Cursor: ~/.cursor/mcp.json. Claude Code: ~/.claude.json under
mcpServers.
Self-hosted backend
Point at your own ingress with SONNYLABS_BASE_URL. Same package,
same code path:
{
"mcpServers": {
"sonnylabs": {
"command": "npx",
"args": ["-y", "@sonnylabs/mcp"],
"env": {
"SONNYLABS_API_KEY": "sk_live_...",
"SONNYLABS_BASE_URL": "https://sonnylabs.internal.example.com"
}
}
}
}Avoid plaintext keys (shared / corporate machines)
Host config files sit in plaintext on disk. For shared workstations,
set SONNYLABS_API_KEY_FILE instead — the server reads the file at
startup, never re-reads, and the host only needs to know the path:
{
"mcpServers": {
"sonnylabs": {
"command": "npx",
"args": ["-y", "@sonnylabs/mcp"],
"env": {
"SONNYLABS_API_KEY_FILE": "/Users/me/.config/sonnylabs/key"
}
}
}
}Drop the file with chmod 600 ~/.config/sonnylabs/key.
Tool surface
All tools are prefixed sonny_ so they don't collide with other MCP
servers' tools.
| Tool | Purpose |
| ------------------------------ | ------------------------------------------------------------------------------- |
| sonny_scan | Scan text for injection / PII / toxicity. Hot path. |
| sonny_get_scan | Fetch a past scan by id. |
| sonny_list_scans | List recent scans (cursor-paginated, filterable). |
| sonny_whoami | Show the Principal (org / scopes) the API key represents. |
| sonny_liveness | Connectivity probe. |
| sonny_list_api_keys | List API keys in the calling org. |
| sonny_create_api_key | Mint a new API key (privileged). |
| sonny_revoke_api_key | Revoke a key by id. |
| sonny_integration_snippet | Emit canonical integration code for FastAPI / Express / Next.js / LangChain. |
| sonny_list_planned_endpoints | Discovery: list backend endpoints declared in the spec but not yet implemented. |
Privacy: sonny_scan is redacted by default
MCP hosts log every tool call argument and every tool response. That means a naive scan tool would echo PII spans straight into the host's audit log — defeating the firewall.
sonny_scan defaults to redact: true, returning only:
{
"scan_id": "scan_01H...",
"decision": { "action": "blocked", "reason": "rule_match" },
"findings_summary": { "count": 2, "detectors": ["pii", "prompt_injection"] },
"content_stored": false,
}If the agent needs the full finding spans, pass redact: false. To
later replay the original input text via sonny_get_scan, also pass
capture: true so the backend retains the content for the configured
retention window.
Prompts
MCP prompts are server-defined templates a user can invoke from their host UI. This package ships:
integrate-fastapi,integrate-express,integrate-nextjs,integrate-langchain— guided walkthroughs that wire SonnyLabs into the user's codebase.pre-pr-scan— pre-PR review pass that scans pending changes for hard-coded prompt-injection / PII / risky tool descriptions.
The integration prompts share their snippets with the
sonny_integration_snippet tool — invoke either, get the same code.
Troubleshooting
"preflight failed: code=auth.api_key.invalid"
The API key didn't authenticate. Check that it isn't revoked and
matches the deployment (a sk_test_* key won't work against a
production base URL).
"warning: API key is missing the mcp:invoke scope"
The mcp:invoke scope is reserved-but-not-enforced today. The
warning is a heads-up: when backend enforcement lands, you'll need a
key minted with that scope. Mint one now via the dashboard or via
sonny_create_api_key.
The host shows the server but no tools
Check stderr (Claude Desktop logs to
~/Library/Logs/Claude/mcp*.log on macOS). The startup line includes
the version diagnostic:
[sonnylabs-mcp] starting v0.2.1 baseUrl=https://api.sonnylabs.ai (default) apiVersion=(server default)
[sonnylabs-mcp] connected: org=org_... key=ak_... scopes=[...]
[sonnylabs-mcp] ready (stdio transport)If the line stops at "starting", the config didn't pass an API key. If it stops at "connected", the transport handshake failed — re-check the host's config syntax.
License
Apache-2.0. You are free to use, modify, and redistribute this server,
including inside proprietary products, as long as you preserve the
LICENSE file and the copyright notice in your redistribution. The
full LICENSE text ships inside every install — once npx -y @sonnylabs/mcp
runs, you can find it next to the package files.
