Concept
Start building your own MCP Servers. At the core of our approach is the Model Context Protocol. Develop MCP Servers that bridge the gap between Copilot agents and the systems, data, and workflows that matter most. This technology enables your agents to act securely, flexibly, and reliably - turning them into strategic assets for your business.
Ask AI about Concept
Powered by Claude Β· Grounded in docs
I know everything about Concept. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Atea MCP Concept
A scaffold repository for teams building their first Model Context Protocol (MCP) servers on Azure. Clone this repo, follow the setup steps, and have a production-ready MCP server deployed in your own Azure environment.
What Is This?
MCP servers expose tools that AI assistants (such as GitHub Copilot or Microsoft 365 Copilot) can invoke on behalf of users. This repository provides:
- A shared .NET class library with authentication, telemetry, and token exchange already wired up
- File templates for scaffolding new MCP servers (C# project, Dockerfile, Bicep, CI/CD workflow, Copilot custom connector)
- Copilot agent prompts that guide you through deployment setup and server creation step by step
- Reusable GitHub Actions workflows for building Docker images and deploying to Azure Container Apps
Architecture
Each MCP server runs as a containerised .NET 9 application on Azure Container Apps.
CI/CD and infrastructure:
GitHub Actions
βββ Build Docker image β push to Azure Container Registry
βββ Deploy Bicep β Azure Container App
βββ reads secrets from Azure Key Vault
βββ reports telemetry to Application Insights
βββ uses Managed Identity for Azure access
Runtime (inbound and outbound auth):
GitHub Copilot / Copilot Studio
β OAuth 2.0 (Entra ID)
β Bearer token in Authorization header
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββ
β Azure Container App (one per MCP server) β
β .NET 9 / ModelContextProtocol.AspNetCore β
β JWT Bearer + MCP WWW-Authenticate discovery β
β Tool β Service β
βββββββββββββββββββββββββββββββββββββββββββββββββ
β
β API Key ββorββ OBO bearer token ββorββ (no auth)
βΌ
Upstream API (Dynamics 365, Power BI, custom β¦)
Shared infrastructure (one per environment):
- Azure Container Registry β stores Docker images
- Container Apps Environment β hosts all MCP server containers
- Azure Key Vault β stores per-server secrets
- Log Analytics Workspace + Application Insights β observability
- Azure Storage Account β optional export target for large tool responses
- User-Assigned Managed Identity β grants containers access to Key Vault
Per server:
- Container App
- GitHub Actions workflow
- Bicep parameter file
- Copilot Custom Connector (
swagger.json)
Prerequisites
| Tool | Purpose | Install |
|---|---|---|
| .NET 9 SDK | Build and run C# projects locally | winget install Microsoft.DotNet.SDK.9 |
| Azure CLI | Provision Azure resources and manage roles | winget install Microsoft.AzureCLI |
| GitHub CLI | Configure Actions secrets and variables | winget install GitHub.cli |
| VS Code | Recommended editor β launch and task configs are included | winget install Microsoft.VisualStudioCode |
| A GitHub account | Host the repo and run Actions | β |
| An Azure subscription | Host all infrastructure | β |
| Entra ID Application Developer role (or higher) | Required to create app registrations and configure permissions | Contact your Azure AD administrator |
| Key Vault Secrets Officer role (or higher) | Required to write credentials to Key Vault | Contact your Azure AD administrator |
Step-by-Step Guide
1. Fork the repository
Fork this repository into your own GitHub organisation using the Fork button at the top of the page, then clone your fork locally:
git clone https://github.com/{your-org}/{your-repo}.git
cd {your-repo}
2. Run /setup-deployment in GitHub Copilot Chat
Open GitHub Copilot Chat in VS Code and run:
/setup-deployment
This guided prompt will:
- Collect your environment name, location, and subscription ID
- Deploy all shared Azure infrastructure (
Infrastructure/main.bicep) - Create a service principal and store its credentials as the
AZURE_CREDENTIALSGitHub secret - Set the
ACR_NAME_DEVandACR_NAME_PRODActions variables
See docs/setup-deployment.md for a detailed walkthrough.
3. Commit and push Infrastructure/dev.bicepparam
The setup prompt writes your environment values into this file. Commit it:
git add Infrastructure/dev.bicepparam
git commit -m "chore: configure deployment environment"
git push
4. Run /create-mcp-account to create the MCP app registration
/create-mcp-account
This guided prompt will:
- Create an app registration for the MCP server (or reuse an existing one)
- Expose an API scope for delegated access
- Create a client secret and store all credentials in Key Vault
See docs/manage-app-registrations.md for details.
Optional: If you are integrating the MCP server with Copilot or other clients that use APIM (Azure API Management) and require an agent or client app with delegated permissions, run /create-agent-account to create the agent app registration.
5. Run /new-mcp-server in GitHub Copilot Chat
/new-mcp-server
This guided prompt scaffolds all files for a new server β C# project, Dockerfile, appsettings.json, Bicep parameter file, GitHub Actions workflow, and Copilot custom connector.
See docs/new-mcp-server.md for a detailed walkthrough.
5. Run /new-mcp-server in GitHub Copilot Chat
/new-mcp-server
This guided prompt scaffolds all files for a new server β C# project, Dockerfile, appsettings.json, Bicep parameter file, GitHub Actions workflow, and Copilot custom connector.
See docs/new-mcp-server.md for a detailed walkthrough.
6. Implement the service and tool
Fill in the generated service and tool classes with real logic:
MCPServers/{ServerName}/Services/{ServerName}Service.csβ calls the upstream APIMCPServers/{ServerName}/Tools/{ServerName}Tool.csβ exposes methods to Copilot via[McpServerTool]
7. Fill in the TODOs in the bicepparam file
Open Infrastructure/containerApp-{ServerName}.bicepparam and replace all TODO values.
The app registration credentials (Client ID, Client Secret, Tenant ID) are stored in Key Vault by /create-mcp-account and will be referenced automatically by the bicepparam file β you should not paste them directly:
| TODO | Replace with |
|---|---|
TODO-container-apps-environment-name | Your EnvironmentName from step 2 |
TODO-resource-group-name | rg-{EnvironmentName} |
TODO-upstream-api-base-url | Base URL of the upstream API (apikey and noauth only) |
TODO-obo-scope | OBO scope for the downstream API, must end in /.default (obo only) |
TODO-api-base-url | Base URL of the downstream API (obo only) |
TODO-public-url-after-first-deploy | Leave for now β fill in after the first deploy (step 10) |
8. No need to create Key Vault secrets manually
The /create-mcp-account prompt already created and stored the required secrets in Key Vault:
{ServerName}ClientIdβ Client ID of the MCP app registration{ServerName}ClientSecretβ Client secret of the MCP app registration{ServerName}TenantIdβ Tenant ID
See docs/manage-app-registrations.md β Key Vault Secret Names and Formats for the complete list.
9. Commit and push
git add .
git commit -m "feat: scaffold {ServerName} MCP server"
git push
GitHub Actions triggers automatically: builds the Docker image, pushes it to ACR, and deploys the Container App via Bicep.
10. Update the public URL and register the connector
After the first successful deployment, find the Container App's public URL in the Azure Portal (or via az containerapp show). Update EntraIdAuth__PublicUrl in the bicepparam file and push again. Then add Copilot/CustomConnectors/{ServerName}.swagger.json as a Copilot Custom Connector in Copilot Studio.
11. (Optional) Add a web reply URI for agent/client apps
If you created an agent app with /create-agent-account for Copilot or APIM integration and the client is a web application using OAuth 2.0 redirects, run:
/set-reply-uri
to add the client's redirect URI. See docs/manage-app-registrations.md β Step 3: Set Reply URI.
Repository Structure
.github/
βββ prompts/
β βββ setup-deployment.prompt.md Copilot agent β provision Azure + configure CI/CD
β βββ create-mcp-account.prompt.md Copilot agent β create MCP app registration
β βββ create-agent-account.prompt.md Copilot agent β create agent app registration
β βββ set-reply-uri.prompt.md Copilot agent β add OAuth reply URI
β βββ new-mcp-server.prompt.md Copilot agent β scaffold a new MCP server
βββ templates/mcp-server/ File templates used by /new-mcp-server
βββ workflows/
βββ docker-publish-template.yml Reusable: build and push Docker image
βββ docker-deploy-containerapp-template.yml Reusable: deploy Bicep to Azure
Copilot/
βββ CustomConnectors/ Generated swagger files for Copilot connectors
Infrastructure/
βββ main.bicep Shared infrastructure (ACR, KV, ACA env, β¦)
βββ containerApp.bicep Per-server Container App deployment
βββ dev.bicepparam Environment parameters (updated by /setup-deployment)
MCPServers/
βββ Shared/ Shared .NET library (auth, telemetry, token exchange)
docs/
βββ setup-deployment.md Detailed guide for /setup-deployment
βββ manage-app-registrations.md Detailed guide for /create-mcp-account, /create-agent-account, /set-reply-uri
βββ new-mcp-server.md Detailed guide for /new-mcp-server
Authentication Models
All MCP servers in this scaffold protect their own endpoint with Entra ID JWT bearer (inbound auth). The AuthType only controls how the service layer calls the downstream API.
obo (On-Behalf-Of) β the downstream API uses Entra ID (e.g. Dynamics 365, Power BI, Microsoft Graph). The MCP server performs an OAuth 2.0 On-Behalf-Of token exchange using MSAL so requests are made in the context of the signed-in user. Client credentials are stored in Key Vault.
apikey β the downstream API authenticates with a static key passed as a request header. The key is stored in Key Vault and injected as an environment variable at runtime.
noauth β the downstream API has no authentication (open or internal API). No auth header is sent to the upstream API.
