다음을 통해 공유


빠른 시작: Azure Container Apps에서 SQL MCP Server 사용

Azure Container Apps에 배포된 SQL MCP 서버를 보여 주는 다이어그램

중요합니다

MCP(SQL 모델 컨텍스트 프로토콜) 서버는 미리 보기 상태이며 이 설명서와 엔진 구현이 변경 될 수 있습니다. Data API Builder 버전 1.7은 미리 보기 상태이지만 MCP 기능이 태그에 아직 포함되지 1.7.83-rc 않았기 때문에 시험판 버전을 명시적으로 사용해야 합니다(예:latest: ).

이 빠른 시작에서는 Azure Container Apps에 SQL MCP Server를 배포하는 방법을 보여줍니다. 배포된 후에는 VS Code(Visual Studio Code), Microsoft Foundry 또는 기타 MCP(모델 컨텍스트 프로토콜) 클라이언트에서 원격 서버 엔드포인트로 연결할 수 있습니다.

ACA 배포 워크플로를 보여 주는 시퀀스 다이어그램

필수 조건

Azure 구독

활성 Azure 구독이 필요합니다. 없는 경우 무료 Azure 계정을 만듭니다.

Azure 커맨드 라인 인터페이스 (CLI)

Azure CLI를 설치하여 리소스를 배포합니다.

winget install Microsoft.AzureCLI

.NET 9 이상

이 도구가 이미 설치되어 있을 수 있습니다. dotnet --version를 실행한 후 버전이 9 이상인지 확인하십시오.

winget install Microsoft.DotNet.Runtime.9

데이터 API 작성기 CLI

dotnet new tool-manifest
dotnet tool install microsoft.dataapibuilder --prerelease

비고

SQL MCP Server는 현재 시험판에 있습니다. 플래그를 --prerelease 사용하면 이 빠른 시작에 사용된 모든 기능을 사용하여 최신 버전의 Data API 작성기를 얻을 수 있습니다.

PowerShell

아직 설치되지 않은 경우 PowerShell을 설치합니다.

dotnet tool install --global PowerShell

1단계: Azure SQL Database 만들기 및 배포

1. Azure에 로그인

az login
az account set --subscription "<your-subscription-id>"

2. 배포에 대한 변수 설정

$RESOURCE_GROUP = "rg-sql-mcp"
$LOCATION = "eastus"
$SQL_SERVER = "sql-mcp-$(Get-Random -Minimum 1000 -Maximum 9999)"
$SQL_DATABASE = "ProductsDB"
$SQL_ADMIN = "sqladmin"
$SQL_PASSWORD = "<YourStrongPassword123!>"

3. 리소스 그룹 만들기

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

4. Azure SQL Server 만들기

az sql server create \
  --name $SQL_SERVER \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --admin-user $SQL_ADMIN \
  --admin-password $SQL_PASSWORD

5. Azure 서비스를 허용하도록 방화벽 구성

az sql server firewall-rule create \
  --resource-group $RESOURCE_GROUP \
  --server $SQL_SERVER \
  --name AllowAzureServices \
  --start-ip-address 0.0.0.0 \
  --end-ip-address 0.0.0.0

6. 데이터베이스 만들기

az sql db create \
  --resource-group $RESOURCE_GROUP \
  --server $SQL_SERVER \
  --name $SQL_DATABASE \
  --service-objective S0

7. 샘플 데이터를 사용하여 Products 테이블 만들기

먼저 연결 문자열을 가져옵니다.

$CONNECTION_STRING = "Server=tcp:$SQL_SERVER.database.windows.net,1433;Database=$SQL_DATABASE;User ID=$SQL_ADMIN;Password=$SQL_PASSWORD;Encrypt=true;TrustServerCertificate=false;Connection Timeout=30;"

SQL 스크립트 파일 create-products.sql만들기:

