Eunomia MCP authorization middleware
Project description
Eunomia MCP Authorization Middleware
Add policy-based authorization to your MCP servers built on FastMCP with minimal code changes.
Overview
Features
- 🔒 Policy-Based Authorization: Control which agents can access which MCP resources and tools
- 📊 Audit Logging: Track all authorization decisions and violations
- ⚡ FastMCP Integration: One-line middleware integration with FastMCP servers
- 🔧 Flexible Configuration: JSON-based policies with support for complex rules
- 🎯 MCP-Aware: Built-in understanding of MCP protocol (tools, resources, prompts)
Architecture
sequenceDiagram
participant MCPClient as MCP Client
participant EunomiaMiddleware as Eunomia Middleware
participant MCPServer as MCP Server
participant EunomiaServer as Eunomia Server
MCPClient->>EunomiaMiddleware: MCP Request
Note over MCPClient, EunomiaMiddleware: Middleware intercepts request to server
EunomiaMiddleware->>EunomiaServer: Authorization Check
EunomiaServer->>EunomiaMiddleware: Authorization Decision (allow/deny)
EunomiaMiddleware-->>MCPClient: MCP Unauthorized Error (if denied)
EunomiaMiddleware->>MCPServer: MCP Request (if allowed)
MCPServer-->>MCPClient: MCP Response (if allowed)
Installation
pip install eunomia-mcp
Quick Start
Create a MCP Server with Middleware
Basic Integration
from fastmcp import FastMCP
from eunomia_mcp import EunomiaMcpMiddleware
# Create your FastMCP server
mcp = FastMCP("Secure MCP Server 🔒")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Add Eunomia authorization middleware
middleware = EunomiaMcpMiddleware()
# Create ASGI app with authorization
app = mcp.add_middleware(middleware)
if __name__ == "__main__":
mcp.run()
[!IMPORTANT]
Eunomia is a standalone server that handles the policy decisions, you must have it running alongside the MCP server.
Run it in the background with Docker:
docker run -d -p 8000:8000 --name eunomia ttommitt/eunomia-server:latestOr refer to the Eunomia documentation for more options.
Advanced Integration
Configure the middleware with custom options for production deployments:
from fastmcp import FastMCP
from eunomia_mcp import create_eunomia_middleware
mcp = FastMCP("Secure MCP Server 🔒")
# Configure middleware with custom options
middleware = [
create_eunomia_middleware(
eunomia_endpoint="https://your-eunomia-server.com",
eunomia_api_key="your-api-key",
enable_audit_logging=True,
)
]
app = mcp.http_app(middleware=middleware)
Policy Configuration
Use the eunomia-mcp CLI to manage your MCP authorization policies:
Initialize a New Project
# Create a default policy configuration file
eunomia-mcp init
# Create policy configuration file with custom name
eunomia-mcp init --policy-file my_policies.json
# Generate both policy configuration file and a sample MCP server
eunomia-mcp init --sample
You can now edit the policy configuration file to your liking.
Validate Policy Configuration
# Validate your policy file
eunomia-mcp validate mcp_policies.json
Push Policies to Eunomia
# Push your policy to Eunomia server
eunomia-mcp push mcp_policies.json
# Push your policy and overwrite existing ones
eunomia-mcp push mcp_policies.json --overwrite
[!IMPORTANT] You need the Eunomia server running for the push operation.
Workflow: Initialize → Customize policies → Validate → Run Eunomia server → Push to Eunomia → Run MCP server
Further Reading
MCP Method Mappings
| MCP Method | Resource URI | Action | Middleware behavior |
|---|---|---|---|
tools/list |
mcp:tools:{name} |
list |
Filters the server's response |
resources/list |
mcp:resources:{name} |
list |
Filters the server's response |
prompts/list |
mcp:prompts:{name} |
list |
Filters the server's response |
tools/call |
mcp:tools:{name} |
call |
Blocks/forwards the request to the server |
resources/read |
mcp:resources:{name} |
read |
Blocks/forwards the request to the server |
prompts/get |
mcp:prompts:{name} |
get |
Blocks/forwards the request to the server |
The Middleware extracts additional attributes from the request that are passed to the decision engine that can be referenced in policies. The attributes are in the form of:
| Attribute | Type | Description |
|---|---|---|
method |
str |
The MCP method being called |
component_type |
str |
The type of component being called (tools, prompts, resources) |
name |
str |
The name of the component being called (e.g. file_read) |
uri |
str |
The URI of the component being called (e.g. mcp:tools:file_read) |
arguments |
dict (optional) |
The arguments passed to the component being called |
Authentication
Agent Identification
Agents are identified through HTTP headers:
X-Agent-ID: claude
X-User-ID: user123
User-Agent: Claude
Authorization: Bearer api-key-here
Custom Principal Extraction
You can customize principal extraction by subclassing the middleware:
from eunomia_core import schemas
from eunomia_mcp import EunomiaMcpMiddleware
class CustomAuthMiddleware(EunomiaMcpMiddleware):
def _extract_principal(self) -> schemas.PrincipalCheck:
# Custom logic to extract principal from JWT, etc.
return schemas.PrincipalCheck(
uri="user:john.doe",
attributes={"role": "admin", "department": "engineering"}
)
Logging
Enable comprehensive audit logging:
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("eunomia_mcp")
# Authorization success
# INFO: Authorized request | MCP method: tools/call | MCP uri: mcp:tools:file_read | User-Agent: Claude
# Authorization violation
# WARNING: Authorization violation: Access denied for tools/call | MCP method: tools/call | MCP uri: mcp:tools:file_read | User-Agent: Claude
Examples
(Sample) Planetary Weather MCP
WhatsApp MCP to Authorized Contacts
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eunomia_mcp-0.3.7.tar.gz.
File metadata
- Download URL: eunomia_mcp-0.3.7.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53c2939984cd56d24a4871b37dc2ae0d2b1c35a36d54a40b7d96c101c7e6a273
|
|
| MD5 |
750408a9d5795a483e8630969fc51d26
|
|
| BLAKE2b-256 |
e495c3f0f249cd5584837e8d1e189c0ba2b0f8aeef218f3a89642b2d5b4e2b1c
|
File details
Details for the file eunomia_mcp-0.3.7-py3-none-any.whl.
File metadata
- Download URL: eunomia_mcp-0.3.7-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74af511fb5d057f56ee8b7a009c8a2de6b327358ae96cca2ddf6681bf6dddc9a
|
|
| MD5 |
794a56f310785724198edc515a68d35d
|
|
| BLAKE2b-256 |
3e93ac3a846f7f08f303baffdb542fed59abaffba13f841fd4636b0c22f550e5
|