Topic 5: Securing it
8 min read·22 Sept 2026
Bearer tokens and audience validation over HTTP
Over HTTP the server is reachable by anything on the network, so it acts as an OAuth 2.1 resource server: it never issues tokens, it only checks them. The check that matters most here is the audience (aud claim): the server URL a token was issued for. Without it, a token Nare's host obtained for some other MCP server (say, a calendar server that trusts the same identity provider) would also open her notes. This is the excerpt from Module 7 that does the check.
python
# Excerpt from notes_assistant/auth.py, lines 35 to 55, dedented (method of JWTTokenVerifier)
async def verify_token(self, token: str) -> AccessToken | None:
try:
claims = jwt.decode(
token,
self.key,
algorithms=self.algorithms,
audience=self.audience,
issuer=self.issuer,
options={"require": ["exp", "iss", "aud", "sub"]},
)
except jwt.InvalidTokenError as exc:
# Log the reason, never the token itself.
logger.warning("rejected token: %s", type(exc).__name__)
return None
return AccessToken(
token=token,
client_id=str(claims.get("client_id", claims["sub"])),
scopes=str(claims.get("scope", "")).split(),
expires_at=int(claims["exp"]),
resource=self.audience,
)Code explained