MCP (Model Context Protocol) Integration
Fire Shield provides a Model Context Protocol (MCP) adapter that exposes RBAC functionality as tools for AI agents.
Features
- 8 MCP Tools for permission management
- AI agent integration (Claude Desktop, Continue, etc.)
- Type-safe tool schemas
- Permission checking and management
- Deny permissions support
- Role and permission listing
- Stdio transport for easy integration
- Full TypeScript support
What is MCP?
Model Context Protocol (MCP) is an open protocol that enables AI applications to securely connect with data sources and tools. Think of it as a standard way for AI agents to interact with external systems.
Use cases:
- AI assistants managing user permissions
- Chatbots checking access control
- Automated permission auditing
- AI-powered admin panels
- Permission recommendations
Installation
npm install @fire-shield/mcp @fire-shield/core @modelcontextprotocol/sdkQuick Start
1. Create MCP Server
import { RBAC } from '@fire-shield/core';
import { createMCPServer } from '@fire-shield/mcp';
// Initialize RBAC
const rbac = new RBAC();
rbac.createRole('admin', ['user:*', 'post:*']);
rbac.createRole('editor', ['post:read', 'post:write']);
rbac.createRole('viewer', ['post:read']);
// Create MCP server
const mcpServer = await createMCPServer({
rbac,
serverName: 'fire-shield-rbac',
serverVersion: '2.2.0',
debug: true
});
// Server is now running and listening for MCP requests2. Configure AI Client (Claude Desktop)
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"fire-shield": {
"command": "node",
"args": ["/path/to/your/mcp-server.js"]
}
}
}3. Use in AI Conversations
Now you can ask Claude:
"Check if user123 with role 'editor' can write posts"
Claude will use the check_permission tool to query your RBAC system.
Available MCP Tools
1. check_permission - Check User Permission
Check if a user has a specific permission.
Input Schema:
{
userId: string; // User ID
roles: string[]; // User roles
permission: string; // Permission to check
}Example:
{
"userId": "user123",
"roles": ["editor"],
"permission": "post:write"
}Response:
{
"hasPermission": true,
"allowed": true,
"reason": "Permission granted",
"userId": "user123",
"roles": ["editor"],
"permission": "post:write"
}2. check_role - Check User Role
Check if a user has a specific role.
Input Schema:
{
userId: string; // User ID
roles: string[]; // User roles
role: string; // Role to check
}Example:
{
"userId": "user123",
"roles": ["editor", "viewer"],
"role": "editor"
}Response:
{
"hasRole": true,
"userId": "user123",
"roles": ["editor", "viewer"],
"role": "editor"
}3. list_permissions - List User Permissions
Get all permissions for a user based on their roles.
Input Schema:
{
userId: string; // User ID
roles: string[]; // User roles
}Example:
{
"userId": "user123",
"roles": ["editor"]
}Response:
{
"userId": "user123",
"roles": ["editor"],
"permissions": ["post:read", "post:write"]
}4. deny_permission - Deny Permission
Deny a specific permission for a user (overrides role permissions).
Input Schema:
{
userId: string; // User ID
permission: string; // Permission to deny
}Example:
{
"userId": "user123",
"permission": "post:delete"
}Response:
{
"success": true,
"message": "Permission 'post:delete' denied for user user123",
"userId": "user123",
"permission": "post:delete"
}5. allow_permission - Allow Permission
Remove a denied permission (restores role permissions).
Input Schema:
{
userId: string; // User ID
permission: string; // Permission to allow
}Example:
{
"userId": "user123",
"permission": "post:delete"
}Response:
{
"success": true,
"message": "Permission 'post:delete' allowed for user user123",
"userId": "user123",
"permission": "post:delete"
}6. get_denied_permissions - Get Denied Permissions
Get all denied permissions for a user.
Input Schema:
{
userId: string; // User ID
}Example:
{
"userId": "user123"
}Response:
{
"userId": "user123",
"deniedPermissions": ["post:delete", "user:write"]
}7. list_roles - List All Roles
List all available roles in the RBAC system.
Input Schema:
{} // No parameters requiredResponse:
{
"roles": ["admin", "editor", "viewer"]
}8. get_role_permissions - Get Role Permissions
Get all permissions for a specific role.
Input Schema:
{
role: string; // Role name
}Example:
{
"role": "editor"
}Response:
{
"role": "editor",
"permissions": ["post:read", "post:write"]
}API Reference
FireShieldMCPServer
Main class for creating an MCP server.
class FireShieldMCPServer {
constructor(options: FireShieldMCPOptions);
async start(): Promise<void>;
getServer(): Server;
}FireShieldMCPOptions
Configuration options for the MCP server.
interface FireShieldMCPOptions {
rbac: RBAC; // RBAC instance
serverName?: string; // Server name (default: 'fire-shield-rbac')
serverVersion?: string; // Server version (default: '2.2.0')
debug?: boolean; // Enable debug logging (default: false)
}createMCPServer()
Factory function to create and start an MCP server.
async function createMCPServer(
options: FireShieldMCPOptions
): Promise<FireShieldMCPServer>startStandalone()
Start a standalone MCP server from a preset configuration.
async function startStandalone(config: PresetConfig): Promise<void>Usage Examples
Standalone Server
Create a standalone MCP server file:
// mcp-server.ts
import { RBAC } from '@fire-shield/core';
import { createMCPServer } from '@fire-shield/mcp';
async function main() {
// Initialize RBAC with your configuration
const rbac = new RBAC();
// Define roles
rbac.createRole('admin', ['*']);
rbac.createRole('editor', ['post:read', 'post:write', 'post:edit']);
rbac.createRole('viewer', ['post:read']);
// Create and start MCP server
const server = await createMCPServer({
rbac,
serverName: 'my-app-rbac',
serverVersion: '1.0.0',
debug: process.env.NODE_ENV === 'development'
});
console.error('MCP server started successfully');
}
main().catch(console.error);Build and run:
# Build
npx tsc mcp-server.ts
# Run
node mcp-server.jsLoad from Config File
// mcp-server-config.ts
import { RBAC } from '@fire-shield/core';
import { createMCPServer } from '@fire-shield/mcp';
import { readFileSync } from 'fs';
async function main() {
// Load RBAC configuration from file
const config = JSON.parse(readFileSync('./rbac-config.json', 'utf-8'));
const rbac = new RBAC({ preset: config });
// Create MCP server
await createMCPServer({
rbac,
serverName: config.name || 'fire-shield-rbac',
serverVersion: config.version || '1.0.0'
});
}
main().catch(console.error);Config file (rbac-config.json):
{
"name": "my-app-rbac",
"version": "1.0.0",
"permissions": [
{ "name": "user:read", "bit": 1 },
{ "name": "user:write", "bit": 2 },
{ "name": "post:read", "bit": 4 },
{ "name": "post:write", "bit": 8 }
],
"roles": [
{ "name": "admin", "permissions": ["user:*", "post:*"] },
{ "name": "editor", "permissions": ["post:read", "post:write"] },
{ "name": "viewer", "permissions": ["post:read"] }
]
}Integration with Express API
Use MCP server alongside your API:
import express from 'express';
import { RBAC } from '@fire-shield/core';
import { createMCPServer } from '@fire-shield/mcp';
// Shared RBAC instance
const rbac = new RBAC();
rbac.createRole('admin', ['*']);
rbac.createRole('editor', ['post:*']);
// Start Express API
const app = express();
app.use(express.json());
app.post('/api/check-permission', (req, res) => {
const { user, permission } = req.body;
const hasPermission = rbac.hasPermission(user, permission);
res.json({ hasPermission });
});
app.listen(3000, () => {
console.log('API running on port 3000');
});
// Start MCP server (shares the same RBAC instance)
createMCPServer({
rbac,
debug: true
}).then(() => {
console.error('MCP server started');
});Claude Desktop Configuration
Basic Configuration
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) %APPDATA%\Claude\claude_desktop_config.json (Windows)
{
"mcpServers": {
"fire-shield": {
"command": "node",
"args": ["/absolute/path/to/mcp-server.js"]
}
}
}With Environment Variables
{
"mcpServers": {
"fire-shield": {
"command": "node",
"args": ["/path/to/mcp-server.js"],
"env": {
"NODE_ENV": "production",
"RBAC_CONFIG": "/path/to/rbac-config.json"
}
}
}
}Using npx
{
"mcpServers": {
"fire-shield": {
"command": "npx",
"args": [
"-y",
"tsx",
"/path/to/mcp-server.ts"
]
}
}
}AI Conversation Examples
Example 1: Check Permission
User: "Check if user 'john' with role 'editor' can write posts"
Claude: Uses check_permission tool
{
"userId": "john",
"roles": ["editor"],
"permission": "post:write"
}Response: "Yes, user 'john' with role 'editor' has permission to write posts."
Example 2: List Permissions
User: "What permissions does the editor role have?"
Claude: Uses get_role_permissions tool
{
"role": "editor"
}Response: "The editor role has the following permissions:
- post:read
- post:write
- post:edit"
Example 3: Deny Permission
User: "Temporarily revoke post delete permission from user 'alice'"
Claude: Uses deny_permission tool
{
"userId": "alice",
"permission": "post:delete"
}Response: "I've denied the 'post:delete' permission for user 'alice'. This override takes precedence over their role permissions."
Example 4: Audit Permissions
User: "Show me all permissions for user 'bob' with roles 'editor' and 'moderator'"
Claude: Uses list_permissions tool
{
"userId": "bob",
"roles": ["editor", "moderator"]
}Response: "User 'bob' with roles 'editor' and 'moderator' has these permissions:
- post:read
- post:write
- post:edit
- comment:moderate
- comment:delete"
Integration with Continue
Continue is an AI code assistant that supports MCP.
Configuration
Add to Continue config (.continue/config.json):
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "node",
"args": ["/path/to/mcp-server.js"]
}
}
]
}
}Usage
In your IDE, ask Continue:
- "Check if this user has admin permissions"
- "What roles are available in our RBAC system?"
- "List all permissions for the editor role"
Debugging
Enable Debug Mode
const server = await createMCPServer({
rbac,
debug: true // Enables debug logging to stderr
});View MCP Messages
MCP communication happens over stdio:
- stdin: Receives MCP requests
- stdout: Sends MCP responses
- stderr: Debug logs (when debug: true)
Test Tools Manually
You can test MCP tools using the MCP Inspector:
npm install -g @modelcontextprotocol/inspector
# Inspect your server
mcp-inspector node mcp-server.jsBest Practices
1. Separate MCP Server Process
Run your MCP server as a separate process from your main application:
// Good: Dedicated MCP server
// mcp-server.ts
createMCPServer({ rbac });
// app.ts
// Your main application2. Share Configuration
Use the same RBAC configuration across your app and MCP server:
// config/rbac.ts
export const rbacConfig = {
permissions: [...],
roles: [...]
};
// app.ts
const rbac = new RBAC({ preset: rbacConfig });
// mcp-server.ts
const rbac = new RBAC({ preset: rbacConfig });3. Validate User Input
Always validate user IDs and roles from AI agents:
const allowedUsers = ['user1', 'user2', 'user3'];
if (!allowedUsers.includes(userId)) {
throw new Error('Invalid user ID');
}4. Audit MCP Operations
Log all permission checks and modifications:
const rbac = new RBAC({
auditLogger: new BufferedAuditLogger(async (logs) => {
console.log('MCP Audit:', logs);
await database.saveLogs(logs);
})
});5. Secure Your MCP Server
MCP servers should only be accessible to trusted AI agents:
- ✅ Run on localhost only
- ✅ Use process isolation
- ✅ Validate all inputs
- ❌ Don't expose over network without authentication
Limitations
- No Network Transport: Currently only stdio transport is supported
- Stateless: Each tool call is independent (no session state)
- Synchronous: All operations are synchronous (no async RBAC operations in tools)
Troubleshooting
MCP Server Not Starting
Error: Cannot find module '@modelcontextprotocol/sdk'
Solution:
npm install @modelcontextprotocol/sdkTools Not Appearing in Claude
Problem: Claude doesn't show Fire Shield tools
Solutions:
- Check config file path
- Ensure server script is executable
- Restart Claude Desktop
- Check stderr for errors
Permission Check Returning Wrong Results
Problem: check_permission returns unexpected results
Solutions:
- Verify RBAC configuration is loaded correctly
- Check user roles are spelled correctly
- Enable debug mode to see logs
- Test with CLI tool first:
fire-shield check config.json -u user1 -r editor -p post:write
Performance
- Cold Start: ~50-100ms
- Tool Execution: <1ms per operation
- Memory: ~10-20MB (depends on RBAC size)
Next Steps
- Core API - RBAC API reference
- CLI Tool - Command-line validation
- Deny Permissions - Understanding denies
- MCP Protocol - Learn more about MCP
Resources
- MCP Specification: https://modelcontextprotocol.io
- MCP SDK: https://github.com/modelcontextprotocol/typescript-sdk
- Claude Desktop: https://claude.ai/download
- Continue: https://continue.dev
