evalstate's picture
evalstate HF Staff
Add FastMCP Hugging Face OAuth provider test Space
ffe6e12 verified
Raw
History Blame Contribute Delete
1.78 kB
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",
)