CREATE TABLE dbo.Products
(
    ProductID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    ProductName NVARCHAR(100) NOT NULL,
    Category NVARCHAR(50) NOT NULL,
    UnitPrice DECIMAL(10,2) NOT NULL,
    UnitsInStock INT NOT NULL,
    Discontinued BIT NOT NULL DEFAULT 0
);

INSERT INTO dbo.Products (ProductName, Category, UnitPrice, UnitsInStock, Discontinued) VALUES
('Laptop Pro 15', 'Electronics', 1299.99, 45, 0),
('Wireless Mouse', 'Electronics', 29.99, 150, 0),
('Office Chair', 'Furniture', 249.99, 30, 0),
('Standing Desk', 'Furniture', 599.99, 15, 0),
('Coffee Maker', 'Appliances', 89.99, 60, 0),
('Notebook Set', 'Office Supplies', 12.99, 200, 0),
('USB-C Hub', 'Electronics', 49.99, 80, 0),
('Desk Lamp', 'Furniture', 39.99, 100, 0),
('Bluetooth Headphones', 'Electronics', 149.99, 50, 0),
('Water Bottle', 'Office Supplies', 19.99, 120, 0);

VS Code, SQL Server Management Studio 또는 sqlcmd를 사용하여 실행합니다.

2단계: SQL MCP 서버 구성

1. dab-config.json 만들기

구성을 초기화합니다.

dab init `
  --database-type mssql `
  --connection-string "@env('MSSQL_CONNECTION_STRING')" `
  --host-mode Production `
  --config dab-config.json

2. 설명이 포함된 Products 엔터티 추가

dab add Products `
  --source dbo.Products `
  --permissions "anonymous:read" `
  --description "Product catalog with pricing, category, and inventory information"

3. 필드 설명이 포함된 AI 에이전트 컨텍스트 제공

AI 에이전트가 데이터베이스 스키마를 이해하는 데 도움이 되는 필드 설명을 추가합니다.

dab update Products `
  --fields.name ProductID `
  --fields.description "Unique product identifier" `
  --fields.primary-key true

dab update Products `
  --fields.name ProductName `
  --fields.description "Name of the product"

dab update Products `
  --fields.name Category `
  --fields.description "Product category (Electronics, Furniture, Office Supplies, Appliances)"

dab update Products `
  --fields.name UnitPrice `
  --fields.description "Retail price per unit in USD"

dab update Products `
  --fields.name UnitsInStock `
  --fields.description "Current inventory count available for purchase"

dab update Products `
  --fields.name Discontinued `
  --fields.description "True if product is no longer available for sale"

3단계: Azure Container Apps에 SQL MCP 서버 배포

1. Azure Container Registry 만들기 및 사용자 지정 이미지 빌드

컨테이너 레지스트리를 만들고 구성이 포함된 사용자 지정 이미지를 빌드합니다.

$ACR_NAME = "acrsqlmcp$(Get-Random -Minimum 1000 -Maximum 9999)"

az acr create `
  --resource-group $RESOURCE_GROUP `
  --name $ACR_NAME `
  --sku Basic `
  --admin-enabled true

2. Dockerfile 만들기

dab-config.json와 동일한 폴더에 Dockerfile라는 파일을 만드십시오.

FROM mcr.microsoft.com/azure-databases/data-api-builder:1.7.83-rc
COPY dab-config.json /App/dab-config.json

3. 이미지 빌드 및 푸시

az acr build `
  --registry $ACR_NAME `
  --image sql-mcp-server:1 `
  .

4. Container Apps 환경 만들기

$CONTAINERAPP_ENV = "sql-mcp-env"
$CONTAINERAPP_NAME = "sql-mcp-server"

az containerapp env create `
  --name $CONTAINERAPP_ENV `
  --resource-group $RESOURCE_GROUP `
  --location $LOCATION

5. SQL MCP Server 컨테이너 배포

$ACR_LOGIN_SERVER = az acr show `
  --name $ACR_NAME `
  --query loginServer `
  --output tsv

$ACR_USERNAME = az acr credential show `
  --name $ACR_NAME `
  --query username `
  --output tsv

