Name | mcp-auth-guard JSON |
Version |
1.0.0
JSON |
| download |
home_page | None |
Summary | Intuitive authorization middleware for MCP tools with type-safe policies |
upload_time | 2025-07-20 22:04:42 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | None |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# ๐ก๏ธ MCP Auth Guard
**Intuitive authorization middleware for MCP tools with type-safe policies**
A modern, developer-friendly authorization system designed specifically for [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers. Get fine-grained access control with simple YAML policies and seamless [FastMCP](https://gofastmcp.com/) integration.
## โจ Key Features
- ๐ **Multiple Auth Methods**: JWT, API keys, header-based, or no auth
- ๐ **Intuitive YAML Policies**: Easy-to-read, semantic policy definitions
- ๐ฏ **Fine-grained Control**: Role-based, pattern-based, and conditional access
- โก **Zero Latency**: In-process authorization with no external dependencies
- ๐ **Comprehensive Auditing**: Detailed logging for security monitoring
- ๐ ๏ธ **Type-safe APIs**: Fluent policy builders with full type safety
- ๐ **Developer-first**: Simple integration, great debugging experience
## User Flow
```mermaid
graph TD
User["User/Client"]
Request["MCP Request"]
subgraph "MCP Server"
AuthMiddleware["AuthGuard Middleware"]
MCPTools["MCP Tools/Resources/Prompts"]
end
subgraph "Authentication Phase"
Auth["Identity Manager"]
AuthResult["Auth Context"]
end
subgraph "Authorization Phase"
Policy["Policy Engine"]
Decision["Access Decision"]
end
subgraph "Execution"
Allowed{"Authorized?"}
ToolExecution["Execute Tool/Resource/Prompt"]
Deny["Access Denied"]
Filter["Filter Components"]
end
Response["MCP Response"]
User --> Request
Request --> AuthMiddleware
AuthMiddleware --> Auth
Auth --> AuthResult
AuthResult --> Policy
Policy --> Decision
Decision --> Allowed
Allowed -->|Yes| ToolExecution
Allowed -->|No| Deny
Allowed -->|List Ops| Filter
ToolExecution --> MCPTools
MCPTools --> Response
Filter --> Response
Deny --> Response
Response --> User
```
## ๐ Quick Start
### Installation
```bash
pip install mcp-auth-guard
```
### Basic Usage
```python
from fastmcp import FastMCP
from mcp_auth_guard import create_api_key_middleware
import asyncio
# Create your MCP server
mcp = FastMCP("My Secure Server")
@mcp.tool()
def safe_tool(data: str) -> str:
"""A safe tool that users can access."""
return f"Safe processing: {data}"
@mcp.tool()
def sensitive_operation(data: str) -> str:
"""A sensitive tool that requires admin access."""
return f"Sensitive processing: {data}"
# Add Auth Guard middleware
auth_middleware = create_api_key_middleware(
policies="./policies.yaml",
api_key_roles={
"user-key-123": ["user"],
"admin-key-456": ["admin"]
}
)
mcp.add_middleware(auth_middleware)
# Run your server
asyncio.run(mcp.run(transport="http"))
```
### Simple Policy Configuration
Create `policies.yaml`:
```yaml
name: "my_service_policy"
default_effect: "deny"
rules:
- name: "admin_access"
effect: "allow"
agents:
roles: ["admin"]
tools:
patterns: ["*"] # All tools
actions: ["list", "call"]
- name: "user_limited_access"
effect: "allow"
agents:
roles: ["user"]
tools:
names: ["safe_tool", "read_only_tool"]
actions: ["list", "call"]
```
### Client Usage
Connect to your secured server:
```python
# User client - can access safe tools
import asyncio
from fastmcp import Client
client = Client({
"mcpServers": {
"my_service": {
"url": "http://localhost:8000/mcp",
"headers": {"X-API-Key": "user-key-123"}
}
}
})
async def main():
async with client:
# This works - user can access safe_tool
result = await client.call_tool("my_service", "safe_tool", {"data": "test"})
print(f"User result: {result}")
# This would fail - user cannot access sensitive_operation
# result = await client.call_tool("my_service", "sensitive_operation", {"data": "test"})
asyncio.run(main())
```
```python
# Admin client - can access all tools
admin_client = Client({
"mcpServers": {
"my_service": {
"url": "http://localhost:8000/mcp",
"headers": {"X-API-Key": "admin-key-456"}
}
}
})
async def admin_demo():
async with admin_client:
# Admin can access any tool
result = await admin_client.call_tool("my_service", "sensitive_operation", {"data": "admin"})
print(f"Admin result: {result}")
asyncio.run(admin_demo())
```
**[โ Learn to write policies](examples/POLICY_GUIDE.md)**
## ๐ Examples
### ๐ Securing Existing MCP Servers with Proxy
Add authorization to **any existing MCP server** without modifying it:
```python
from fastmcp import Client, FastMCP
from mcp_auth_guard import create_api_key_middleware
# 1. Connect to existing SQLite MCP Server
config = {
"mcpServers": {
"sqlite": {
"command": "uv",
"args": [
"--directory", "servers/src/sqlite",
"run", "mcp-server-sqlite",
"--db-path", "~/test.db"
]
}
}
}
client = Client(config)
# 2. Create proxy with authorization
proxy_server = FastMCP.as_proxy(client)
auth_middleware = create_api_key_middleware(
policies="./database_policies.yaml",
api_key_roles={
"read-only-key-123": ["reader"], # SELECT queries only
"admin-key-456": ["admin"], # Full database access
"analyst-key-789": ["analyst"] # Queries + views
}
)
proxy_server.add_middleware(auth_middleware)
# 3. Run authorized proxy
proxy_server.run(transport="http", port=4200)
```
**Role-based Database Access**:
- **`reader`** role: Can only execute SELECT queries and view table schemas
- **`analyst`** role: Can query data, create views, but cannot modify database structure
- **`admin`** role: Full database access including CREATE, DROP, INSERT, UPDATE operations
- **Security**: Automatically blocks dangerous SQL operations (DROP, DELETE, ALTER) for non-admin users
**Benefits**: โ
No server changes โ
Role-based DB access โ
SQL injection prevention โ
Audit logging
```mermaid
sequenceDiagram
participant User
participant ClientApp as Client/SDK
participant ProxyServer as FastMCP Proxy Server (with Auth)
participant Backend as Backend MCP Server
User->>ClientApp: Sends tool call request (with API key)
ClientApp->>ProxyServer: Forwards request (includes API key in header)
ProxyServer->>ProxyServer: Auth middleware checks API key, assigns roles
alt Authorized
ProxyServer->>Backend: Proxies tool call to backend MCP server
Backend-->>ProxyServer: Returns tool result
ProxyServer-->>ClientApp: Returns result
ClientApp-->>User: Shows result
else Not authorized
ProxyServer-->>ClientApp: Returns authorization error
ClientApp-->>User: Shows error
end
```
### ๐ Weather Service Example
Check out the [**Weather Service Example**](examples/weather_service/) - a complete working demo with **all transport types**:
### ๐ Weather Service Features
- **Multiple user roles** (admin, user, intern)
- **Conditional access** (time-based restrictions)
- **Safety policies** (blocking dangerous operations)
- **Transport support** (STDIO, HTTP, SSE)
- **Comprehensive audit logging**
### ๐งช Test with Real MCP Client
```bash
cd examples/weather_service
# Simple HTTP client examples
python weather_server.py # Start server (terminal 1)
python basic_client.py # Basic client (terminal 2)
python http_roles_demo.py # Role-based demo (terminal 2)
# Comprehensive testing with all transports
python test_client.py # Test all roles (STDIO)
python test_client.py admin # Test specific role
python test_client.py admin http https://weather.api.com/mcp # HTTP transport
# See examples/weather_service/ for complete demo
```
### ๐ฎ Interactive Demo
```bash
# Try the policy simulation
python test_client.py
```
## ๐ Authentication Methods
### JWT Authentication
```python
from mcp_auth_guard import create_jwt_middleware
middleware = create_jwt_middleware(
jwt_secret="your-secret-key",
policies="./policies.yaml",
required_claims=["sub", "role"]
)
```
### API Key Authentication
```python
from mcp_auth_guard import create_api_key_middleware
middleware = create_api_key_middleware(
policies="./policies.yaml",
api_key_roles={
"admin-key-123": ["admin"],
"user-key-456": ["user"],
"readonly-key-789": ["readonly"]
}
)
```
### Header-based Authentication
```python
from mcp_auth_guard import create_header_middleware
middleware = create_header_middleware(
policies="./policies.yaml",
header_mapping={
"x-user-id": "user_id",
"x-user-roles": "roles"
}
)
```
## ๐ Policy Language
### Agent Matching
```yaml
agents:
user_id: ["alice", "bob"] # Specific users
roles: ["admin", "developer"] # User roles
agent_id: ["claude", "gpt-4"] # Agent identifiers
patterns: ["admin_*", "*_service"] # Wildcard patterns
```
### Tool Matching
```yaml
tools:
names: ["get_weather", "send_email"] # Exact tool names
patterns: ["get_*", "*_admin"] # Wildcard patterns
namespaces: ["weather", "admin"] # Tool namespaces
tags: ["safe", "public"] # Tool tags
```
### Conditions
```yaml
conditions:
- field: "tool.args.time"
operator: "equals"
value: "night"
- field: "user.roles"
operator: "in"
value: ["admin", "moderator"]
- field: "tool.name"
operator: "regex"
value: "^admin_.*"
```
## ๐ ๏ธ Type-safe Policy Building
For programmatic policy creation:
```python
from mcp_auth_guard.policy import policy, rule
# Build policies with code
my_policy = (policy("secure_service")
.with_description("Security policy for my service")
.deny_by_default()
.add_rule(
rule("admin_access")
.for_roles("admin")
.for_tool_patterns("*")
.allow()
)
.add_rule(
rule("user_read_only")
.for_roles("user")
.for_tool_patterns("get_*", "list_*")
.when_equals("tool.args.readonly", True)
.allow()
)
.build())
```
## ๐ Policy Testing & Debugging
Built-in tools for testing your policies:
```python
# Test a policy
from mcp_auth_guard.policy import PolicyLoader, PolicyEngine
from mcp_auth_guard.schemas import AuthContext, ToolResource, ResourceContext
# Load and test
policy = PolicyLoader.load_from_file("policies.yaml")
engine = PolicyEngine([policy])
# Create test context
auth_ctx = AuthContext(user_id="alice", roles=["user"], authenticated=True)
resource_ctx = ResourceContext(
resource_type="tool",
resource=ToolResource(name="get_weather"),
action="call",
method="tools/call"
)
# Evaluate
decision = await engine.evaluate(auth_ctx, resource_ctx)
print(f"Allowed: {decision.allowed}, Reason: {decision.reason}")
```
## ๐ง Advanced Features
### Dynamic Policy Updates
```python
# Update policies at runtime
middleware.add_policy(new_policy)
middleware.remove_policy("old_policy_name")
middleware.reload_policies("./updated_policies/")
```
### Custom Conditions
```python
# Extend with custom condition evaluators
class TimeBasedCondition(PolicyCondition):
def evaluate(self, context):
current_hour = datetime.now().hour
return 9 <= current_hour <= 17 # Business hours only
```
### Performance Monitoring
```python
# Built-in performance metrics
decision = await engine.evaluate(auth_ctx, resource_ctx)
print(f"Evaluation took: {decision.evaluation_time_ms}ms")
print(f"Rules evaluated: {decision.evaluated_rules}")
```
## ๐ Documentation
- [**Getting Started Guide**](docs/getting-started.md)
- [**Policy Reference**](docs/policy-reference.md)
- [**Authentication Methods**](docs/authentication.md)
- [**API Reference**](docs/api-reference.md)
- [**Migration from Eunomia v1**](docs/migration.md)
## ๐ค Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
## ๐ License
Apache License 2.0. See [LICENSE](LICENSE) for details.
---
**Built with โค๏ธ for the MCP community**
Raw data
{
"_id": null,
"home_page": null,
"name": "mcp-auth-guard",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": null,
"author": null,
"author_email": "Sandipan Haldar <work@sandipanhaldar.com>",
"download_url": "https://files.pythonhosted.org/packages/ed/86/6a92f1029ec8114f25217bebcf1127518c55e2720af8772c12ddea801ec5/mcp_auth_guard-1.0.0.tar.gz",
"platform": null,
"description": "# \ud83d\udee1\ufe0f MCP Auth Guard\n\n**Intuitive authorization middleware for MCP tools with type-safe policies**\n\nA modern, developer-friendly authorization system designed specifically for [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers. Get fine-grained access control with simple YAML policies and seamless [FastMCP](https://gofastmcp.com/) integration.\n\n## \u2728 Key Features\n\n- \ud83d\udd10 **Multiple Auth Methods**: JWT, API keys, header-based, or no auth\n- \ud83d\udcdd **Intuitive YAML Policies**: Easy-to-read, semantic policy definitions \n- \ud83c\udfaf **Fine-grained Control**: Role-based, pattern-based, and conditional access\n- \u26a1 **Zero Latency**: In-process authorization with no external dependencies\n- \ud83d\udd0d **Comprehensive Auditing**: Detailed logging for security monitoring\n- \ud83d\udee0\ufe0f **Type-safe APIs**: Fluent policy builders with full type safety\n- \ud83d\ude80 **Developer-first**: Simple integration, great debugging experience\n\n## User Flow \n\n```mermaid\ngraph TD\n User[\"User/Client\"]\n Request[\"MCP Request\"]\n \n subgraph \"MCP Server\"\n AuthMiddleware[\"AuthGuard Middleware\"]\n MCPTools[\"MCP Tools/Resources/Prompts\"]\n end\n \n subgraph \"Authentication Phase\"\n Auth[\"Identity Manager\"]\n AuthResult[\"Auth Context\"]\n end\n \n subgraph \"Authorization Phase\"\n Policy[\"Policy Engine\"]\n Decision[\"Access Decision\"]\n end\n \n subgraph \"Execution\"\n Allowed{\"Authorized?\"}\n ToolExecution[\"Execute Tool/Resource/Prompt\"]\n Deny[\"Access Denied\"]\n Filter[\"Filter Components\"]\n end\n \n Response[\"MCP Response\"]\n \n User --> Request\n Request --> AuthMiddleware\n AuthMiddleware --> Auth\n Auth --> AuthResult\n AuthResult --> Policy\n Policy --> Decision\n Decision --> Allowed\n \n Allowed -->|Yes| ToolExecution\n Allowed -->|No| Deny\n Allowed -->|List Ops| Filter\n \n ToolExecution --> MCPTools\n MCPTools --> Response\n Filter --> Response\n Deny --> Response\n Response --> User\n```\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install mcp-auth-guard\n```\n\n### Basic Usage\n\n```python\nfrom fastmcp import FastMCP\nfrom mcp_auth_guard import create_api_key_middleware\nimport asyncio\n# Create your MCP server\nmcp = FastMCP(\"My Secure Server\")\n\n@mcp.tool()\ndef safe_tool(data: str) -> str:\n \"\"\"A safe tool that users can access.\"\"\"\n return f\"Safe processing: {data}\"\n\n@mcp.tool() \ndef sensitive_operation(data: str) -> str:\n \"\"\"A sensitive tool that requires admin access.\"\"\"\n return f\"Sensitive processing: {data}\"\n\n# Add Auth Guard middleware\nauth_middleware = create_api_key_middleware(\n policies=\"./policies.yaml\",\n api_key_roles={\n \"user-key-123\": [\"user\"],\n \"admin-key-456\": [\"admin\"]\n }\n)\nmcp.add_middleware(auth_middleware)\n\n# Run your server\nasyncio.run(mcp.run(transport=\"http\"))\n```\n\n### Simple Policy Configuration\n\nCreate `policies.yaml`:\n\n```yaml\nname: \"my_service_policy\"\ndefault_effect: \"deny\"\n\nrules:\n - name: \"admin_access\"\n effect: \"allow\"\n agents:\n roles: [\"admin\"]\n tools:\n patterns: [\"*\"] # All tools\n actions: [\"list\", \"call\"]\n\n - name: \"user_limited_access\"\n effect: \"allow\"\n agents:\n roles: [\"user\"]\n tools:\n names: [\"safe_tool\", \"read_only_tool\"]\n actions: [\"list\", \"call\"]\n```\n\n### Client Usage\n\nConnect to your secured server:\n\n\n```python\n# User client - can access safe tools\nimport asyncio\nfrom fastmcp import Client\n\nclient = Client({\n \"mcpServers\": {\n \"my_service\": {\n \"url\": \"http://localhost:8000/mcp\",\n \"headers\": {\"X-API-Key\": \"user-key-123\"}\n }\n }\n})\n\nasync def main():\n async with client:\n # This works - user can access safe_tool\n result = await client.call_tool(\"my_service\", \"safe_tool\", {\"data\": \"test\"})\n print(f\"User result: {result}\")\n \n # This would fail - user cannot access sensitive_operation\n # result = await client.call_tool(\"my_service\", \"sensitive_operation\", {\"data\": \"test\"})\n\nasyncio.run(main())\n```\n\n```python \n# Admin client - can access all tools\nadmin_client = Client({\n \"mcpServers\": {\n \"my_service\": {\n \"url\": \"http://localhost:8000/mcp\", \n \"headers\": {\"X-API-Key\": \"admin-key-456\"}\n }\n }\n})\n\nasync def admin_demo():\n async with admin_client:\n # Admin can access any tool\n result = await admin_client.call_tool(\"my_service\", \"sensitive_operation\", {\"data\": \"admin\"})\n print(f\"Admin result: {result}\")\n\nasyncio.run(admin_demo())\n```\n\n**[\u2192 Learn to write policies](examples/POLICY_GUIDE.md)**\n\n## \ud83d\udccb Examples\n\n### \ud83d\udd12 Securing Existing MCP Servers with Proxy\n\nAdd authorization to **any existing MCP server** without modifying it:\n\n```python\nfrom fastmcp import Client, FastMCP\nfrom mcp_auth_guard import create_api_key_middleware\n\n# 1. Connect to existing SQLite MCP Server\nconfig = {\n \"mcpServers\": {\n \"sqlite\": {\n \"command\": \"uv\",\n \"args\": [\n \"--directory\", \"servers/src/sqlite\",\n \"run\", \"mcp-server-sqlite\",\n \"--db-path\", \"~/test.db\"\n ]\n }\n }\n}\nclient = Client(config)\n\n# 2. Create proxy with authorization\nproxy_server = FastMCP.as_proxy(client)\nauth_middleware = create_api_key_middleware(\n policies=\"./database_policies.yaml\",\n api_key_roles={\n \"read-only-key-123\": [\"reader\"], # SELECT queries only\n \"admin-key-456\": [\"admin\"], # Full database access\n \"analyst-key-789\": [\"analyst\"] # Queries + views\n }\n)\nproxy_server.add_middleware(auth_middleware)\n\n# 3. Run authorized proxy\nproxy_server.run(transport=\"http\", port=4200)\n```\n\n**Role-based Database Access**:\n- **`reader`** role: Can only execute SELECT queries and view table schemas\n- **`analyst`** role: Can query data, create views, but cannot modify database structure \n- **`admin`** role: Full database access including CREATE, DROP, INSERT, UPDATE operations\n- **Security**: Automatically blocks dangerous SQL operations (DROP, DELETE, ALTER) for non-admin users\n\n**Benefits**: \u2705 No server changes \u2705 Role-based DB access \u2705 SQL injection prevention \u2705 Audit logging\n\n```mermaid \nsequenceDiagram\n participant User\n participant ClientApp as Client/SDK\n participant ProxyServer as FastMCP Proxy Server (with Auth)\n participant Backend as Backend MCP Server\n\n User->>ClientApp: Sends tool call request (with API key)\n ClientApp->>ProxyServer: Forwards request (includes API key in header)\n ProxyServer->>ProxyServer: Auth middleware checks API key, assigns roles\n alt Authorized\n ProxyServer->>Backend: Proxies tool call to backend MCP server\n Backend-->>ProxyServer: Returns tool result\n ProxyServer-->>ClientApp: Returns result\n ClientApp-->>User: Shows result\n else Not authorized\n ProxyServer-->>ClientApp: Returns authorization error\n ClientApp-->>User: Shows error\n end\n\n```\n\n### \ud83c\udf0d Weather Service Example\n\nCheck out the [**Weather Service Example**](examples/weather_service/) - a complete working demo with **all transport types**:\n\n### \ud83c\udf0d Weather Service Features\n- **Multiple user roles** (admin, user, intern) \n- **Conditional access** (time-based restrictions)\n- **Safety policies** (blocking dangerous operations)\n- **Transport support** (STDIO, HTTP, SSE)\n- **Comprehensive audit logging**\n\n### \ud83e\uddea Test with Real MCP Client\n\n```bash\ncd examples/weather_service\n\n# Simple HTTP client examples\npython weather_server.py # Start server (terminal 1)\npython basic_client.py # Basic client (terminal 2)\npython http_roles_demo.py # Role-based demo (terminal 2)\n\n# Comprehensive testing with all transports\npython test_client.py # Test all roles (STDIO)\npython test_client.py admin # Test specific role\npython test_client.py admin http https://weather.api.com/mcp # HTTP transport\n\n# See examples/weather_service/ for complete demo\n```\n\n### \ud83c\udfae Interactive Demo\n```bash\n# Try the policy simulation\npython test_client.py\n```\n\n## \ud83d\udd10 Authentication Methods\n\n### JWT Authentication\n\n```python\nfrom mcp_auth_guard import create_jwt_middleware\n\nmiddleware = create_jwt_middleware(\n jwt_secret=\"your-secret-key\",\n policies=\"./policies.yaml\",\n required_claims=[\"sub\", \"role\"]\n)\n```\n\n### API Key Authentication\n\n```python\nfrom mcp_auth_guard import create_api_key_middleware\n\nmiddleware = create_api_key_middleware(\n policies=\"./policies.yaml\",\n api_key_roles={\n \"admin-key-123\": [\"admin\"],\n \"user-key-456\": [\"user\"],\n \"readonly-key-789\": [\"readonly\"]\n }\n)\n```\n\n### Header-based Authentication\n\n```python\nfrom mcp_auth_guard import create_header_middleware\n\nmiddleware = create_header_middleware(\n policies=\"./policies.yaml\",\n header_mapping={\n \"x-user-id\": \"user_id\",\n \"x-user-roles\": \"roles\"\n }\n)\n```\n\n## \ud83d\udcdd Policy Language\n\n### Agent Matching\n\n```yaml\nagents:\n user_id: [\"alice\", \"bob\"] # Specific users\n roles: [\"admin\", \"developer\"] # User roles \n agent_id: [\"claude\", \"gpt-4\"] # Agent identifiers\n patterns: [\"admin_*\", \"*_service\"] # Wildcard patterns\n```\n\n### Tool Matching\n\n```yaml\ntools:\n names: [\"get_weather\", \"send_email\"] # Exact tool names\n patterns: [\"get_*\", \"*_admin\"] # Wildcard patterns\n namespaces: [\"weather\", \"admin\"] # Tool namespaces\n tags: [\"safe\", \"public\"] # Tool tags\n```\n\n### Conditions\n\n```yaml\nconditions:\n - field: \"tool.args.time\"\n operator: \"equals\"\n value: \"night\"\n \n - field: \"user.roles\"\n operator: \"in\"\n value: [\"admin\", \"moderator\"]\n \n - field: \"tool.name\"\n operator: \"regex\"\n value: \"^admin_.*\"\n```\n\n## \ud83d\udee0\ufe0f Type-safe Policy Building\n\nFor programmatic policy creation:\n\n```python\nfrom mcp_auth_guard.policy import policy, rule\n\n# Build policies with code\nmy_policy = (policy(\"secure_service\")\n .with_description(\"Security policy for my service\")\n .deny_by_default()\n .add_rule(\n rule(\"admin_access\")\n .for_roles(\"admin\")\n .for_tool_patterns(\"*\")\n .allow()\n )\n .add_rule(\n rule(\"user_read_only\")\n .for_roles(\"user\")\n .for_tool_patterns(\"get_*\", \"list_*\")\n .when_equals(\"tool.args.readonly\", True)\n .allow()\n )\n .build())\n```\n\n## \ud83d\udd0d Policy Testing & Debugging\n\nBuilt-in tools for testing your policies:\n\n```python\n# Test a policy\nfrom mcp_auth_guard.policy import PolicyLoader, PolicyEngine\nfrom mcp_auth_guard.schemas import AuthContext, ToolResource, ResourceContext\n\n# Load and test\npolicy = PolicyLoader.load_from_file(\"policies.yaml\")\nengine = PolicyEngine([policy])\n\n# Create test context\nauth_ctx = AuthContext(user_id=\"alice\", roles=[\"user\"], authenticated=True)\nresource_ctx = ResourceContext(\n resource_type=\"tool\",\n resource=ToolResource(name=\"get_weather\"),\n action=\"call\",\n method=\"tools/call\"\n)\n\n# Evaluate\ndecision = await engine.evaluate(auth_ctx, resource_ctx)\nprint(f\"Allowed: {decision.allowed}, Reason: {decision.reason}\")\n```\n\n## \ud83d\udd27 Advanced Features\n\n### Dynamic Policy Updates\n\n```python\n# Update policies at runtime\nmiddleware.add_policy(new_policy)\nmiddleware.remove_policy(\"old_policy_name\")\nmiddleware.reload_policies(\"./updated_policies/\")\n```\n\n### Custom Conditions\n\n```python\n# Extend with custom condition evaluators\nclass TimeBasedCondition(PolicyCondition):\n def evaluate(self, context):\n current_hour = datetime.now().hour\n return 9 <= current_hour <= 17 # Business hours only\n```\n\n### Performance Monitoring\n\n```python\n# Built-in performance metrics\ndecision = await engine.evaluate(auth_ctx, resource_ctx)\nprint(f\"Evaluation took: {decision.evaluation_time_ms}ms\")\nprint(f\"Rules evaluated: {decision.evaluated_rules}\")\n```\n\n## \ud83d\udcda Documentation\n\n- [**Getting Started Guide**](docs/getting-started.md)\n- [**Policy Reference**](docs/policy-reference.md) \n- [**Authentication Methods**](docs/authentication.md)\n- [**API Reference**](docs/api-reference.md)\n- [**Migration from Eunomia v1**](docs/migration.md)\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n## \ud83d\udcc4 License\n\nApache License 2.0. See [LICENSE](LICENSE) for details.\n\n---\n\n**Built with \u2764\ufe0f for the MCP community**\n",
"bugtrack_url": null,
"license": null,
"summary": "Intuitive authorization middleware for MCP tools with type-safe policies",
"version": "1.0.0",
"project_urls": null,
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e5cbd3eebaaf5a97d7bf70282a0cade7616503d68b4b06ab29f671c0ba510ad8",
"md5": "f17e2d91f88966212e6fde5a4d28e679",
"sha256": "23275b7932f5be275b614f4ac96a362e07cc99369e5756d6646801ebe1d2d41d"
},
"downloads": -1,
"filename": "mcp_auth_guard-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f17e2d91f88966212e6fde5a4d28e679",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 29196,
"upload_time": "2025-07-20T22:04:40",
"upload_time_iso_8601": "2025-07-20T22:04:40.777252Z",
"url": "https://files.pythonhosted.org/packages/e5/cb/d3eebaaf5a97d7bf70282a0cade7616503d68b4b06ab29f671c0ba510ad8/mcp_auth_guard-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ed866a92f1029ec8114f25217bebcf1127518c55e2720af8772c12ddea801ec5",
"md5": "0fbe0bb17722d1a867f6efa0e145169d",
"sha256": "1de5e03c6fbea0592951de684c1d106d2f8420878b4adb5712c9f913211476af"
},
"downloads": -1,
"filename": "mcp_auth_guard-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "0fbe0bb17722d1a867f6efa0e145169d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 108007,
"upload_time": "2025-07-20T22:04:42",
"upload_time_iso_8601": "2025-07-20T22:04:42.289607Z",
"url": "https://files.pythonhosted.org/packages/ed/86/6a92f1029ec8114f25217bebcf1127518c55e2720af8772c12ddea801ec5/mcp_auth_guard-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-20 22:04:42",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "mcp-auth-guard"
}