mcp-azure

jspoelstra/mcp-azure

3.1

If you are the rightful owner of mcp-azure and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This document provides a comprehensive guide to setting up and deploying a Model Context Protocol (MCP) server using FastMCP, with a focus on Azure App Service deployment.

MCP Azure Sample Server

A minimal Model Context Protocol (MCP) server implemented with fastmcp using simple API key authentication. Includes instructions for local development and deployment to Azure App Service (Linux, Python) with optional GitHub integration.


Features

  • Lightweight FastMCP server (server.py)
  • API key based auth via environment variable API_KEY
  • Local dotenv support (python-dotenv)
  • Minimal pyproject.toml
  • Ready for manual Azure App Service deployment

Prerequisites

  • Python 3.10+
  • (Optional) uv or pip
  • Azure CLI (az) logged in: az login
  • (Optional) GitHub repo connected (this repo)

Quick Start (Local)

# Clone repository
 git clone https://github.com/<your-org-or-user>/mcp-azure.git
 cd mcp-azure

# Create virtual environment
 python3 -m venv .venv
 source .venv/bin/activate  # Windows: .venv\\Scripts\\activate

# Install dependencies
 pip install --upgrade pip
 pip install -e .

# Set API key (or use a .env file)
 export API_KEY="dev-secret-key"   # Windows PowerShell: $env:API_KEY="dev-secret-key"

# Run the server
 python server.py

Server will listen on https://0.0.0.0:8000 (self-signed or platform TLS). Adjust port via PORT or MCP framework options if needed.

Create a .env for convenience:

API_KEY=your-secret-api-key

Project Structure

.
├── server.py          # FastMCP server definition
├── pyproject.toml     # Project metadata & dependencies
└── README.md

Environment Variables

NameRequiredDescriptionDefault
API_KEYYesShared secret for authyour-secret-api-key (fallback)
PORTNoPort Azure sets automatically8000 (local only)

Deployment to Azure App Service (Python)

Below are manual CLI-based steps. For production, consider Infrastructure-as-Code (Bicep/Terraform) and GitHub Actions.

1. Set Variables

APP_NAME="mcp-azure-$RANDOM"   # Must be globally unique
RESOURCE_GROUP="mcp-azure-rg"
LOCATION="westus3"             # Pick a nearby region
PYTHON_VERSION="PYTHON|3.11"   # Azure runtime stack

2. Create Resource Group

az group create \
  --name "$RESOURCE_GROUP" \
  --location "$LOCATION"

3. Create App Service Plan (Linux)

az appservice plan create \
  --name "$APP_NAME-plan" \
  --resource-group "$RESOURCE_GROUP" \
  --sku B1 \
  --is-linux

4. Create Web App (Python)

az webapp create \
  --name "$APP_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --plan "$APP_NAME-plan" \
  --runtime "$PYTHON_VERSION" \
  --https-only true

5. Configure App Settings (API Key)

az webapp config appsettings set \
  --name "$APP_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --settings API_KEY="prod-secret-key"

6. Deploy Code (Zip Deploy)

From repo root (excluding virtualenv):

zip -r deploy.zip . -x '*.venv*' '*.git*' '__pycache__/*'

az webapp deploy \
  --resource-group "$RESOURCE_GROUP" \
  --name "$APP_NAME" \
  --src-path deploy.zip \
  --type zip

Azure will detect pyproject.toml and build using Oryx. If build fails, you can add a requirements.txt generated via:

pip freeze > requirements.txt

(Alternative) Deploy Using Makefile

The repository includes a Makefile that wraps the manual commands.

Inspect effective variables:

make variables

Deploy end-to-end (create group, plan, web app, configure, zip, deploy):

make deploy APP_NAME=my-unique-mcp API_KEY=my-secret-key

Common targets:

make install         # Create venv & install deps
make run             # Run locally with API_KEY
make package         # Build deploy.zip
make deploy          # Package and zip deploy (idempotent)
make logs            # Tail app logs
make ssh             # Open remote connection (then ssh -p 4321 localhost)
make destroy CONFIRM=yes  # Delete resource group (irreversible)

Override defaults inline:

make deploy APP_NAME=mcp-azure-123 RESOURCE_GROUP=mcp-azure-rg LOCATION=westus3 API_KEY=prod-secret

7. Verify Deployment

az webapp show -g "$RESOURCE_GROUP" -n "$APP_NAME" --query "defaultHostName" -o tsv

Visit: https://<hostname>/ (adjust to actual endpoint your FastMCP exposes if different).

8. Enable SSH / Remote Debug (Optional)

az webapp remote-connection create \
  --resource-group "$RESOURCE_GROUP" \
  --name "$APP_NAME" \
  --port 4321
# Then in another terminal:
ssh -p 4321 localhost

9. (Optional) Enable Logging

az webapp log config \
  --name "$APP_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --application-logging filesystem \
  --level information

az webapp log tail \
  --name "$APP_NAME" \
  --resource-group "$RESOURCE_GROUP"

GitHub Deployment Options

Option A: Manual Zip (above)

Option B: GitHub Action (Basic)

Create .github/workflows/deploy.yml (example skeleton):

name: Deploy MCP Server
on:
  push:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - name: Install deps
        run: |
          pip install --upgrade pip
          pip install -e .
      - name: Archive
        run: zip -r deploy.zip . -x '*.git*' '__pycache__/*'
      - name: Deploy to Azure
        uses: azure/webapps-deploy@v3
        with:
          app-name: ${{ secrets.AZURE_WEBAPP_NAME }}
          publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
          package: deploy.zip

Set secrets in GitHub repo settings:

  • AZURE_WEBAPP_NAME
  • AZURE_PUBLISH_PROFILE (download from Azure Portal Web App -> Get publish profile)

Option C: Continuous Deployment via GitHub Integration

az webapp deployment source config \
  --name "$APP_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --repo-url https://github.com/<your-org-or-user>/mcp-azure \
  --branch main \
  --manual-integration

Security Notes

  • Rotate API_KEY periodically; use Azure Key Vault for secrets at scale
  • Enforce HTTPS (already enabled)
  • Avoid committing real secrets (.env is ignored—create a .gitignore entry if needed)
  • Consider adding rate limiting / auth middleware for production use

Cleanup

az group delete --name "$RESOURCE_GROUP" --yes --no-wait

(Be sure you really want to delete all resources.)


Next Steps

  • Add tests for tools
  • Add health endpoint
  • Introduce structured logging (e.g., structlog)
  • Optional: Move to Azure Container Apps for more flexibility

License

MIT


Disclaimer

Sample project for demonstration purposes. Harden before production.