@bulwarkauth/mcp-auth
v0.1.0
Published
Bulwark authentication provider for MCP servers
Downloads
109
Maintainers
Readme
@bulwark/mcp-auth
Secure authentication for MCP (Model Context Protocol) servers, powered by Bulwark.
Drop-in auth for any MCP server — 3 lines to integrate. Agents get scoped, time-limited credentials. Humans approve once. Everything is audited.
Why
MCP servers connect AI agents to tools and data. But how do you authenticate those connections securely?
Most MCP servers use hardcoded API keys or the developer's own credentials. This means:
- No scoping (the agent has full access to everything the key allows)
- No time limits (the key works forever)
- No audit trail (no record of what the agent accessed)
- No revocation (you can't stop access without rotating the key)
@bulwark/mcp-auth fixes all of this.
Quick Start
Install
npm install @bulwark/mcp-authIntegrate (3 lines)
import { BulwarkMCP } from "@bulwark/mcp-auth";
const bulwark = new BulwarkMCP();
server.tool(
"query_database",
bulwark.protect(async (params, context) => {
// Your tool logic here — Bulwark handles auth
const db = await bulwark.getCredential("database");
return await db.query(params.sql);
}),
);Configure
Set these environment variables (or pass to constructor):
| Variable | Description | Required |
| ------------------- | ------------------------------ | -------- |
| BULWARK_ENDPOINT | Bulwark API URL | Yes |
| BULWARK_AGENT_KEY | Agent API key (bwk_live_...) | Yes |
| BULWARK_TENANT_ID | Tenant ID | Yes |
Claude Desktop Example
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["my-mcp-server"],
"env": {
"BULWARK_ENDPOINT": "https://api.bulwarkauth.com",
"BULWARK_AGENT_KEY": "bwk_live_abc123...",
"BULWARK_TENANT_ID": "your-tenant-id"
}
}
}
}How It Works
- Agent registers with Bulwark — gets an API key
- User authorizes — Bulwark issues a scoped, time-limited credential
- MCP server uses
protect()— Bulwark verifies auth on every tool call - Credentials are proxied — the agent never sees raw API keys
- Session ends — credentials auto-revoke
User → Approves → Bulwark → Scoped Token → MCP Server → Tool
| |
Verifies Proxies credentials
Audits Returns responseAPI Reference
BulwarkMCP
The main class. Create one instance per MCP server.
const bulwark = new BulwarkMCP({
endpoint: "https://api.bulwarkauth.com",
agentKey: "bwk_live_...",
tenantId: "tenant-uuid",
defaultTTL: 900, // 15 minutes
defaultMaxUses: 100,
});bulwark.protect(handler, options?)
Wraps a tool handler with Bulwark authentication.
server.tool(
"my_tool",
bulwark.protect(
async (params, context) => {
// context.sessionId — current Bulwark session
// context.tenantId — tenant ID
return result;
},
{
services: ["my-api"],
operations: ["read"],
ttl: 600,
},
),
);bulwark.getCredential(service)
Gets an authenticated credential for a service.
const cred = await bulwark.getCredential("github");
// cred.headers — auth headers to pass to the servicebulwark.complete()
Ends the current session and revokes all credentials.
BulwarkMCPClient
Lower-level client for direct API access.
import { BulwarkMCPClient } from "@bulwark/mcp-auth";
const client = new BulwarkMCPClient({ endpoint, agentKey, tenantId });
const session = await client.createSession({ task: "...", ttl: 900 });
const result = await client.proxyRequest(session.id, {
service: "api",
method: "GET",
path: "/data",
});
await client.completeSession(session.id);Security
- Credentials are never embedded in tokens — they're injected server-side by Bulwark's credential proxy
- Sessions are time-limited and usage-limited
- All access is audited with full trail
- Tokens support Biscuit-style attenuation — sub-agents get narrower permissions automatically
License
Apache 2.0
