-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllm.txt
More file actions
95 lines (73 loc) · 3.03 KB
/
Copy pathllm.txt
File metadata and controls
95 lines (73 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Authplane Python Monorepo — LLM Quick Guide
Short, self-contained index for AI agents. Read `llm-full.txt` for everything else.
## Packages
- `authplane-sdk` (folder `authplane/`) — framework-agnostic OAuth 2.1 JWT
validation, RFC 8414 discovery, JWKS cache, RFC 7662 / 7009 / 8693 token
ops, RFC 9449 DPoP, RFC 9728 PRM, SSRF-hardened fetches.
- `authplane-mcp` (folder `authplane-mcp/`) — adapter for the official MCP
Python SDK.
- `authplane-fastmcp` (folder `authplane-fastmcp/`) — adapter for FastMCP.
Adapter packages depend on `authplane-sdk`, so installing one adapter brings
the core SDK along. Adapter packages export only their own glue
(`authplane_auth`, `AuthplaneAuthResult`, `AuthplaneTokenVerifier`, etc.);
core types come from `authplane` (and `authplane.oauth` for
`TokenExchangeOptions` / `TokenResponse`). Requires Python 3.11+.
## Most common task: protect an MCP server with one call
### FastMCP
```python
import asyncio
from authplane_fastmcp import authplane_auth
from fastmcp import FastMCP
from fastmcp.server.auth import require_scopes
async def main() -> None:
result = await authplane_auth(
issuer="https://auth.company.com",
base_url="https://mcp.company.com",
scopes=["tools/query"],
)
mcp = FastMCP("My Server", **result)
@mcp.tool(auth=require_scopes("tools/query"))
def query(sql: str) -> str: ...
try:
await mcp.run_async(transport="http", port=8080)
finally:
await result.aclose()
asyncio.run(main())
```
### Official MCP SDK
```python
import asyncio
from authplane_mcp import authplane_mcp_auth, require_scope
from mcp.server.fastmcp import FastMCP
async def main() -> None:
auth_result = await authplane_mcp_auth(
issuer="https://auth.company.com",
resource="https://mcp.company.com",
scopes=["tools/query"],
)
mcp = FastMCP("My Server", json_response=True, **auth_result)
@mcp.tool()
async def query(sql: str) -> str:
require_scope("tools/query")
...
try:
await mcp.run_streamable_http_async()
finally:
await auth_result.aclose()
asyncio.run(main())
```
`authplane_mcp_auth()` creates async resources (locks, HTTP client, background
JWKS/metadata caches) bound to the running loop. The adapter setup, server,
and `aclose()` must share one loop — call `mcp.run_streamable_http_async()`
(or `run_sse_async` / `run_stdio_async`) from inside `asyncio.run(main())`.
Wrapping only the setup in `asyncio.run(...)` and then calling the sync
`mcp.run()` strands those resources on a closed loop and the first request
will fail.
## Architectural rules (do not break)
- Protocol primitives belong in reusable modules under `authplane/oauth/*`.
- Stateful orchestration belongs in `AuthplaneClient`.
- Framework glue belongs inside the adapter package, not the core SDK.
## Where to look for more
- API surface, errors, DPoP, token operations, PRM, SSRF: package READMEs and
user guides in `authplane*/docs/user-guide.md`.
- Validation, demo flow, env vars, pitfalls: `llm-full.txt`.