Add MCP server with Entra ID auth and update documentation for msdocs-fastapi-postgresql-sample-app#19
Open
yogitasrivastava wants to merge 3 commits intoAzure-Samples:mainfrom
Open
Conversation
- Add mcp_server.py with 4 MCP tools (list/get/create restaurants & reviews) - Mount MCP server at /mcp in app.py with lifespan support - Add mcp[cli] dependency to pyproject.toml - Set gunicorn worker lifespan to 'on' for MCP session manager - Add comprehensive auth guide (GUIDE_AUTH_MCP_SERVER.md)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces major enhancements to the FastAPI restaurant review application by integrating a Model Context Protocol (MCP) server, enabling Azure AI Foundry agent access via Microsoft Entra ID authentication, and updating the infrastructure to support these features. It also improves documentation with a comprehensive setup and deployment guide.
Key changes include:
Summary
Add a Model Context Protocol (MCP) server to the existing FastAPI restaurant reviews sample app, secure it with Microsoft Entra ID authentication (EasyAuth v2), and preauthorize Azure AI Foundry agent identities to call the MCP tools using managed identity (
ServiceIdentity) authentication via theclient_credentialsflow.Motivation
Azure AI Foundry agents need to consume MCP servers hosted on Azure App Service. The existing sample app needs to demonstrate how to secure an MCP endpoint for agent identity access to reduce the risk of agentic threats. This change provides a working, end-to-end example that developers can follow to:
ServiceIdentitytype principals, not standard app registrations)Changes
New Files
src/fastapi_app/mcp_server.py— MCP server with 4 tools (list_restaurants_mcp,get_details_mcp,create_review_mcp,create_restaurant_mcp) usingFastMCPwithstateless_http=TrueGUIDE_AUTH_MCP_SERVER.md— Comprehensive step-by-step guide covering app registration, EasyAuth configuration, PRM setup, Foundry agent preauthorization, verification, troubleshooting, and 22 test casesModified Files
src/pyproject.toml— Addedmcp[cli]to dependenciessrc/fastapi_app/app.py— Imported and mounted MCP server at/mcp, addedmcp_lifespancontext manager to FastAPI appsrc/my_uvicorn_worker.py— Changedlifespanfrom"auto"to"on"(required for MCP session manager to start under gunicorn)README.md— Updated title, description, and added sections for MCP tools, architecture diagram, local MCP verification, Entra ID auth setup steps, Foundry agent integration, and key learningsinfra/main.bicep,infra/resources.bicep— Infrastructure updates fromazd updeploymentTechnical Details
MCP Server
/mcp/mcpunder the existing FastAPI appstateless_http=Truefor compatibility with FastAPI mountmcp_lifespancontext manager ensures the MCP session manager starts/stops with the appasyncio.to_thread()to run synchronous SQLModel/SQLAlchemy DB queriesAuthentication Architecture
Azure AI Foundry Agent
│
│ client_credentials flow → token with MCP.Access role
▼
Azure App Service (EasyAuth ~2, Return401)
│
│ JWT validated: issuer, audience, allowedClientApplications
▼
FastAPI + gunicorn (lifespan: on)
│
│ /mcp/mcp → FastMCP (stateless_http)
▼
MCP Tools → PostgreSQL
Key Configuration
runtimeVersion~2(v1 doesn't enforce auth properly)unauthenticatedClientActionReturn401MCP.AccessallowedMemberTypes: ["Application"]WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPESapi://<client-id>/user_impersonationlifespan"on"(critical for MCP session manager)Key Learnings Documented
ServiceIdentityprincipals (Foundry agents) cannot be added topreAuthorizedApplications— use app role assignments +allowedClientApplicationsinsteadruntimeVersion: "~2"is required for EasyAuth to properly enforce authentication/.well-known/oauth-protected-resource) is served by EasyAuth and is exempt from authentication by designTest Coverage
22 test cases across 3 groups:
Verification
mslearnagent) successfully connects and enumerates all 4 MCP tools (mcp_list_toolsstatus:OK)ServiceIdentityauthentication