Skip to content

Commit 3920bf4

Browse files
committed
auth: add optional subject field to AccessToken (fixes #1038)
Adds a `subject` field to the AccessToken pydantic model to hold the "sub" claim from JWT tokens. This allows token verifiers to include the user ID in the access token, which can then be retrieved via `get_access_token().subject` in request handlers. The field is optional (str | None) to maintain backward compatibility.
1 parent 3d7b311 commit 3920bf4

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

src/mcp/server/auth/provider.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class AccessToken(BaseModel):
4040
scopes: list[str]
4141
expires_at: int | None = None
4242
resource: str | None = None # RFC 8707 resource indicator
43+
subject: str | None = None # Subject (user ID, "sub" claim)
4344

4445

4546
RegistrationErrorCode = Literal[

tests/server/auth/test_provider.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,27 @@ def test_construct_redirect_uri_encoded_values():
7777

7878
# urlencode uses + for spaces by default
7979
assert "state=test+state+with+spaces" in result
80+
81+
82+
def test_access_token_subject_field():
83+
"""Test AccessToken supports optional subject (user ID) claim."""
84+
from mcp.server.auth.provider import AccessToken
85+
86+
token = AccessToken(
87+
token="token123",
88+
client_id="client1",
89+
scopes=["read", "write"],
90+
subject="user_456"
91+
)
92+
assert token.subject == "user_456"
93+
assert token.token == "token123"
94+
assert token.client_id == "client1"
95+
assert token.scopes == ["read", "write"]
96+
97+
# subject is optional
98+
token2 = AccessToken(
99+
token="token2",
100+
client_id="client2",
101+
scopes=["read"]
102+
)
103+
assert token2.subject is None

0 commit comments

Comments
 (0)