$ACR_PASSWORD = az acr credential show `
  --name $ACR_NAME `
  --query "passwords[0].value" `
  --output tsv

az containerapp create `
  --name $CONTAINERAPP_NAME `
  --resource-group $RESOURCE_GROUP `
  --environment $CONTAINERAPP_ENV `
  --image "$ACR_LOGIN_SERVER/sql-mcp-server:1" `
  --registry-server $ACR_LOGIN_SERVER `
  --registry-username $ACR_USERNAME `
  --registry-password $ACR_PASSWORD `
  --target-port 5000 `
  --ingress external `
  --min-replicas 1 `
  --max-replicas 3 `
  --secrets "mssql-connection-string=$CONNECTION_STRING" `
  --env-vars "MSSQL_CONNECTION_STRING=secretref:mssql-connection-string" `
  --cpu 0.5 `
  --memory 1.0Gi

리소스 그룹은 다음 예제와 유사해야 합니다.

배포 후 Azure Portal 리소스 그룹의 스크린샷

6. MCP 엔드포인트 URL 가져오기

$MCP_URL = az containerapp show `
  --name $CONTAINERAPP_NAME `
  --resource-group $RESOURCE_GROUP `
  --query "properties.configuration.ingress.fqdn" `
  --output tsv

Write-Host "Your MCP Server URL: https://$MCP_URL/mcp"

이 URL을 저장합니다. 이 URL을 사용하여 MCP 클라이언트에서 연결합니다.

7. 배포 테스트

curl "https://$MCP_URL/health"

정상적인 응답이 보여야 합니다.

MCP 클라이언트에서 연결

이제 SQL MCP Server가 배포되어 사용할 준비가 되었습니다. 다양한 클라이언트에서 연결하는 방법은 다음과 같습니다.

VS Code(Visual Studio Code)

VS Code 가이드를 사용하여 빠른 시작을 수행하고 로컬로 실행하는 대신 배포된 MCP 서버 URL을 사용합니다.

Microsoft Foundry에서

MCP 서버를 사용자 지정 MCP 도구로 추가하려면 Microsoft Foundry 가이드의 빠른 시작을 따릅니다.

기타 MCP 클라이언트

3.6단계의 MCP 서버 URL을 사용하여 MCP 호환 클라이언트에서 연결합니다.

모니터링 및 문제 해결

Container Apps 로그 보기

az containerapp logs show \
  --name $CONTAINERAPP_NAME \
  --resource-group $RESOURCE_GROUP \
  --follow

MCP 엔드포인트 상태 확인

curl "https://$MCP_URL/health"

일반적인 문제

연결 실패 오류

  • Container Apps의 ingress 수신이 external로 설정되어 있는지 확인합니다.
  • SQL 연결 문자열이 올바른지 확인합니다.
  • Azure SQL에서 방화벽 규칙 확인

데이터가 반환되지 않음

  • Products 테이블이 만들어지고 채워졌는지 확인합니다.
  • dab-config.json에서 엔터티 권한 확인
  • 오류에 대한 Container Apps 로그 검토

성능이 느림

  • CPU/메모리 할당을 늘리는 것이 좋습니다.
  • 복제본을 확장해야 하는지 확인
  • Application Insights 메트릭 검토

프로덕션에 대한 보안 모범 사례

  • 인증 사용 - 익명 액세스 대신 Microsoft Entra ID 인증 구성
  • 관리 ID 사용 - 관리 ID를 사용하여 Container Apps가 SQL에 인증하도록 허용
  • CORS 구현 - MCP 서버에 액세스할 수 있는 도메인 제한
  • 속도 제한 사용 - 남용으로부터 보호
  • Azure Key Vault 사용 - 연결 문자열을 안전하게 저장
  • Application Insights를 사용하여 모니터링 - 사용량 및 성능 추적
  • 권한 제한 - 필요한 액세스 수준만 부여

