Skip to content

Commit 73fdb56

Browse files
chore: reformat docs code blocks for current ruff
ruff's newer formatter changed how it renders code blocks embedded in Markdown; CI installs the latest ruff, so the format check fails on files this branch does not otherwise touch. Formatting-only, no content changes. Expected to become a no-op once the in-flight change that already carries this reformatting lands on main.
1 parent 245d31a commit 73fdb56

5 files changed

Lines changed: 52 additions & 29 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ from authplane_fastmcp import authplane_auth
2020
from fastmcp import FastMCP
2121
from fastmcp.server.auth import require_scopes
2222

23+
2324
async def main() -> None:
2425
result = await authplane_auth(
2526
issuer="https://auth.company.com",
@@ -37,6 +38,7 @@ async def main() -> None:
3738
finally:
3839
await result.aclose()
3940

41+
4042
asyncio.run(main())
4143
```
4244

authplane-fastmcp/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ async def main():
3232
)
3333

3434
@mcp.tool(auth=require_scopes("tools/query"))
35-
async def query_database(
36-
query: str, token: AccessToken = CurrentAccessToken()
37-
) -> str:
35+
async def query_database(query: str, token: AccessToken = CurrentAccessToken()) -> str:
3836
user_id = token.claims.get("sub")
3937
return f"Query: {query}, User: {user_id}"
4038

authplane-fastmcp/docs/user-guide.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import asyncio
3737
from fastmcp import FastMCP
3838
from authplane_fastmcp import authplane_auth
3939

40+
4041
async def main() -> None:
4142
result = await authplane_auth(
4243
issuer="https://auth.company.com",
@@ -55,6 +56,7 @@ async def main() -> None:
5556
finally:
5657
await result.aclose()
5758

59+
5860
asyncio.run(main())
5961
```
6062

@@ -98,11 +100,13 @@ Use FastMCP's built-in `require_scopes` decorator to enforce per-tool scope requ
98100
```python
99101
from fastmcp.server.auth import require_scopes
100102

103+
101104
@mcp.tool(auth=require_scopes("tools/query"))
102105
def query(sql: str) -> str:
103106
"""Requires the tools/query scope."""
104107
return f"Ran: {sql}" # replace with your real handler
105108

109+
106110
@mcp.tool(auth=require_scopes("tools/admin", "tools/delete"))
107111
def delete_all() -> str:
108112
"""Requires BOTH tools/admin AND tools/delete scopes."""
@@ -119,21 +123,22 @@ FastMCP enforces scopes **before** the handler runs by **filtering tools the cal
119123
from fastmcp.dependencies import CurrentAccessToken
120124
from fastmcp.server.auth import AccessToken
121125

126+
122127
@mcp.tool()
123128
async def my_tool(data: str, token: AccessToken = CurrentAccessToken()) -> str:
124129
# Standard JWT claims
125-
sub = token.claims.get("sub") # Subject (user ID)
126-
jti = token.claims.get("jti") # JWT ID
127-
iss = token.claims.get("iss") # Issuer
128-
aud = token.claims.get("aud") # Audience
129-
exp = token.claims.get("exp") # Expiration (Unix timestamp)
130-
nbf = token.claims.get("nbf") # Not before
131-
iat = token.claims.get("iat") # Issued at
130+
sub = token.claims.get("sub") # Subject (user ID)
131+
jti = token.claims.get("jti") # JWT ID
132+
iss = token.claims.get("iss") # Issuer
133+
aud = token.claims.get("aud") # Audience
134+
exp = token.claims.get("exp") # Expiration (Unix timestamp)
135+
nbf = token.claims.get("nbf") # Not before
136+
iat = token.claims.get("iat") # Issued at
132137

133138
# OAuth claims
134-
client_id = token.client_id # Client ID
135-
scopes = token.scopes # List of granted scopes
136-
expires_at = token.expires_at # Expiration (Unix timestamp)
139+
client_id = token.client_id # Client ID
140+
scopes = token.scopes # List of granted scopes
141+
expires_at = token.expires_at # Expiration (Unix timestamp)
137142

138143
# Custom claims
139144
tenant = token.claims.get("tenant_id")
@@ -149,6 +154,7 @@ The `claims` dict contains the **full JWT payload** including all standard and c
149154
```python
150155
from fastmcp.server.dependencies import get_access_token
151156

157+
152158
@mcp.tool()
153159
async def my_tool(data: str) -> str:
154160
token = get_access_token() # Returns None if unauthenticated
@@ -220,10 +226,12 @@ Implement your own revocation logic with an async callable:
220226
```python
221227
from authplane import VerifiedClaims
222228

229+
223230
async def check_blocklist(claims: VerifiedClaims, raw_token: str) -> bool:
224231
"""Return True to reject the token (it is revoked)."""
225232
return await redis_client.sismember("revoked_tokens", claims.jti)
226233

234+
227235
await authplane_auth(
228236
issuer="https://auth.company.com",
229237
base_url="https://mcp.company.com",
@@ -253,8 +261,8 @@ result = await authplane_auth(
253261
downstream = await result.client.exchange(
254262
TokenExchangeOptions(
255263
subject_token=inbound_token,
256-
scope="tools/add", # narrow to the minimum
257-
resources=("https://downstream.example",), # RFC 8707 audience binding
264+
scope="tools/add", # narrow to the minimum
265+
resources=("https://downstream.example",), # RFC 8707 audience binding
258266
)
259267
)
260268

@@ -287,6 +295,7 @@ from authplane import ConsentRequiredError
287295
from authplane.oauth import TokenExchangeOptions
288296
from mcp.shared.exceptions import UrlElicitationRequiredError
289297

298+
290299
@mcp.tool(auth=require_scopes("tools/call_downstream"))
291300
async def call_downstream(payload: str) -> str:
292301
try:
@@ -379,6 +388,7 @@ When `fetch_settings` is provided, `dev_mode` is ignored for both metadata and J
379388
```python
380389
import asyncio
381390

391+
382392
async def main() -> None:
383393
result = await authplane_auth(...)
384394
try:
@@ -387,6 +397,7 @@ async def main() -> None:
387397
finally:
388398
await result.aclose()
389399

400+
390401
asyncio.run(main())
391402
```
392403

authplane-mcp/docs/user-guide.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ Use the `require_scope()` helper at the top of tool handlers to enforce per-tool
101101
```python
102102
from authplane_mcp import require_scope
103103

104+
104105
@mcp.tool()
105106
async def query(sql: str) -> str:
106107
"""Requires the tools/query scope."""
107108
require_scope("tools/query")
108109
return f"Ran: {sql}" # replace with your real handler
109110

111+
110112
@mcp.tool()
111113
async def delete_all() -> str:
112114
"""Requires the tools/admin scope."""
@@ -127,14 +129,15 @@ Use the MCP SDK's `get_access_token()` to access the validated token in tool han
127129
```python
128130
from mcp.server.auth.middleware.auth_context import get_access_token
129131

132+
130133
@mcp.tool()
131134
async def my_tool(data: str) -> str:
132135
token = get_access_token()
133136
if token:
134-
client_id = token.client_id # Client ID
135-
scopes = token.scopes # List of granted scopes
136-
expires_at = token.expires_at # Expiration (Unix timestamp)
137-
resource = token.resource # Resource (audience) URL
137+
client_id = token.client_id # Client ID
138+
scopes = token.scopes # List of granted scopes
139+
expires_at = token.expires_at # Expiration (Unix timestamp)
140+
resource = token.resource # Resource (audience) URL
138141
return f"Processing {data}"
139142
```
140143

@@ -211,10 +214,12 @@ Implement your own revocation logic with an async callable:
211214
```python
212215
from authplane import VerifiedClaims
213216

217+
214218
async def check_blocklist(claims: VerifiedClaims, raw_token: str) -> bool:
215219
"""Return True to reject the token (it is revoked)."""
216220
return await redis_client.sismember("revoked_tokens", claims.jti)
217221

222+
218223
await authplane_mcp_auth(
219224
issuer="https://auth.company.com",
220225
resource="https://mcp.company.com",
@@ -244,8 +249,8 @@ result = await authplane_mcp_auth(
244249
downstream = await result.client.exchange(
245250
TokenExchangeOptions(
246251
subject_token=inbound_token,
247-
scope="tools/add", # narrow to the minimum
248-
resources=("https://downstream.example",), # RFC 8707 audience binding
252+
scope="tools/add", # narrow to the minimum
253+
resources=("https://downstream.example",), # RFC 8707 audience binding
249254
)
250255
)
251256

@@ -278,6 +283,7 @@ The adapter handles this for you. The `client` returned by `authplane_mcp_auth(.
278283
```python
279284
from authplane.oauth import TokenExchangeOptions
280285

286+
281287
@mcp.tool()
282288
async def call_downstream(user_token: str, payload: str) -> str:
283289
downstream = await result.client.exchange(
@@ -379,6 +385,7 @@ When `fetch_settings` is provided, `dev_mode` is ignored for both metadata and J
379385
```python
380386
import asyncio
381387

388+
382389
async def main() -> None:
383390
auth_result = await authplane_mcp_auth(...)
384391
try:
@@ -387,6 +394,7 @@ async def main() -> None:
387394
finally:
388395
await auth_result.aclose()
389396

397+
390398
asyncio.run(main())
391399
```
392400

authplane/docs/user-guide.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ res = client.resource(
137137
resource="https://api.example.com",
138138
scopes=["read"],
139139
inbound_dpop=InboundDPoPOptions(
140-
replay_store=InMemoryDPoPReplayStore(), # process-scoped by default
140+
replay_store=InMemoryDPoPReplayStore(), # process-scoped by default
141141
max_proof_age_seconds=300,
142142
clock_skew_seconds=30,
143143
allowed_proof_algorithms=("RS256", "ES256"),
144-
required=True, # reject bearer-only tokens
144+
required=True, # reject bearer-only tokens
145145
),
146146
)
147147
```
@@ -159,13 +159,16 @@ For each incoming request that may carry a DPoP-bound token, build a
159159
```python
160160
from dataclasses import dataclass
161161

162+
162163
@dataclass
163164
class IncomingRequest:
164165
"""Implements DPoPRequestContext."""
166+
165167
method: str
166168
url: str
167169
proof: str | None
168170

171+
169172
claims = await res.verify(
170173
token,
171174
dpop_request=IncomingRequest(
@@ -261,6 +264,7 @@ res = client.resource(
261264
```python
262265
from authplane import VerifiedClaims
263266

267+
264268
async def my_revocation_checker(claims: VerifiedClaims, raw_token: str) -> bool:
265269
return claims.jti in revoked_jtis
266270
```
@@ -415,12 +419,12 @@ For multi-instance or shared-state deployments, provide your own `DPoPNonceStore
415419
```python
416420
from authplane import DPoPKeyMaterial, DPoPNonceStore, DPoPProvider
417421

422+
418423
class MyNonceStore:
419-
def get(self, key: str) -> str:
420-
...
424+
def get(self, key: str) -> str: ...
425+
426+
def put(self, key: str, nonce: str) -> None: ...
421427

422-
def put(self, key: str, nonce: str) -> None:
423-
...
424428

425429
provider = DPoPProvider(
426430
DPoPKeyMaterial.from_pem(private_key_pem),
@@ -597,8 +601,8 @@ except AuthplaneError as e:
597601
Generate an RFC 9728 protected resource metadata document with:
598602

599603
```python
600-
prm = res.prm_response() # the document body (a dict)
601-
url = res.prm_url() # the well-known URL where clients can fetch it
604+
prm = res.prm_response() # the document body (a dict)
605+
url = res.prm_url() # the well-known URL where clients can fetch it
602606
```
603607

604608
Example output:

0 commit comments

Comments
 (0)