Skip to main content
Glama
app.py3.17 kB
# This file serves as the main entry point for the Render web service, # integrating FastMCP with an ASGI server (Uvicorn) and adding a security layer. import os import uvicorn import asyncio # Import mcp and initialization function from your logic file from mcp_server import mcp, initialize_db_pool from mcp.server.http import StreamableHttpTransport from fastapi import FastAPI, HTTPException, Request, Depends from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials # --- Security Dependency --- # Sets up the Bearer Token authentication schema security = HTTPBearer() def check_auth(credentials: HTTPAuthorizationCredentials = Depends(security)): """ Checks the Authorization: Bearer <TOKEN> header against the secret key (MCP_API_KEY) stored in the Render environment variables. """ expected_key = os.getenv("MCP_API_KEY") # Critical Check: Ensure the secret key is configured on the server if not expected_key: print("SECURITY ERROR: MCP_API_KEY is not set in environment variables!") raise HTTPException( status_code=500, detail="Server Misconfiguration: Authentication key missing.", ) # Validate the token sent by the client if credentials.credentials != expected_key: raise HTTPException( status_code=401, detail="Unauthorized access. Invalid MCP_API_KEY.", headers={"WWW-Authenticate": "Bearer"}, ) return True # --- Setup and Run --- async def start_server(): """Initializes the database pool and starts the Streamable HTTP Transport.""" # 1. Initialize the Database (connection pool) # This must be done before the server starts accepting connections await initialize_db_pool() # Render sets the PORT environment variable automatically. port = int(os.getenv("PORT", 8080)) # 2. Configure the Streamable HTTP Transport # This handles the MCP JSON-RPC protocol messages over HTTP. transport = StreamableHttpTransport( server=mcp, host="0.0.0.0", port=port, # Allow connections from any origin (required for a public web client like yours) cors_allow_origins=['*'], cors_allow_headers=['*', 'Authorization', 'Mcp-Session-Id'] ) # 3. Get the core ASGI application object app = transport.get_app() # 4. Add the security layer to the main MCP endpoints # All requests to /mcp MUST now include the correct Authorization header. @app.post("/mcp", dependencies=[Depends(check_auth)]) @app.get("/mcp", dependencies=[Depends(check_auth)]) async def protected_mcp_endpoint(request: Request): # Once authenticated, pass the request to the core MCP logic return await transport.handle_request(request) print(f"INFO: Starting secured Render-Postgres-Assistant on port {port}...") # 5. Start the Uvicorn server config = uvicorn.Config(app, host="0.0.0.0", port=port) server = uvicorn.Server(config) await server.serve() if __name__ == '__main__': # Start the async runtime and the server asyncio.run(start_server())

Latest Blog Posts

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/SheshuGit/MCP_Postgres'

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