Metadata-Version: 2.4
Name: authplane-mcp
Version: 0.1.0
Summary: Authplane JWT validation adapter for the official MCP Python SDK
Project-URL: Homepage, https://github.com/AuthPlane/python-sdk/tree/main/authplane-mcp
Project-URL: Issues, https://github.com/AuthPlane/python-sdk/issues
Author: Authplane Team
License-Expression: Apache-2.0
Keywords: adapter,authplane,jwt,mcp,oauth
Requires-Python: >=3.11
Requires-Dist: authplane-sdk==0.1.0
Requires-Dist: mcp<1.28.0,>=1.23.0
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: coverage>=7; extra == 'dev'
Requires-Dist: cryptography>=42; extra == 'dev'
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Description-Content-Type: text/markdown

# authplane-mcp

[![PyPI](https://img.shields.io/pypi/v/authplane-mcp?style=flat-square&label=authplane-mcp)](https://pypi.org/project/authplane-mcp/)
[![License](https://img.shields.io/badge/License-Apache_2.0-blue?style=flat-square)](https://opensource.org/licenses/Apache-2.0)

Authplane JWT validation for servers built on the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).

## Install

```bash
pip install authplane-mcp
```

## Compatibility

Supported `mcp` range: **`>=1.23.0, <1.28.0`**. MCP 1.28 renamed the elicitation field from `elicitationId` (camelCase) to `elicitation_id` (snake_case), which breaks this adapter's current wire handling. If your project needs MCP 1.28+, please open an issue — the adapter update is straightforward, we just haven't cut it yet.

## Quickstart

```python
import asyncio
from authplane_mcp import authplane_mcp_auth
from mcp.server.fastmcp import FastMCP

auth_result = asyncio.run(
    authplane_mcp_auth(
        issuer="https://auth.company.com",
        resource="https://mcp.company.com",
        scopes=["tools/query", "tools/write"],
    )
)

mcp = FastMCP("My MCP Server", json_response=True, **auth_result)

@mcp.tool()
async def query_database(query: str) -> str:
    return f"Result for: {query}"

mcp.run(transport="streamable-http")
```

`mcp.run()` starts its own event loop, so the auth setup runs synchronously via `asyncio.run(...)` first. `auth_result` holds background JWKS and metadata refresh tasks — call `await auth_result.aclose()` during server shutdown.

## Documentation

PRM behavior, dev mode, revocation checking, manual setup, the full `authplane_mcp_auth` / `AuthplaneTokenVerifier` API, and error handling: **[User Guide](docs/user-guide.md)**.
