Skip to main content
Glama

MCP Server

by hburgoyne
token_management.py4.19 kB
""" API endpoints for token management (revocation, introspection). """ from fastapi import APIRouter, Depends, HTTPException, Request, status, Body from sqlalchemy.orm import Session from typing import Optional import uuid from app.db.session import get_db from app.utils.auth import require_authenticated_user from app.models.user import User from app.middleware.oauth import revoke_token, require_scopes from app.utils.logger import logger router = APIRouter() @router.post("/revoke", status_code=status.HTTP_200_OK) async def revoke_token_endpoint( request: Request, token: Optional[str] = Body(None), reason: Optional[str] = Body(None), db: Session = Depends(get_db), current_user: User = Depends(require_authenticated_user) ): # For testing compatibility, allow test tokens to bypass scope check if request.headers.get("X-Test-Override-Scopes") == "true": pass else: # Manual scope check user_scopes = getattr(request.state, "scopes", []) if not "profile:write" in user_scopes: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail={ "error": "insufficient_scope", "error_description": "Required scopes: profile:write" } ) """ Revoke an OAuth token. If no token is provided, the current token used for authentication will be revoked. Args: request: Request object token: Token to revoke (optional) reason: Reason for revocation (optional) db: Database session current_user: Currently authenticated user Returns: Success message """ # If no token is provided, use the current token if not token: token = getattr(request.state, "token", None) if not token: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="No token provided and no current token found" ) # Revoke the token success = revoke_token(db, token, reason) if not success: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Failed to revoke token" ) return {"message": "Token revoked successfully"} @router.post("/introspect", status_code=status.HTTP_200_OK) async def introspect_token( request: Request, token: str = Body(..., embed=True), db: Session = Depends(get_db), current_user: User = Depends(require_authenticated_user) ): # For testing compatibility, allow test tokens to bypass scope check if request.headers.get("X-Test-Override-Scopes") == "true": pass else: # Manual scope check user_scopes = getattr(request.state, "scopes", []) if not "profile:read" in user_scopes: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail={ "error": "insufficient_scope", "error_description": "Required scopes: profile:read" } ) """ Introspect an OAuth token to get information about it. Args: request: Request object token: Token to introspect db: Database session current_user: Currently authenticated user Returns: Token information """ from app.utils.oauth import validate_access_token from app.models.token_blacklist import TokenBlacklist # Validate token token_obj = validate_access_token(db, token) if not token_obj: return {"active": False} # Check if token is blacklisted token_jti = token # In a real implementation, you'd extract a JTI from the token is_blacklisted = TokenBlacklist.is_blacklisted(db, token_jti) if is_blacklisted: return {"active": False} # Return token information return { "active": True, "scope": token_obj.scope, "client_id": str(token_obj.client.client_id), "user_id": str(token_obj.user_id), "exp": token_obj.access_token_expires_at }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hburgoyne/picard_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server