This hands-on lab guides you through setting up a complete development environment for building MCP servers with PostgreSQL integration. You'll configure all necessary tools, deploy Azure resources, and validate your setup before proceeding with implementation.
A proper development environment is crucial for successful MCP server development. This lab provides step-by-step instructions for setting up Docker, Azure services, development tools, and validating that everything works correctly together.
By the end of this lab, you'll have a fully functional development environment ready for building the Zava Retail MCP server.
By the end of this lab, you will be able to:
- Install and configure all required development tools
- Deploy Azure resources needed for the MCP server
- Set up Docker containers for PostgreSQL and the MCP server
- Validate your environment setup with test connections
- Troubleshoot common setup issues and configuration problems
- Understand the development workflow and file structure
Before starting, ensure you have:
- Basic command line usage (Windows Command Prompt/PowerShell)
- Understanding of environment variables
- Familiarity with Git version control
- Basic Docker concepts (containers, images, volumes)
- Operating System: Windows 10/11, macOS, or Linux
- RAM: Minimum 8GB (16GB recommended)
- Storage: At least 10GB free space
- Network: Internet connection for downloads and Azure deployment
- Azure Subscription: Free tier is sufficient
- GitHub Account: For repository access
- Docker Hub Account: (Optional) For custom image publishing
Docker provides the containerized environment for our development setup.
-
Download Docker Desktop:
# Visit https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe # Or use Windows Package Manager winget install Docker.DockerDesktop
-
Install and Configure:
- Run the installer as Administrator
- Enable WSL 2 integration when prompted
- Restart your computer when installation completes
-
Verify Installation:
docker --version docker-compose --version
-
Download and Install:
# Download from https://desktop.docker.com/mac/stable/Docker.dmg # Or use Homebrew brew install --cask docker
-
Start Docker Desktop:
- Launch Docker Desktop from Applications
- Complete the initial setup wizard
-
Verify Installation:
docker --version docker-compose --version
-
Install Docker Engine:
# Ubuntu/Debian curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER # Log out and back in for group changes to take effect
-
Install Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
The Azure CLI enables Azure resource deployment and management.
# Using Windows Package Manager
winget install Microsoft.AzureCLI
# Or download MSI from: https://aka.ms/installazurecliwindows# Using Homebrew
brew install azure-cli
# Or using installer
curl -L https://aka.ms/InstallAzureCli | bash# Ubuntu/Debian
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# RHEL/CentOS
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo dnf install azure-cli# Check installation
az version
# Login to Azure
az login
# Set default subscription (if you have multiple)
az account list --output table
az account set --subscription "Your-Subscription-Name"Git is required for cloning the repository and version control.
# Using Windows Package Manager
winget install Git.Git
# Or download from: https://git-scm.com/download/win# Git is usually pre-installed, but you can update via Homebrew
brew install git# Ubuntu/Debian
sudo apt update && sudo apt install git
# RHEL/CentOS
sudo dnf install gitVisual Studio Code provides the integrated development environment with MCP support.
# Windows
winget install Microsoft.VisualStudioCode
# macOS
brew install --cask visual-studio-code
# Linux (Ubuntu/Debian)
sudo snap install code --classicInstall these VS Code extensions:
# Install via command line
code --install-extension ms-python.python
code --install-extension ms-vscode.vscode-json
code --install-extension ms-azuretools.vscode-docker
code --install-extension ms-vscode.azure-accountOr install through VS Code:
- Open VS Code
- Go to Extensions (Ctrl+Shift+X)
- Install:
- Python (Microsoft)
- Docker (Microsoft)
- Azure Account (Microsoft)
- JSON (Microsoft)
Python 3.8+ is required for MCP server development.
# Using Windows Package Manager
winget install Python.Python.3.11
# Or download from: https://www.python.org/downloads/# Using Homebrew
brew install python@3.11# Ubuntu/Debian
sudo apt update && sudo apt install python3.11 python3.11-pip python3.11-venv
# RHEL/CentOS
sudo dnf install python3.11 python3.11-pippython --version # Should show Python 3.11.x
pip --version # Should show pip version# Clone the main repository
git clone https://github.com/microsoft/MCP-Server-and-PostgreSQL-Sample-Retail.git
# Navigate to the project directory
cd MCP-Server-and-PostgreSQL-Sample-Retail
# Verify repository structure
ls -la# Create virtual environment
python -m venv mcp-env
# Activate virtual environment
# Windows
mcp-env\Scripts\activate
# macOS/Linux
source mcp-env/bin/activate
# Upgrade pip
python -m pip install --upgrade pip# Install development dependencies
pip install -r requirements.lock.txt
# Verify key packages
pip list | grep fastmcp
pip list | grep asyncpg
pip list | grep azureOur MCP server requires these Azure resources:
| Resource | Purpose | Estimated Cost |
|---|---|---|
| Azure AI Foundry | AI model hosting and management | $10-50/month |
| OpenAI Deployment | Text embedding model (text-embedding-3-small) | $5-20/month |
| Application Insights | Monitoring and telemetry | $5-15/month |
| Resource Group | Resource organization | Free |
# Navigate to infrastructure directory
cd infra
# Windows - PowerShell
./deploy.ps1
# macOS/Linux - Bash
./deploy.shThe deployment script will:
- Create a unique resource group
- Deploy Azure AI Foundry resources
- Deploy the text-embedding-3-small model
- Configure Application Insights
- Create a service principal for authentication
- Generate
.envfile with configuration
If you prefer manual control or the automated script fails:
# Set variables
RESOURCE_GROUP="rg-zava-mcp-$(date +%s)"
LOCATION="westus2"
AI_PROJECT_NAME="zava-ai-project"
# Create resource group
az group create --name $RESOURCE_GROUP --location $LOCATION
# Deploy main template
az deployment group create \
--resource-group $RESOURCE_GROUP \
--template-file main.bicep \
--parameters location=$LOCATION \
--parameters resourcePrefix="zava-mcp"# Check resource group
az group show --name $RESOURCE_GROUP --output table
# List deployed resources
az resource list --resource-group $RESOURCE_GROUP --output table
# Test AI service
az cognitiveservices account show \
--name "your-ai-service-name" \
--resource-group $RESOURCE_GROUPAfter deployment, you should have a .env file. Verify it contains:
# .env file contents
PROJECT_ENDPOINT=https://your-project.cognitiveservices.azure.com/
AZURE_OPENAI_ENDPOINT=https://your-openai.openai.azure.com/
EMBEDDING_MODEL_DEPLOYMENT_NAME=text-embedding-3-small
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
AZURE_TENANT_ID=your-tenant-id
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=your-key;...
# Database configuration (for development)
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=zava
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-secure-passwordOur development environment uses Docker Compose:
# docker-compose.yml overview
version: '3.8'
services:
postgres:
image: pgvector/pgvector:pg17
environment:
POSTGRES_DB: zava
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password}
ports:
- "5432:5432"
volumes:
- ./data:/backup_data:ro
- ./docker-init:/docker-entrypoint-initdb.d:ro
mcp_server:
build: .
depends_on:
postgres:
condition: service_healthy
ports:
- "8000:8000"
env_file:
- .env# Ensure you're in the project root directory
cd /path/to/MCP-Server-and-PostgreSQL-Sample-Retail
# Start the services
docker-compose up -d
# Check service status
docker-compose ps
# View logs
docker-compose logs -f# Connect to PostgreSQL container
docker-compose exec postgres psql -U postgres -d zava
# Check database structure
\dt retail.*
# Verify sample data
SELECT COUNT(*) FROM retail.stores;
SELECT COUNT(*) FROM retail.products;
SELECT COUNT(*) FROM retail.orders;
# Exit PostgreSQL
\q# Check MCP server health
curl http://localhost:8000/health
# Test basic MCP endpoint
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-H "x-rls-user-id: 00000000-0000-0000-0000-000000000000" \
-d '{"method": "tools/list", "params": {}}'Create VS Code MCP configuration:
// .vscode/mcp.json
{
"servers": {
"zava-sales-analysis-headoffice": {
"url": "http://127.0.0.1:8000/mcp",
"type": "http",
"headers": {"x-rls-user-id": "00000000-0000-0000-0000-000000000000"}
},
"zava-sales-analysis-seattle": {
"url": "http://127.0.0.1:8000/mcp",
"type": "http",
"headers": {"x-rls-user-id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"}
},
"zava-sales-analysis-redmond": {
"url": "http://127.0.0.1:8000/mcp",
"type": "http",
"headers": {"x-rls-user-id": "e7f8a9b0-c1d2-3e4f-5678-90abcdef1234"}
}
},
"inputs": []
}// .vscode/settings.json
{
"python.defaultInterpreterPath": "./mcp-env/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": ["tests"],
"files.exclude": {
"**/__pycache__": true,
"**/.pytest_cache": true,
"**/mcp-env": true
}
}-
Open the project in VS Code:
code . -
Open AI Chat:
- Press
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(macOS) - Type "AI Chat" and select "AI Chat: Open Chat"
- Press
-
Test MCP Server Connection:
- In AI Chat, type
#zavaand select one of the configured servers - Ask: "What tables are available in the database?"
- You should receive a response listing the retail database tables
- In AI Chat, type
Run this validation script to verify your setup:
# Create validation script
cat > validate_setup.py << 'EOF'
#!/usr/bin/env python3
"""
Environment validation script for MCP Server setup.
"""
import asyncio
import os
import sys
import subprocess
import requests
import asyncpg
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
async def validate_environment():
"""Comprehensive environment validation."""
results = {}
# Check Python version
python_version = sys.version_info
results['python'] = {
'status': 'pass' if python_version >= (3, 8) else 'fail',
'version': f"{python_version.major}.{python_version.minor}.{python_version.micro}",
'required': '3.8+'
}
# Check required packages
required_packages = ['fastmcp', 'asyncpg', 'azure-ai-projects']
for package in required_packages:
try:
__import__(package)
results[f'package_{package}'] = {'status': 'pass'}
except ImportError:
results[f'package_{package}'] = {'status': 'fail', 'error': 'Not installed'}
# Check Docker
try:
result = subprocess.run(['docker', '--version'], capture_output=True, text=True)
results['docker'] = {
'status': 'pass' if result.returncode == 0 else 'fail',
'version': result.stdout.strip() if result.returncode == 0 else 'Not available'
}
except FileNotFoundError:
results['docker'] = {'status': 'fail', 'error': 'Docker not found'}
# Check Azure CLI
try:
result = subprocess.run(['az', '--version'], capture_output=True, text=True)
results['azure_cli'] = {
'status': 'pass' if result.returncode == 0 else 'fail',
'version': result.stdout.split('\n')[0] if result.returncode == 0 else 'Not available'
}
except FileNotFoundError:
results['azure_cli'] = {'status': 'fail', 'error': 'Azure CLI not found'}
# Check environment variables
required_env_vars = [
'PROJECT_ENDPOINT',
'AZURE_OPENAI_ENDPOINT',
'EMBEDDING_MODEL_DEPLOYMENT_NAME',
'AZURE_CLIENT_ID',
'AZURE_CLIENT_SECRET',
'AZURE_TENANT_ID'
]
for var in required_env_vars:
value = os.getenv(var)
results[f'env_{var}'] = {
'status': 'pass' if value else 'fail',
'value': '***' if value and 'SECRET' in var else value
}
# Check database connection
try:
conn = await asyncpg.connect(
host=os.getenv('POSTGRES_HOST', 'localhost'),
port=int(os.getenv('POSTGRES_PORT', 5432)),
database=os.getenv('POSTGRES_DB', 'zava'),
user=os.getenv('POSTGRES_USER', 'postgres'),
password=os.getenv('POSTGRES_PASSWORD', 'secure_password')
)
# Test query
result = await conn.fetchval('SELECT COUNT(*) FROM retail.stores')
await conn.close()
results['database'] = {
'status': 'pass',
'store_count': result
}
except Exception as e:
results['database'] = {
'status': 'fail',
'error': str(e)
}
# Check MCP server
try:
response = requests.get('http://localhost:8000/health', timeout=5)
results['mcp_server'] = {
'status': 'pass' if response.status_code == 200 else 'fail',
'response': response.json() if response.status_code == 200 else response.text
}
except Exception as e:
results['mcp_server'] = {
'status': 'fail',
'error': str(e)
}
# Check Azure AI service
try:
credential = DefaultAzureCredential()
project_client = AIProjectClient(
endpoint=os.getenv('PROJECT_ENDPOINT'),
credential=credential
)
# This will fail if credentials are invalid
results['azure_ai'] = {'status': 'pass'}
except Exception as e:
results['azure_ai'] = {
'status': 'fail',
'error': str(e)
}
return results
def print_results(results):
"""Print formatted validation results."""
print("🔍 Environment Validation Results\n")
print("=" * 50)
passed = 0
failed = 0
for component, result in results.items():
status = result.get('status', 'unknown')
if status == 'pass':
print(f"✅ {component}: PASS")
passed += 1
else:
print(f"❌ {component}: FAIL")
if 'error' in result:
print(f" Error: {result['error']}")
failed += 1
print("\n" + "=" * 50)
print(f"Summary: {passed} passed, {failed} failed")
if failed > 0:
print("\n❗ Please fix the failed components before proceeding.")
return False
else:
print("\n🎉 All validations passed! Your environment is ready.")
return True
if __name__ == "__main__":
asyncio.run(main())
async def main():
results = await validate_environment()
success = print_results(results)
sys.exit(0 if success else 1)
EOF
# Run validation
python validate_setup.py✅ Basic Tools
- Docker version 20.10+ installed and running
- Azure CLI 2.40+ installed and authenticated
- Python 3.8+ with pip installed
- Git 2.30+ installed
- VS Code with required extensions
✅ Azure Resources
- Resource group created successfully
- AI Foundry project deployed
- OpenAI text-embedding-3-small model deployed
- Application Insights configured
- Service principal created with proper permissions
✅ Environment Configuration
-
.envfile created with all required variables - Azure credentials working (test with
az account show) - PostgreSQL container running and accessible
- Sample data loaded in database
✅ VS Code Integration
-
.vscode/mcp.jsonconfigured - Python interpreter set to virtual environment
- MCP servers appear in AI Chat
- Can execute test queries through AI Chat
Problem: Docker containers won't start
# Check Docker service status
docker info
# Check available resources
docker system df
# Clean up if needed
docker system prune -f
# Restart Docker Desktop (Windows/macOS)
# Or restart Docker service (Linux)
sudo systemctl restart dockerProblem: PostgreSQL connection fails
# Check container logs
docker-compose logs postgres
# Verify container is healthy
docker-compose ps
# Test direct connection
docker-compose exec postgres psql -U postgres -d zava -c "SELECT 1;"Problem: Azure deployment fails
# Check Azure CLI authentication
az account show
# Verify subscription permissions
az role assignment list --assignee $(az account show --query user.name -o tsv)
# Check resource provider registration
az provider register --namespace Microsoft.CognitiveServices
az provider register --namespace Microsoft.InsightsProblem: AI service authentication fails
# Test service principal
az login --service-principal \
--username $AZURE_CLIENT_ID \
--password $AZURE_CLIENT_SECRET \
--tenant $AZURE_TENANT_ID
# Verify AI service deployment
az cognitiveservices account list --query "[].{Name:name,Kind:kind,Location:location}"Problem: Package installation fails
# Upgrade pip and setuptools
python -m pip install --upgrade pip setuptools wheel
# Clear pip cache
pip cache purge
# Install packages one by one to identify issues
pip install fastmcp
pip install asyncpg
pip install azure-ai-projectsProblem: VS Code can't find Python interpreter
# Show Python interpreter paths
which python # macOS/Linux
where python # Windows
# Activate virtual environment first
source mcp-env/bin/activate # macOS/Linux
mcp-env\Scripts\activate # Windows
# Then open VS Code
code .After completing this lab, you should have:
✅ Complete Development Environment: All tools installed and configured
✅ Azure Resources Deployed: AI services and supporting infrastructure
✅ Docker Environment Running: PostgreSQL and MCP server containers
✅ VS Code Integration: MCP servers configured and accessible
✅ Validated Setup: All components tested and working together
✅ Troubleshooting Knowledge: Common issues and solutions
With your environment ready, continue to Lab 04: Database Design and Schema to:
- Explore the retail database schema in detail
- Understand multi-tenant data modeling
- Learn about Row Level Security implementation
- Work with sample retail data
- Docker Documentation - Complete Docker reference
- Azure CLI Reference - Azure CLI commands
- VS Code Documentation - Editor configuration and extensions
- Azure AI Foundry Documentation - AI service configuration
- Azure OpenAI Service - AI model deployment
- Application Insights - Monitoring setup
- Python Virtual Environments - Environment management
- AsyncIO Documentation - Async programming patterns
- FastAPI Documentation - Web framework patterns
Next: Environment ready? Continue with Lab 04: Database Design and Schema