An MCP server exposes token_verifier. That hook is the auth boundary. A missing or rejected Authdog bearer never reaches a tool.
Getting started, including the runnable sample, is MCP agents. Connect an MCP client is how a client obtains a token. This page is the check after the client presents one.
This is your MCP server. Authdog's management MCP is a different host.
The verifier
verify_token calls fetch_user_data, the same userinfo check as require_auth. It returns an MCP AccessToken only when the payload is authenticated and has a subject. None refuses the bearer.
return AccessToken(
token=token,
client_id=subject,
scopes=["agent:invoke"],
subject=subject,
)subject_of reads id, then sub. Pass the verifier on MCPServer:
server = MCPServer(
name="authdog-mcp",
token_verifier=AuthdogTokenVerifier(payload),
auth=AuthSettings(
issuer_url=issuer,
resource_server_url=resource_url,
required_scopes=["agent:invoke"],
validate_token_resource=False,
),
)validate_token_resource=False because this verifier checks the token by userinfo. It does not require an aud claim equal to the MCP resource URL. Set the audience on the Authdog client when you need that binding. The sample does not add a second JWT parser.
PK_AUTHDOG selects the identity host. The server never sees the client secret.
What you should see
POST /mcp with no bearer returns 401. The initialize method does not run as an authenticated session. Repeat with a bearer userinfo accepts, then call whoami. The text is the Authdog subject.
The tool reads that subject from get_access_token(), which is the context the verifier filled in. It does not parse the header again.
Related
| Read | To learn how to |
|---|---|
| MCP agents | Run the sample |
| API keys and M2M for MCP | Choose the token the client presents |
| Authorizing tool calls for MCP | Allow a tool after the verifier returns |
| Build an MCP server | Add the runtime guard beside this verifier |