Eliminate the "47 Front Doors" Problem - A three-agent AI system that provides a single, intelligent entry point for university student support.
The Universal Front Door Support Agent is a three-agent AI system that provides a single, intelligent entry point for all university student support requests. Instead of navigating multiple disconnected support channels, students interact with one interface that:
- π― Detects intent from natural language queries
- π Routes requests to the correct department
- π« Creates tickets automatically in ServiceNow
- π Retrieves knowledge articles for self-service
- π€ Escalates to humans for policy-related requests
- π€ Voice interaction via Azure OpenAI GPT-4o Realtime API with WebRTC β speak naturally with the same AI pipeline
- π± Phone support via Azure Communication Services β callers dial a real number and interact with the same AI pipeline
- πΊ Live demo dashboard β audience sees real-time phone call transcripts on LivePage
π― Target Impact: Increase first-contact resolution from 40% to 65%
Build this entire system in 8 hours using GitHub Codespaces! This repository includes a complete boot camp curriculum with 8 progressive labs. All labs run in GitHub Codespaces - no local installation required.
| π Lab | π Title | β±οΈ Duration | π¨ What You'll Build |
|---|---|---|---|
| 00 | π Environment Setup | 30 min | Launch GitHub Codespaces, configure CORS, test the chat interface |
| 01 | π€ Understanding AI Agents | 90 min | Learn multi-agent vs monolithic architectures, build an intent classifier with >90% accuracy |
| 02 | π Azure MCP Setup | 30 min | Configure Model Context Protocol for Azure OpenAI and AI Search integration |
| 03 | π Spec-Driven Development | 45 min | Write feature specs and AI constitution before generating code with Claude/Copilot |
| 04 | π Build RAG Pipeline | 2 hrs | Implement hybrid search (vector + keyword) with Azure AI Search and 54 KB articles |
| 05 | π Agent Orchestration | 2 hrs | Wire up QueryAgent β RouterAgent β ActionAgent pipeline with session management |
| 06 | π Deploy with azd | 90 min | Containerize with Docker, deploy to Azure Container Apps with azd up |
| 07 | π MCP Server | 60 min | (Stretch) Expose your agent as an MCP server for Claude Desktop integration |
βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ
β π Lab 00 β β π€ Lab 01 β β π Lab 02 β β π Lab 03 β
β Setup ββββββΆβ Agents ββββββΆβ MCP ββββββΆβ Specs β
β 30 min β β 90 min β β 30 min β β 45 min β
βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ
β π Lab 04 β β π Lab 05 β β π Lab 06 β β π Lab 07 β
β RAG ββββββΆβ Pipeline ββββββΆβ Deploy ββββββΆβ MCP β
β 2 hrs β β 2 hrs β β 90 min β β 60 min β
βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ
| π‘ Skill | Lab 00 | Lab 01 | Lab 02 | Lab 03 | Lab 04 | Lab 05 | Lab 06 | Lab 07 |
|---|---|---|---|---|---|---|---|---|
| π Python/FastAPI | β | β | β | β | ||||
| π€ Azure OpenAI | β | β | β | β | ||||
| π Azure AI Search | β | β | β | |||||
| π¬ Prompt Engineering | β | β | β | β | ||||
| π³ Docker/Containers | β | |||||||
| βοΈ Azure Deployment | β | |||||||
| π MCP Protocol | β | β |
Labs 00-03 and 06 can run entirely in mock mode without Azure credentials. Labs 04, 05, and 07 require live Azure OpenAI for their core learning objectives.
| π Requirement | Lab 00 | Lab 01 | Lab 02 | Lab 03 | Lab 04 | Lab 05 | Lab 06 | Lab 07 |
|---|---|---|---|---|---|---|---|---|
| β Mock Mode OK | β | β | β | β | β | |||
| π€ Azure OpenAI (GPT-4o) | Required | Required | Required | |||||
| π Azure AI Search | Required | Required | ||||||
| π€ Voice (browser) | Azure OpenAI Realtime deployment | Lab 05x extension | Mock-OK | |||||
| π± Phone (PSTN) | Azure Communication Services + Event Grid | Coach demo | Mock-OK |
π‘ Cost-Saving Tip: Run Labs 00-03 with
USE_MOCK_MODE=trueto validate your setup before provisioning Azure services. Switch to live Azure OpenAI starting in Lab 04 when you build the RAG pipeline.
π Coach Materials: coach-guide/ | π Participant Guide: docs/boot-camp/
- π Python 3.11+
- π¦ Node.js 18+
- π³ Docker (optional)
The easiest way to get started is using GitHub Codespaces:
# π§ Backend setup
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# β οΈ IMPORTANT: Configure CORS for Codespaces
# Edit backend/.env and update CORS_ORIGINS with your Codespaces URLs:
# CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","https://<your-codespace-name>-5173.app.github.dev"]
# π Start backend (bind to all interfaces for Codespaces)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# π¨ Frontend setup (new terminal)
cd frontend
npm install
cp .env.example .env
# β οΈ CRITICAL: Do NOT set VITE_API_BASE_URL in Codespaces!
# Leave it empty so the Vite dev server proxy handles API routing.
# Setting it to http://localhost:8000 will cause ERR_CONNECTION_REFUSED
# because the browser cannot reach localhost inside the container.
# VITE_API_BASE_URL= <-- must be empty or unset
npm run dev-
π Make port 8000 public for external access:
gh codespace ports visibility 8000:public -c $CODESPACE_NAME -
π Get your Codespaces URLs from the Ports tab in VS Code, or construct them:
- π¨ Frontend:
https://<codespace-name>-5173.app.github.dev - π§ Backend:
https://<codespace-name>-8000.app.github.dev - Your codespace name is in the environment variable
$CODESPACE_NAME
- π¨ Frontend:
-
βοΈ Update CORS configuration in backend/.env:
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","https://<your-codespace-name>-5173.app.github.dev"]
Note: The backend config uses
validation_aliasto mapCORS_ORIGINSfrom .env to theallowed_originssetting. -
π Restart the backend after updating CORS settings to clear the settings cache.
-
β οΈ Frontend.envβ Do NOT setVITE_API_BASE_URLtohttp://localhost:8000! In Codespaces, the browser runs outside the container and cannot reachlocalhost:8000. LeaveVITE_API_BASE_URLempty so that API calls use relative paths (/api/...) and are proxied by the Vite dev server to the backend.# β Correct (Codespaces) VITE_API_BASE_URL= # β Wrong (causes ERR_CONNECTION_REFUSED / 502 errors) # VITE_API_BASE_URL=http://localhost:8000
-
π IPv4/IPv6 proxy mismatch β The Vite proxy target in
vite.config.tsmust usehttp://127.0.0.1:8000(nothttp://localhost:8000). In some environments,localhostresolves to IPv6 (::1) while uvicorn binds to IPv4 (0.0.0.0), causing 500 errors from the proxy with an empty response body.
| π Service | π URL |
|---|---|
| π¨ Frontend | https://<codespace>-5173.app.github.dev |
| π§ Backend API | https://<codespace>-8000.app.github.dev |
| π API Docs | https://<codespace>-8000.app.github.dev/api/docs |
| π Health Check | https://<codespace>-8000.app.github.dev/api/health |
# π Clone repository
git clone https://github.com/msftsean/hiedcab_frontdoor_agent.git
cd hiedcab_frontdoor_agent
# π§ Backend setup
cd backend
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --reload --port 8000
# π¨ Frontend setup (new terminal)
cd frontend
npm install
cp .env.example .env
npm run dev| π Service | π URL |
|---|---|
| π¨ Frontend | http://localhost:5173 |
| π§ Backend API | http://localhost:8000 |
| π API Docs | http://localhost:8000/docs |
| π Health Check | http://localhost:8000/api/health |
docker-compose up --build| π Service | π URL |
|---|---|
| π¨ Frontend | http://localhost:3000 |
| π§ Backend | http://localhost:8000 |
The system supports three input modalitiesβtext chat, browser voice (WebRTC), and phone calls (ACS/PSTN)βall routing through the same three-agent pipeline.
The three-agent system processes each user query through a coordinated pipeline:
- π― QueryAgent - Classifies intent (financial aid, registration, housing, technical support, general)
- π RouterAgent - Searches Azure AI Search for relevant KB articles
- β‘ ActionAgent - Generates contextual responses and determines if a support ticket is needed
| π§ Service | π Purpose |
|---|---|
| π€ Azure OpenAI | Intent classification, response generation |
| π¦ Container Apps | Backend API hosting |
| π Static Web Apps | Frontend hosting (optional in backend-first lab deployment path) |
| πΎ Cosmos DB | Session and audit storage |
| π AI Search | Knowledge base search |
| π Key Vault | Secrets management |
Deploy to regions with GPT-4o availability:
| π Region | π€ GPT-4o | π€ GPT-4o-mini |
|---|---|---|
| πΊπΈ East US | β | β |
| πΊπΈ East US 2 | β | β |
| πΊπΈ West US 3 | β | β |
| π¬π§ UK South | β | β |
| πΈπͺ Sweden Central | β | β |
# π Login to Azure
azd auth login
# ποΈ Initialize and deploy
azd init
azd upazd auth logincan be blocked by Conditional Access (AADSTS53003) in hosted environments. Use service principal login for non-interactive deployments:
az login --service-principal \
-u <AZURE_CLIENT_ID> \
-p <AZURE_CLIENT_SECRET> \
--tenant <AZURE_TENANT_ID>
az account set --subscription <AZURE_SUBSCRIPTION_ID>
azd auth login \
--client-id <AZURE_CLIENT_ID> \
--client-secret <AZURE_CLIENT_SECRET> \
--tenant-id <AZURE_TENANT_ID> \
--no-prompt- If
azd upfails with provider registration errors, an admin must register providers at subscription scope:
az provider register -n Microsoft.App --subscription <AZURE_SUBSCRIPTION_ID> --wait
az provider register -n Microsoft.Web --subscription <AZURE_SUBSCRIPTION_ID> --wait- Cosmos DB regional capacity and subscription access vary by region. If deployment fails in one region, set Cosmos to an allowed region (for example
canadacentral) while keeping app hosting in your preferred region.
| π Scale | π₯ Users | π΅ Monthly Cost |
|---|---|---|
| π§ͺ Development | 1-10 | $50-100 |
| π Small Pilot | 100-500 | $160-305 |
| π Medium | 500-2,000 | $400-700 |
| π’ Production | 2,000-10,000 | $1,000-2,500 |
See Cost Estimation Guide for details.
| π§ Method | π Endpoint | π Description |
|---|---|---|
POST |
/api/chat |
π¬ Submit support query |
GET |
/api/health |
π Health check |
GET |
/api/session/{id} |
π Get session |
DELETE |
/api/session/{id} |
ποΈ End session |
π₯ Request:
{
"message": "I forgot my password",
"session_id": null
}π€ Response:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"ticket_id": "TKT-IT-20260121-0001",
"department": "IT",
"status": "created",
"message": "I've created a ticket for IT Support...",
"knowledge_articles": [
{
"title": "How to Reset Your Password",
"url": "https://kb.university.edu/password-reset",
"relevance_score": 0.94
}
],
"escalated": false,
"estimated_response_time": "2 hours"
}| Suite | Tests | Status |
|---|---|---|
| Backend (pytest) | 435/435 | β Passing |
| Frontend (vitest) | 8/8 | β Passing |
| Lab 01 β Understanding Agents | 7/7 | β EXEMPLARY |
| Lab 03 β Spec-Driven Dev | 8/8 | β EXEMPLARY |
| Lab 05 β Agent Orchestration | 3/3 | β Passing |
| Lab 07 β MCP Server | 8/8 | β EXEMPLARY |
Labs 02 and 06 require
az loginfor Azure-dependent tests.
cd backend
source .venv/bin/activate
pytest # π§ͺ Run all tests
pytest --cov=app --cov-report=html # π With coveragecd frontend
npm test # π§ͺ Unit tests
npm run test:e2e # π E2E tests| π Document | π Description |
|---|---|
| π Feature Spec | Detailed requirements |
| πΎ Data Model | Schema definitions |
| πΊοΈ Implementation Plan | Development roadmap |
| βοΈ Customization Guide | Hands-on customization lab |
| π¦ Sample Customizations | Ready-to-use examples |
| π° Cost Estimation | Detailed pricing |
47doors/
βββ π§ backend/ # FastAPI Python backend
β βββ app/
β β βββ agents/ # π€ QueryAgent, RouterAgent, ActionAgent
β β βββ api/ # π‘ REST endpoints
β β βββ models/ # π Pydantic schemas
β β βββ services/ # βοΈ Azure integrations
β βββ tests/
βββ π¨ frontend/ # React TypeScript frontend
β βββ src/
β β βββ components/
β β βββ services/
β βββ tests/
βββ π labs/ # Boot Camp curriculum (8 labs)
β βββ 00-setup/
β βββ 01-understanding-agents/
β βββ 02-azure-mcp-setup/
β βββ 03-spec-driven-development/
β βββ 04-build-rag-pipeline/
β βββ 05-agent-orchestration/
β βββ 06-deploy-with-azd/
β βββ 07-mcp-server/
βββ π¨βπ« coach-guide/ # Facilitation materials
βββ π¦ shared/ # Common resources (constitution, schemas)
βββ π docs/ # Documentation
β βββ architecture/ # ποΈ Diagrams
β βββ customization/
β βββ deployment/
β βββ boot camp/ # π Participant guides
β βββ specs/ # π Feature specifications
βββ βοΈ infra/ # Azure Bicep templates
βββ π³ docker-compose.yml
βββ π azure.yaml
- π΄ Fork the repository
- πΏ Create a feature branch (
git checkout -b feature/amazing-feature) - πΎ Commit your changes (
git commit -m 'Add amazing feature') - π€ Push to the branch (
git push origin feature/amazing-feature) - π Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
| π§ Component | π Required Version | β Tested Version |
|---|---|---|
| π Python | 3.11+ | 3.11.14 |
| β‘ FastAPI | 0.100+ | 0.109.0 |
| π¦ Node.js | 18+ | 22.x |
| βοΈ React | 18+ | 18.2.0 |
| π TypeScript | 5.0+ | 5.3.3 |
| π³ Docker | 20.10+ | 24.0.7 |
| βοΈ Azure CLI | 2.50+ | 2.56.0 |
| π azd | 1.5+ | 1.7.0 |
ποΈ Built with Azure AI for Higher Education
π Last Updated: 2026-03-01 | π Version: 1.1.0