자원을 정리하세요

완료되면 리소스 그룹을 삭제하여 모든 리소스를 제거합니다.

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

전체 샘플 스크립트

다음은 이 빠른 시작의 모든 단계를 수행하는 전체 PowerShell 스크립트입니다. 실행하기 전에 테넌트 ID, 구독 ID 및 암호 변수를 업데이트합니다.

팁 (조언)

관리 ID 인증, 상태 검사 및 자동 정리를 사용하는 프로덕션 준비 배포는 Data API Builder 데모 환경 스크립트를 참조하세요.

# ============================================
# Variables - UPDATE THESE VALUES
# ============================================
$RESOURCE_GROUP = "rg-sql-mcp"
$LOCATION = "centralus"
$SQL_SERVER = "sql-mcp-$(Get-Random -Minimum 1000 -Maximum 9999)"
$SQL_DATABASE = "ProductsDB"
$SQL_ADMIN = "sqladmin"
$SQL_PASSWORD = "P@ssw0rd!"  # Replace with a strong password
$ACR_NAME = "acrsqlmcp$(Get-Random -Minimum 1000 -Maximum 9999)"
$CONTAINERAPP_ENV = "sql-mcp-env"
$CONTAINERAPP_NAME = "sql-mcp-server"

# ============================================
# Sign in to Azure
# ============================================
az login --tenant "<your-tenant-id>"
az account set --subscription "<your-subscription-id>"

# ============================================
# Check if resource group exists and create unique name
# ============================================
$RG_COUNTER = 0
$ORIGINAL_RG = $RESOURCE_GROUP
while ($true) {
    $RG_EXISTS = az group exists --name $RESOURCE_GROUP
    if ($RG_EXISTS -eq "false") {
        break
    }
    $RG_COUNTER++
    $RESOURCE_GROUP = "$ORIGINAL_RG-$RG_COUNTER"
}
Write-Host "Using resource group: $RESOURCE_GROUP" -ForegroundColor Green

# ============================================
# Step 1: Create Azure SQL Database
# ============================================
az group create --name $RESOURCE_GROUP --location $LOCATION

az sql server create `
  --name $SQL_SERVER `
  --resource-group $RESOURCE_GROUP `
  --location $LOCATION `
  --admin-user $SQL_ADMIN `
  --admin-password $SQL_PASSWORD

az sql server firewall-rule create `
  --resource-group $RESOURCE_GROUP `
  --server $SQL_SERVER `
  --name AllowAzureServices `
  --start-ip-address 0.0.0.0 `
  --end-ip-address 0.0.0.0

