mcp-auth-guard


Namemcp-auth-guard JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryIntuitive authorization middleware for MCP tools with type-safe policies
upload_time2025-07-20 22:04:42
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseNone
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"
}
        
Elapsed time: 1.19852s