SQL MCP Server’ı App Service’te Çalıştırmak: Container’sız Yol
Açık konuşayım: container tarafını seven bir adamım. Ama her müşteride aynı şeyi söyleyince bana boş boş bakanlar da oluyor — “Aşkın bey, biz daha Kubernetes’e geçmedik, App Service’te koşturuyoruz her şeyi.” Tamam, anlıyorum. Herkesin AKS cluster’ı yok; olması da gerekmiyor zaten.
İşte tam da bu yüzden geçen hafta Microsoft’un Azure SQL ekibinden çıkan duyuruyu okuyunca biraz sevindim. SQL MCP Server artık container olmadan, düz bir App Service üzerinde çalışabiliyor (ben de ilk duyduğumda şaşırmıştım). Peki bu ne demek? Kime yarıyor, nerede tökezliyor, nereye kadar gidiyor — hepsini sırayla anlatacağım. Ama önce şu MCP işini bir yerine oturtalım, çünkü herkes “MCP MCP” diyor ama yarısı ne olduğunu bilmiyor.
Evet, doğru duydunuz.
MCP Server Tam Olarak Ne İşe Yarıyor?
Model Context Protocol, yanı MCP, basitçe söyleyeyim, bir AI ajanı ile dış dünya arasındaki köprü gibi dürüyor. Ajan bir veritabanına, bir API’ye ya da dosya sistemine erişmek istediğinde, MCP server o işi standart bir protokolle toparlıyor; yanı ajan gidip kafasına göre “SELECT * FROM Customers” diye SQL atmıyor, onun yerine kontrollü bir yüzeyle konuşuyor. Kulağa biraz soyut geliyor olabilir. Ama işin aslı tam burada başlıyor.
Araya gireyim: SQL MCP Server da bunun SQL Server ve Azure SQL tarafındaki hali. Altında Data API builder (DAB) çalışıyor — DAB’ı bilenler bilir, zaten REST ve GraphQL endpoint’lerini config dosyasından üretiyordu, şimdi aynı runtime aynı config üzerinden MCP’yi de servis ediyor. Hani bir taşla birkaç kuş vurmak var ya, işte biraz öyle; ama durun, bu kısmın bedeli de yok değil, ona sonra geleceğim.
Bunun benim için en önemli kısmı şu: Tek bir ayarla aynı anda hem MCP hem REST hem GraphQL servis edebiliyorsunuz. Üç ayrı API yazmak yok, üç ayrı deployment yok. Baya iş görüyor.
Niye Doğrudan SQL’e Bağlanmak Kötü Fikir?
Geçen ay bir sigorta şirketinde POC yapıyorduk. Ekip OpenAI ajanına doğrudan production SQL connection string’i vermişti; “Aşkın abi çalışıyor ama” dediler. Çalışıyordu tabiî, ta ki ajan bir gün DELETE FROM Policies WHERE 1=1 üretene kadar… Neyse ki prod değildi, şükür. Ama bak şimdi mesele şu: LLM’ler bazen aklınıza gelmeyecek sorgular yazıyor, hatta bazen bildiğin saçmalıyor; schema’yı doğrudan göstermek baya ayağınıza sıkmak gibi oluyor.
Bak şimdi, MCP server araya girince ajan sadece tanımladığınız entity’leri görüyor. Customer entity’sinde yalnızca id, name, email alanlarını expose ettiyseniz, ajan başka bir şey göremiyor; ne gizli kolonlar kalıyor ne de yanlışlıkla ortalığı karıştıracak alanlar. Bu sadece güvenlik değil aslında (evet güvenlik önemli), aynı zamanda uygulama modelinizi koruma meselesi de var. Fiziksel şema değişse bile ajan aynı entity’yi görmeye devam ediyor.
Bir dakika — bununla bitmedi.
Peki neden önemli? Çünkü modelin önüne her şeyi koyunca iş kolaylaşmıyor, tam tersine karışıyor.
Container Şart mı? Hayır, Değil.
Aslında, Microsoft’un dokümanlarına bakınca SQL MCP Server için varsayılan yol container gibi dürüyor. Mantıklı, evet; image hazır, indiriyorsun, çalıştırıyorsun, olay kapanıyor. Ama iş sahaya gelince tablo biraz değişiyor, çünkü her ekip Docker’la haşır neşir değil.
Türkiye’de gördüğüm kurumsal müşterilerde durum baya benzer. Banka var, sigorta var, kamu var; çoğu hâlâ App Service üstünde gidiyor ve container tarafı ya hiç yok ya da var ama prod’a sürülmemiş (yanı rafın üstünde bekliyor), AKS kuracak insan sayısı da açık konuşayım çok sınırlı.
Şimdi böyle bir ekibe “AI ajan için MCP server lazım, hadi AKS kuralım” derseniz ne olur? Pek bir şey olmaz. Proje uzar, motivasyon düşer, bazen de bayağı rafa kalkar. İşte tam burada container’sız App Service seçeneği ciddi rahatlatıyor.
Container Maliyetinin Görünmeyen Tarafı
Container deyince sadece Docker image akla geliyor ama mesele orada bitmiyor. Build pipeline kuracaksın, registry yöneteceksin, vulnerability scan bakacaksın, image versiyonlayacaksın, rollback planlayacaksın; hmm, bunların hepsi ayrı iş (inanın bana). Küçük ekipte baya yoruyor.
App Service’te git push ile deploy edebiliyorken neden ekstra katman açalım? Şey gibi düşünün: elinizde. Çalışan bir yol varken sırf “modern görünsün” diye yeni bir yol yapmak pek mantıklı olmuyor.
Bunu Türkiye’deki şirketler açısından okuyunca özellikle 50 kişi altındaki yazılım ekiplerinde container’sız yaklaşım bana daha doğru geliyor. Az önce “container kötü” dedim sanmayın; değil aslında, sadece her yerde ilk seçenek olmak zorunda değil. Sonra isterseniz geçersiniz.
DAB CLI ile Yerel Geliştirme
İşin hoş. Şu: Data API builder’ın cross-platform bir CLI’ı var..NET kurulu olan her makinede çalışıyor, yanı Windows’ta da oluyor, Maç’te de, Linux’ta da; Docker’a, Kubernetes’e falan bulaşmadan ilerleyebiliyorsunuz (kendi tecrübem)
Hani, Lokal kurulum aslında şöyle akıyor:
# DAB CLI kurulumu
dotnet tool install -g Microsoft.DataApiBuilder
# Yeni bir konfigurasyon olustur
dab init --database-type mssql --connection-string "Server=...;Database=...;"
# Bir entity ekle (Customers tablosu için)
dab add Customer --source dbo.Customers --permissions "anonymous:read"
# Runtime'i baslat
dab start
Bu kadar. dab start dediğiniz anda MCP endpoint’i, REST endpoint’i ve GraphQL endpoint’i kalkıyor. Aynı porttan servis veriyorlar, aynı config’i kullanıyorlar, ama tüketim şekli üç ayrı kapı gibi dürüyor. Garip ama işe yarıyor.
Bir de küçük bir not düşeyim: İlk denememde dab start çalıştırınca port çakışması hatası almıştım. Default port 5000 ya, çoğu makinede başka bir şey o portu çoktan kapmış oluyor. --port 8080 deyince düzeldi. Minik detay gibi görünüyor ama bazen yarım saat yediriyor insana.
Evet, doğru duydunuz.
Azure App Service’e Deployment
Şimdi işin can alıcı yerine geldik. Lokalde koşturan bu yapıyı App Service tarafına nasıl taşıyoruz, mesele tam olarak bu.
Mantık aslında basit gibi dürüyor, ama küçük bir detay yüzünden insanı uğraştırabiliyor: DAB zaten bir.NET uygulaması, App Service de.NET tarafını gayet iyi host ediyor, yanı yapacağımız şey DAB binary’lerini App Service’e koymak. dab start komutunu startup command olarak vermek.
Adım Adım Kurulum
- App Service oluştur: Linux tabanlı bir plan açın,.NET 8 runtime seçin. Windows da çalışıyor, evet, ama Linux App Service Plan’ları çoğu zaman daha hesaplı oluyor; bazen fark öyle az değil, insan dönüp bir daha bakıyor. — bunu es geçmeyin
- DAB binary’lerini paketle:
dotnet publishile klasik uygulama yayımlar gibi ilerlemeyin; burada doğrudan DAB CLI’ı bir zıp içine koymak daha net bir yol. İsterseniz nuget üzerinden global tool olarak kurup oradan da başlatabilirsiniz, ikisi de iş görüyor. - Konfigürasyon dosyasını ekle:
dab-config.jsondosyanız mutlaka App Service’in dosya sistemine gitmeli. Ben genelde/home/site/wwwrootaltına bırakıyorum, çünkü sonra ararken kafam karışmıyor. - Startup command: App Service’in Configuration > General Settings bölümünden startup command olarak
dab start --config /home/site/wwwroot/dab-config.jsonverin. Kulağa fazla düz geliyor ama burada sadelik baya işe yarıyor. — ciddi fark yaratıyor - Connection string: Veritabanı bağlantı dizesini App Service’in Application Settings kısmına environment variable olarak ekleyin. Config dosyasına gömmeyin, açık konuşayım, bunu yapan ekipler sonra neden güvenlik taramasında patladık diye düşünüyor.
Evet. Küçük görünüyor ama kritik.
Ne yalan söyleyeyim, Neyse uzatmayalım; bu kurulumda asıl mesele sadece deploy etmek değil, sırayı doğru kurmak (ilk duyduğumda inanamadım). Önce paketleme, sonra config, ardından startup command ve en son secret yönetimi. Kısacası, peki neden? Çünkü en çok sorun çıkaran kısım genelde uygulamanın kendisi değil, çevresindeki ayarlar oluyor.
Peki neden?
Şahsen, Bazı ekipler burada işi gereksiz karmaşıklaştırıyor, halbuki çoğu senaryoda düzgün bir Linux App Service + temiz ayar + Key Vault üçlüsü baya yeterli oluyor. Yanı evet, gösterişli değil; ama çalışıyor.
Hangi Senaryoda Hangisi Daha Mantıklı?
Şimdi açık konuşayım, App Service her zaman doğru seçenek değil. Duruma göre değişiyor; bazen baya iş görüyor, bazen de insanı gereksiz yere uğraştırıyor.
| Senaryo | App Service | Container (AKS/ACA) |
|---|---|---|
| Küçük ekip, tek MCP endpoint | ✅ Tercih edilir | ❌ Aşırı karmaşık |
| Mevcut App Service yatırımı var | ✅ Doğal uyum | ⚠️ Yeniden mimarı gerekir |
| Çoklu MCP server, mikroservis mimarı | ⚠️ Yönetim zorlaşır | ✅ Daha mantıklı |
| Auto-scaling kritik | ✅ Yeterli (Premium plan) | ✅ Daha esnek |
| CI/CD basitliği | ✅ Git push yeter | ⚠️ Image pipeline lazım |
| Multi-region failover | ⚠️ Traffic Manager gerek | ✅ Native destek iyi |
Kısacası, tek bir AI ajanı için MCP server çalıştıracaksanız, App Service gayet mantıklı. Hatta çoğu zaman fazla düşünmeye bile gerek yok. Ama iş büyüyorsa, birkaç ajan devreye giriyorsa ya da çok bölgeli dağıtım. Dinamik scaling istiyorsanız, o noktada Container Apps veya AKS tarafına bakmak daha doğru olur.
Peki neden? Çünkü mesele sadece ayağa kaldırmak değil. Sonrası da var; bakım, ölçekleme, dağıtım derken tablo bir anda değişiyor.
Evet.
Açıkçası burada sihirli bir cevap yok.
Bazen en sade yol en iyisidir, bazen de o sade yol ileride baş ağrıtır. İşin aslı bu kadar net.
Güvenlik Tarafı: Entra ID Authentication
İşin garibi, App Service tarafında en sevdiğim şeylerden biri, açık konuşayım, “Easy Auth” oluyor — yanı built-in Microsoft Entra ID entegrasyonu. Tek bir ayarla MCP endpoint’ınızı Entra ID’nın arkasına alıyorsunuz. Token doğrulamasını App Service yapıyor, DAB işe sadece request’i karşılıyor; basit görünüyor ama işin rahatlatan kısmı tam da burada.
Bu nokta agentic senaryolarda baya kritik. Ajanınız bazen Managed Identity ile, bazen de bir service principal üzerinden MCP server’a token yolluyor, server bunu doğruluyor, ardından DAB seviyesinde role-based filtering devreye giriyor; yanı zincirin her halkasında ayrı bir kontrol var, bu da defense in depth yaklaşımını pratikte hissedilir hâle getiriyor.
Daha geniş güvenlik mimarisi için Least Privilege Ajanlar: Güvenliği Baştan Kurmanın Yeni Yolu yazısına bakmanızı tavsiye ederim — orada ajan-seviyesi yetkilendirme stratejilerini daha didik didik anlattım, hatta bazı yerlerde biraz fazla detaya da girdim diyebilirim.
Maliyet Analizi: TL Bazında Düşünelim
Türkiye’deki müşterilerimin ilk sorduğu şey şu oluyor: “Bu bana ayda kaç para?”
Açık konuşayım, container ile App Service arasındaki maliyet farkı tamamen kullanım şekline bağlı (şaşırtıcı ama gerçek). Ama tipik bir tabloyu kabaca böyle düşünebilirsiniz: trafik düşükse bir taraf baya iş görüyor, trafik dalgalanıyorsa başka bir taraf daha mantıklı geliyor (evet, iş biraz orada karışıyor).
- App Service B2 plan: Aylık yaklaşık 55-60 USD. Tek MCP server için gayet yeterli. TL bazında bakınca küçük bir ekip için idare eder bir rakam diyebilirim. (bence en önemlisi)
- Container Apps (consumption): İlk 180.000 vCPU-saniye ücretsiz. Az trafik varsa aslında daha ucuz bile çıkabiliyor. Ama dur bir saniye — soğuk başlangıç konusu var, yanı ilk isteklerde kısa da olsa bekleme yaşayabiliyorsunuz.
- AKS: Cluster yönetim ücreti yok ama node’lar için ödeme yapıyorsunuz. En az 2 node Standard_D2s_v3 ile ayda 140+ USD’den başlıyor, üstüne load balancer geliyor, storage ekleniyor, derken fatura sessizce büyüyor.
FinOps tarafından bakınca küçük ve orta ölçek için App Service çoğu zaman öne çıkıyor. Hatta elinizde zaten bir App Service Plan varsa iş daha da rahatlıyor; aynı plan üzerinde birden fazla app host edebiliyorsunuz, dolayısıyla marjinal maliyet neredeyse sıfıra yaklaşıyor.
İlk Adım Olarak Ne Yapmalı?
Bak şimdi, eğer bunu denemek istiyorsanız, işi ilk günden büyütmeyin; lokalde başlayın, DAB CLI’ı kurun, dab start ile ayağa kaldırın, sonra da AdventureWorks üzerinden 2-3 entity expose edip akışı bir görün. Evet, bu kadar basit başlamak çoğu zaman daha iyi çalışıyor.
- Lokalde DAB CLI’ı kurun,
dab startile çalıştırın (bu kritik) - Bir AdventureWorks örneği üzerinden 2-3 entity expose edin
- VS Code’da MCP-compatible bir client ile (örneğin Claude Desktop veya GitHub Copilot) endpoint’e bağlanıp test edin
- Çalıştığını gördükten sonra App Service’e taşıyın
- Entra ID authentication’ı en sonda aktive edin — önce çalışsın, sonra güvenliği katmanlayın (bu kritik)
İnanın, Peki neden böyle? Çünkü önce çalıştığını görmek lazım; yoksa güvenlik, deployment, client uyumu derken insan gereksiz yere boğuluyor. Geçenlerde benzer bir senaryoda, ekip önce Entra ID tarafına abanmıştı (iyi niyetle tabiî), ama asıl sorun endpoint’in doğru cevap vermemesiydi; yanı mesele kimlik doğrulama değilmiş gibi duruyordu, aslında tamamen başka yerde patlıyordu. Neyse, çok dağıtmayayım.
Evet, doğru duydunuz.
Bu konuyu Cosmos tarafıyla karşılaştırmak isterseniz Azure Cosmos DB ile Kurumsal Yapay Zekâ: Ölçek Meselesi yazısına da bir göz atın — orada veritabanı seçimi ve ölçek konularını ele aldım. Bir de vektör tarafında neler döndüğünü merak ediyorsanız Azure SQL’de AI_GENERATE_EMBEDDINGS GA: T-SQL ile Vektör Devri yazısı işinize yarar (bizzat test ettim). Şey, burada bağlantılar boşuna durmuyor; biri mimariyi tartıyor, diğeri de vektör işinin mutfağına biraz daha yakından bakıyor. Sız ne dersiniz?
Benim Genel Değerlendirmem
Şimdi biraz soğukkanlı bakayım. SQL MCP Server’ın App Service üzerinde çalışması güzel bir gelişme, ama işin içinde hâlâ birkaç pürüz var.
Mesela telemetri tarafı, container deployment’a kıyasla App Service’te biraz daha uğraştırıyor; Application Insights entegrasyonu otomatik gelmiyor, elle ekliyorsunuz, yanı küçük gibi duran ama prod’da bir şeyler ters giderse insanın canını baya kurtaran bir detay bu.
Bir de DAB tarafı var. Hani proje kötü mü, değil; ama olgunluk seviyesi hâlâ yol alıyor. Bu ne anlama geliyor? Bazı edge case’lerde, özellikle complex authorization policy’leri devreye girince, beklemediğiniz davranışlar çıkabiliyor; ben test yaparken computed column ile ilgili bir bug’a denk geldim, GitHub’a issue açtım, ekip hızlı döndü ama yine de prod’a taşırken temkinli olmak lazım.
Şunu söyleyeyim, Kağıt üstünde tablo iyi görünüyor. Pratikte de idare eder. Ama henüz “set and forget” noktasında değil, açık konuşayım; biraz el değmesi istiyor. Evet. Önümüzdeki 6-12 ay içinde bunun da toparlanacağını düşünüyorum.
Sıkça Sorulan Sorular
SQL MCP Server ile Data API builder arasındaki fark ne?
Aslında ikisi de aynı runtime üzerinde çalışıyor. Data API builder bir düşüneyim… REST ve GraphQL endpoint’i üretiyor; SQL MCP Server işe aynı DAB runtime’ına MCP protokolü üzerinden erişim sağlıyor (inanın bana). Yanı SQL MCP Server’ı, hani DAB’ın bir uzantısı gibi düşünebilirsiniz. Tek bir ayar dosyasıyla üç endpoint tipini birden ayağa kaldırabiliyorsunuz.
Container kullanmadan App Service’e deploy etmek production için yeterli mi?
Bakın, Evet, çoğu senaryo için gayet yeterli. App Service zaten production-grade bir hosting servisi — TLS, scaling, monitöring, custom domain, hepsi hazır geliyor. Açıkçası tek bir MCP server koşturuyorsanız ve trafiğiniz çok yüksek değilse, bence App Service hem operasyonel hem de maliyet açısından container’dan çok daha mantıklı bir seçenek.
MCP endpoint’ımı nasıl güvenli hâle getirebilirim?
İki katmanlı bir yaklaşım öneririm. Önce App Service’in built-in Microsoft Entra ID authentication’ını, yanı Easy Auth’u aktive edin. Sonra DAB konfigürasyonunda role-based permission’ları tanımlayın. Connection string’i Key Vault’a koyup Managed Identity ile çekin. Bir de IP restriction veya Private Endpoint eklersen, mesela, her şey yerli yerine oturmuş olur.
Şimdi gelelim işin can alıcı noktasına.
AI ajanım MCP server’a nasıl bağlanıyor?
MCP-compatible bir client kütüphanesi üzerinden bağlanıyor. Microsoft’un Agent Framework’ü, GitHub Copilot, Claude Desktop — bunların hepsinde MCP client desteği var (ben de ilk duyduğumda şaşırmıştım). Ajan, MCP server’ın URL’sını ve auth token’ını alıp standart MCP protokolüyle konuşuyor. Tecrübeme göre server tarafında ne çalıştığı, container mı App Service mi, hiç fark etmiyor.
Mevcut bir SQL veritabanım var, başka bir şey değiştirmem gerekiyor mu?
Hayır, genelde veritabanı tarafında herhangi bir değişiklik yapmanıza gerek yok. DAB sadece okuyor; sizin yapacağınız şey config dosyasında hangi tablo ya da view’ların hangi entity olarak expose edileceğini. Hangi rollerin neye erişebileceğini tanımlamak. Yine de bence production’da direct tablo expose etmek yerine view kullanın — bu şekilde bir abstraction katmanı koymuş olursunuz ve ileride şema değişikliklerinde başınız ağrımaz.
Kaynaklar ve İleri Okuma
SQL MCP Server as an App Service — Azure SQL DevBlog (orijinal kaynak)
Data API builder Resmî Dokümantasyonu — Microsoft Learn
Data API builder CLI Reference — Microsoft Learn
Data API builder GitHub Repository
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.








Yorum gönder