# Add current client IP to firewall
$MY_IP = (Invoke-RestMethod -Uri 'https://api.ipify.org?format=text')
az sql server firewall-rule create `
  --resource-group $RESOURCE_GROUP `
  --server $SQL_SERVER `
  --name AllowMyIP `
  --start-ip-address $MY_IP `
  --end-ip-address $MY_IP

az sql db create `
  --resource-group $RESOURCE_GROUP `
  --server $SQL_SERVER `
  --name $SQL_DATABASE `
  --service-objective S0

$CONNECTION_STRING = "Server=tcp:$SQL_SERVER.database.windows.net,1433;Database=$SQL_DATABASE;User ID=$SQL_ADMIN;Password=$SQL_PASSWORD;Encrypt=true;TrustServerCertificate=false;Connection Timeout=30;"

# Create sample table using sqlcmd
Write-Host "Creating Products table and sample data..." -ForegroundColor Yellow

$SQL_SCRIPT = @"
CREATE TABLE dbo.Products (
    ProductID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    ProductName NVARCHAR(100) NOT NULL,
    Category NVARCHAR(50) NOT NULL,
    UnitPrice DECIMAL(10,2) NOT NULL,
    UnitsInStock INT NOT NULL,
    Discontinued BIT NOT NULL DEFAULT 0
);

INSERT INTO dbo.Products (ProductName, Category, UnitPrice, UnitsInStock, Discontinued) VALUES
('Laptop Pro 15', 'Electronics', 1299.99, 45, 0),
('Wireless Mouse', 'Electronics', 29.99, 150, 0),
('Office Chair', 'Furniture', 249.99, 30, 0),
('Standing Desk', 'Furniture', 599.99, 15, 0),
('Coffee Maker', 'Appliances', 89.99, 60, 0);
"@

# Use Invoke-Sqlcmd if available, otherwise skip table creation
try {
    $SQL_SCRIPT | Out-File -FilePath "create-table.sql" -Encoding utf8
    sqlcmd -S "$SQL_SERVER.database.windows.net" -d $SQL_DATABASE -U $SQL_ADMIN -P $SQL_PASSWORD -i "create-table.sql"
    Remove-Item "create-table.sql" -ErrorAction SilentlyContinue
    Write-Host "Products table created successfully!" -ForegroundColor Green
} catch {
    Write-Host "Note: Could not create table automatically. You can create it manually later." -ForegroundColor Yellow
    Write-Host "SQL Script saved for manual execution if needed." -ForegroundColor Yellow
}

# ============================================
# Step 2: Configure SQL MCP Server
# ============================================
# Remove existing config if present
if (Test-Path "dab-config.json") {
    Remove-Item "dab-config.json" -Force
}

dab init `
  --database-type mssql `
  --connection-string "@env('MSSQL_CONNECTION_STRING')" `
  --host-mode Production `
  --config dab-config.json

dab add Products `
  --source dbo.Products `
  --permissions "anonymous:read" `
  --description "Product catalog with pricing, category, and inventory information"

# ============================================
# Step 3: Deploy to Azure Container Apps
# ============================================
az acr create `
  --resource-group $RESOURCE_GROUP `
  --name $ACR_NAME `
  --sku Basic `
  --admin-enabled true

# Create Dockerfile
@"
FROM mcr.microsoft.com/azure-databases/data-api-builder:1.7.83-rc
COPY dab-config.json /App/dab-config.json
"@ | Out-File -FilePath Dockerfile -Encoding utf8

az acr build --registry $ACR_NAME --image sql-mcp-server:1 .

az containerapp env create `
  --name $CONTAINERAPP_ENV `
  --resource-group $RESOURCE_GROUP `
  --location $LOCATION

# Get ACR credentials for initial deployment
$ACR_LOGIN_SERVER = az acr show --name $ACR_NAME --query loginServer --output tsv
$ACR_USERNAME = az acr credential show --name $ACR_NAME --query username --output tsv
$ACR_PASSWORD = az acr credential show --name $ACR_NAME --query "passwords[0].value" --output tsv

az containerapp create `
  --name $CONTAINERAPP_NAME `
  --resource-group $RESOURCE_GROUP `
  --environment $CONTAINERAPP_ENV `
  --image "$ACR_LOGIN_SERVER/sql-mcp-server:1" `
  --registry-server $ACR_LOGIN_SERVER `
  --registry-username $ACR_USERNAME `
  --registry-password $ACR_PASSWORD `
  --target-port 5000 `
  --ingress external `
  --min-replicas 1 `
  --max-replicas 3 `
  --secrets "mssql-connection-string=$CONNECTION_STRING" `
  --env-vars "MSSQL_CONNECTION_STRING=secretref:mssql-connection-string" `
  --cpu 0.5 `
  --memory 1.0Gi

# ============================================
# Output
# ============================================
$MCP_URL = az containerapp show `
  --name $CONTAINERAPP_NAME `
  --resource-group $RESOURCE_GROUP `
  --query "properties.configuration.ingress.fqdn" `
  --output tsv

Write-Host ""
Write-Host "Deployment complete!" -ForegroundColor Green
Write-Host "MCP Server URL: https://$MCP_URL/mcp" -ForegroundColor Cyan
Write-Host "Health check:   https://$MCP_URL/health" -ForegroundColor Cyan