import os from fastmcp import FastMCP from fastmcp.server.auth.providers.huggingface import HuggingFaceProvider from fastmcp.utilities.auth import parse_scopes def scopes_from_space() -> list[str]: scopes = parse_scopes(os.environ.get("OAUTH_SCOPES")) or [] merged = list(dict.fromkeys(["openid", "profile", *scopes])) return merged base_url = f"https://{os.environ['SPACE_HOST']}" mcp = FastMCP( name="FastMCP Hugging Face OAuth Test", auth=HuggingFaceProvider( client_id=os.environ["OAUTH_CLIENT_ID"], client_secret=os.environ["OAUTH_CLIENT_SECRET"], base_url=base_url, jwt_signing_key=os.environ["JWT_SIGNING_KEY"], required_scopes=scopes_from_space(), ), ) @mcp.tool async def whoami() -> dict: """Return the authenticated Hugging Face user's token claims.""" from fastmcp.server.dependencies import get_access_token token = get_access_token() return { "client_id": token.client_id, "scopes": token.scopes, "claims": { "sub": token.claims.get("sub"), "preferred_username": token.claims.get("preferred_username"), "name": token.claims.get("name"), "email": token.claims.get("email"), "email_verified": token.claims.get("email_verified"), "profile": token.claims.get("profile"), "picture": token.claims.get("picture"), "organizations": token.claims.get("organizations"), }, } @mcp.tool async def echo(message: str) -> str: """Echo a message after OAuth succeeds.""" return message if __name__ == "__main__": mcp.run( transport="http", host="0.0.0.0", port=int(os.environ.get("PORT", "7860")), path="/mcp", )