02.13db44e4 numaralı fikir

MCP vs API: Rakip Değiller, Farklı Problemleri Çözüyorlar

MCP ve API çoğu zaman birbirine rakip teknolojiler gibi anlatılıyor ancak aslında farklı problemleri çözüyorlar. API'ler uygulamalar arasındaki iletişimi sağlarken MCP, yapay zeka modellerinin dış sistemlerdeki araçları keşfetmesini ve kullanmasını standartlaştırıyor. Bu yazıda iki yaklaşımın farklarını, birlikte nasıl kullanılabileceklerini ve özellikle backend mimarileri açısından nelere dikkat edilmesi gerektiğini ele alıyorum.

İçindekiler
MCP vs API: Rakip Değiller, Farklı Problemleri Çözüyorlar

Son dönemde MCP ile ilgili içeriklere bakarken aynı soruya sürekli rastlıyorum: MCP, API'lerin yerini mi alacak? İlk bakışta bu soru çok da yanlış görünmüyor. Sonuçta yıllardır uygulamalar arasında REST API, GraphQL veya gRPC gibi yöntemlerle iletişim kuruyoruz. Şimdi Model Context Protocol, yani MCP geliyor ve yine dış sistemlerden veri okumaktan, işlem çalıştırmaktan ve servislerle haberleşmekten bahsediyoruz. Ben de ilk baktığımda ister istemez aynı noktaya takılmıştım. Zaten API diye gayet iyi çalışan bir yapı varken neden yeni bir protokole ihtiyacımız olsun? Biraz daha derine indiğimde ise aslında MCP ile API'yi aynı seviyede iki alternatif olarak karşılaştırmanın çok doğru olmadığını fark ettim. Çünkü temel olarak çözdükleri problem farklı. API, uygulamaların birbiriyle nasıl konuşacağını belirliyor. MCP ise yapay zeka modellerinin bir sistemde hangi yeteneklerin bulunduğunu keşfetmesini, bu yetenekleri anlamasını ve gerektiğinde kullanmasını kolaylaştırıyor. Aradaki fark özellikle AI agent tabanlı sistemler geliştirmeye başladığımızda çok daha belirgin hale geliyor.

API Tarafında Yıllardır Ne Yapıyoruz?

Bir .NET uygulamasından başka bir servise bağlandığımızı düşünelim. Elimizde şöyle bir endpoint olsun:

GET /api/customers/42

Uygulamamızda da buna benzer bir kod yazalım:

var client = httpClientFactory.CreateClient("CustomerApi");

var customer = await client.GetFromJsonAsync<CustomerDto>(
    "/api/customers/42",
    cancellationToken);

Burada aslında çok önemli bir varsayım var: Uygulama ne yapacağını zaten biliyor. Hangi servise bağlanacağını biz belirledik. Hangi endpoint'in çağrılacağını biliyoruz. Parametrelerin ne olduğunu biliyoruz. Dönen cevabın hangi modele deserialize edileceğini de biliyoruz. Yani entegrasyon bilgisi bizim yazdığımız kodun içerisinde zaten mevcut. API'nin kendisini uygulamaya anlatmasına gerek yok. Swagger veya OpenAPI dokümantasyonu olabilir ama bu dokümantasyonu okuyup kodu yazan yine geliştirici. Bu model yıllardır oldukça iyi çalışıyor ve çalışmaya da devam edecek.

Tüketici Değişince Problem de Değişiyor

AI agent sistemlerinde ise tüketici artık her zaman bizim yazdığımız deterministik bir kod değil. Bazen bir LLM. Örneğin kullanıcı şu isteği versin:

Son bir haftadaki kritik production hatalarını bul, bunlarla ilişkili GitHub issue'larını kontrol et ve açık issue yoksa oluştur.

Klasik bir uygulamada bu workflow'u biz yazarız:

1. Log servisine git.
2. Critical logları getir.
3. GitHub üzerinde issue ara.
4. Issue yoksa oluştur.
5. Sonucu kullanıcıya göster.

Bu yaklaşımda her adım bizim tarafımızdan belirlenmiştir. Agent tarafında ise modele şunu söylemek istiyoruz:

Bu problemi çöz.

Modelin elindeki araçlara bakmasını, hangi aracı ne zaman kullanacağına karar vermesini ve gerekirse birkaç farklı sistemi birlikte kullanmasını bekliyoruz. MCP'nin asıl anlam kazandığı yer tam olarak burası.

MCP Neyi Standartlaştırıyor?

Model Context Protocol, AI uygulamalarının dış sistemlerdeki veri ve araçlara standart bir şekilde erişmesini sağlayan bir protokol. MCP tarafında temel olarak üç kavram öne çıkıyor:

  • Tools
  • Resources
  • Prompts

Tools

Modelin çalıştırabileceği işlemler. Örneğin:

search_issues
get_issue
create_issue
send_email

Resources

Modelin okuyabileceği veriler. Örneğin:

log://production/errors
docs://architecture/payment-service

Prompts

Belirli görevler için yeniden kullanılabilir prompt tanımları. Pratikte benim en ilginç bulduğum bölüm ise Tools tarafı. Çünkü burada API'den farklı bir abstraction oluşuyor.

API "Nasıl", MCP "Ne Yapabilirsin?" Diyor

Bir REST API bana şöyle bir yapı sunabilir:

POST /api/orders

Request body:

{
  "customerId": 42,
  "productId": 18,
  "quantity": 2
}

MCP tarafında aynı operasyon modele şöyle sunulabilir:

create_order

Tool açıklaması da kabaca şöyle olabilir:

Creates an order for a customer.

Model artık endpoint'in URL'ini, HTTP methodunu veya hangi header'ın gönderileceğini bilmek zorunda değil. Onun açısından sistemde bir yetenek var:

create_order

Burada MCP'nin API'den farklılaştığı nokta HTTP kullanıp kullanmaması değil. Asıl fark abstraction seviyesinde. Arka planda MCP server'ın kendisi mevcut REST API'yi çağırıyor olabilir.

LLM
 ↓
MCP Client
 ↓
MCP Server
 ↓
REST API
 ↓
Application Layer
 ↓
Database

Bu nedenle MCP'yi REST API'nin yerine gelen yeni bir teknoloji gibi görmek bana çok doğru gelmiyor. Daha çok mevcut sistemlerin üzerine eklenen, AI tarafına özel bir entegrasyon katmanı gibi düşünüyorum.

Asıl Fark: Tool Discovery

Bence MCP'nin en güçlü taraflarından biri discovery mekanizması. Klasik uygulamada hangi servislerin kullanılacağı önceden bellidir. Örneğin kodda şöyle bir satır varsa:

await githubService.CreateIssueAsync(...);

GitHub üzerinde issue oluşturacağımız compile-time sırasında zaten belirlenmiştir. Agent tarafında ise model mevcut araçları çalışma anında görebilir. Örneğin sistem şu tool'ları sunsun:

search_logs
query_database
search_issues
create_issue
send_email

Model kullanıcıdan gelen isteğe göre bu araçları birleştirebilir. Örneğin:

search_logs
      ↓
search_issues
      ↓
create_issue
      ↓
send_email

Buradaki önemli nokta şu: Biz bu workflow'u birebir kodlamadık. Biz sisteme yetenekleri sunduk. Workflow, göreve göre model tarafından oluşturuldu. Klasik uygulamalar ile AI agent mimarileri arasındaki en belirgin farklardan biri de bence bu.

Gerçek Bir Senaryo Üzerinden Bakalım

Şirket içinde kullanılan bir AI assistant geliştirdiğimizi düşünelim. Kullanıcı şu komutu versin:

Dün gece payment servisinde oluşan hataları incele. Aynı hata için daha önce açılmış ticket varsa göster, yoksa yeni ticket oluştur.

Sistemde üç MCP server olsun:

Logging MCP
Jira MCP
Database MCP

Logging MCP:

search_logs
get_log_details

Jira MCP:

search_issues
create_issue

Database MCP:

get_transaction
get_payment_details

Model önce:

search_logs

tool'unu kullanabilir. Log içinde bir transaction id görürse:

get_transaction

çağırabilir. Sonrasında hata mesajına göre:

search_issues

çalıştırabilir. Daha önce ticket açılmadığını görürse:

create_issue

ile yeni kayıt oluşturabilir. Burada modele özel olarak:

Önce log ara, sonra transaction kontrol et, sonra Jira'ya git.

demedik. Biz yalnızca kullanabileceği araçları sunduk. Agent yaklaşımının gücü de burada ortaya çıkıyor.

O Zaman Bütün API'leri MCP'ye Çevirelim mi?

Bence hayır. Hatta böyle bir yaklaşım gereksiz yere sistemi karmaşık hale getirebilir. Örneğin elimizde klasik bir order-payment akışı olsun:

Order Service
    ↓
Payment Service

Order Service bir sipariş oluştuğunda doğrudan payment servisini çağırıyor. Burada davranış zaten belli.

await paymentService.ChargeAsync(order);

Bu operasyon için araya LLM koymanın veya MCP tool discovery yaptırmanın pek bir anlamı yok. Çünkü karar verilmesi gereken bir durum yok. İşlem deterministik. Ben bu ayrımı kendi kafamda oldukça basit tutuyorum: Davranış önceden belliyse klasik API yaklaşımı yeterli. Davranış çalışma anında modele göre şekilleniyorsa MCP değerlendirilebilir. Elbette bu kesin bir kural değil ama mimari karar verirken iyi bir başlangıç noktası.

MCP Server'ın Arkasında Yine API Olabilir

Bence MCP konusunda en sık yanlış anlaşılan noktalardan biri de bu. MCP kullanmaya başladığımızda mevcut backend'i yeniden yazmamız gerekmiyor. Örneğin elimizde şu endpoint'ler olsun:

GET /api/customers/{id}
POST /api/customers/{id}/block
GET /api/customers/{id}/orders

MCP tarafında bunları şöyle expose edebiliriz:

get_customer
block_customer
get_customer_orders

MCP server içeride mevcut API'yi çağırabilir.

AI Agent
     ↓
MCP Server
     ↓
Existing REST API
     ↓
Application Layer

Benim tercih edeceğim yaklaşım da büyük ihtimalle bu olurdu. Çünkü business logic'in iki farklı yerde yaşamasını istemem. Domain logic application layer içerisinde kalır. REST API bunu web veya mobil uygulamalara sunar. MCP server ise aynı capability'leri AI agent'lara sunar. Böylece tek bir domain katmanını farklı tüketicilere açmış oluruz.

Tool Design Yeni Bir API Design Problemi Olabilir

API geliştirirken yıllardır belirli konuları tartışıyoruz:

  • Endpoint isimlendirme
  • Versioning
  • Pagination
  • Authentication
  • Authorization
  • Idempotency
  • Error handling
  • Rate limiting

MCP ile birlikte buna yeni bir başlık ekleniyor: Tool Design. Modelin kullanacağı tool'ların isimleri ve açıklamaları oldukça önemli hale geliyor. Örneğin:

execute

çok kötü bir tool ismi. Benzer şekilde:

process_data

da model açısından fazla belirsiz. Buna karşılık:

search_customer_orders

çok daha açık. Description tarafında da aynı durum geçerli. Şu açıklama:

Gets data.

neredeyse hiçbir şey anlatmıyor. Ama şöyle bir açıklama çok daha kullanışlı:

Returns the customer's orders created within the specified date range.
Use this tool when order history is required.

Burada description artık yalnızca dokümantasyon değil. Modelin tool'u doğru zamanda seçebilmesi için kullanılan bir metadata haline geliyor. Bu yüzden önümüzdeki dönemde API Design kadar Tool Design konusunun da konuşulacağını düşünüyorum.

Güvenlik Tarafı Daha Kritik Hale Geliyor

MCP tarafında en dikkat edilmesi gereken konulardan biri güvenlik. Sistemde şu tool'ların olduğunu düşünelim:

get_customer
delete_customer
refund_payment
send_email
execute_sql

Bir modele bunların tamamını kontrolsüz şekilde sunmak ciddi risk oluşturabilir. Özellikle destructive operasyonlarda mutlaka authorization ve approval mekanizmaları düşünülmeli. Ben ayrıca mümkün olduğunca düşük seviyeli tool'lardan kaçınmayı tercih ederim. Örneğin:

execute_sql

yerine:

get_customer_statistics

sunmak çok daha kontrollü bir yaklaşım. Çünkü modelin ihtiyacı SQL çalıştırmak değil. Modelin ihtiyacı müşteri istatistiklerini almak. Bu ayrım küçük görünse de güvenlik açısından ciddi fark yaratıyor.

MCP Stateful mı, Stateless mı?

MCP ile ilgili bazı içeriklerde şöyle bir karşılaştırma görüyorum:

REST = Stateless
MCP = Stateful

Bu ayrım bana fazla kesin geliyor. MCP kullanılan transport ve implementasyona göre stateful veya stateless davranabilecek şekilde tasarlanabilir. Bazı senaryolarda session bilgisi tutulabilir. Bazılarında ise her istek bağımsız şekilde işlenebilir. Dolayısıyla MCP'nin doğrudan stateful bir protokol olduğunu söylemek yerine, session yönetimini destekleyen daha esnek bir yapı olduğunu söylemek daha doğru olur. Özellikle production ortamında yüksek trafikli MCP server'lar geliştirilecekse bu mimari kararın dikkatli verilmesi gerekir.

.NET Tarafında MCP Nasıl Konumlanabilir?

.NET geliştiricisi açısından baktığımda en mantıklı yapı mevcut application layer'ı koruyup farklı adapter'lar üzerinden dış dünyaya açmak. Örneğin:

              Web / Mobile
                   ↓
               REST API
                   ↓
            Application Layer
                   ↑
              MCP Server
                   ↑
               AI Agent

Business logic yine aynı yerde duruyor. REST API klasik uygulamaları besliyor. MCP server ise AI agent'ların aynı capability'lere erişmesini sağlıyor. Bence özellikle Clean Architecture veya benzeri katmanlı yapılarda bu yaklaşım oldukça doğal. MCP server'ı yeni bir business layer gibi değil, yeni bir interface veya adapter olarak düşünmek daha doğru geliyor.

MCP mi API mi?

Ben bu soruyu artık biraz farklı soruyorum: Sistemin tüketicisi kim? Eğer tüketici başka bir servis ise:

Service A → Service B

REST, gRPC veya ihtiyaç varsa GraphQL kullanmak gayet mantıklı. Eğer tüketici çalışma anında karar veren bir AI agent ise:

AI Agent → Tools

MCP çok daha anlamlı hale geliyor. Gerçek sistemlerde ise büyük ihtimalle cevap çoğu zaman şu olacak: İkisi de. Çünkü web uygulamaları API kullanmaya devam edecek. Mobil uygulamalar API kullanmaya devam edecek. Mikroservisler kendi aralarında yine REST veya gRPC ile haberleşecek. AI agent'lar ise aynı sistemde MCP üzerinden capability'leri kullanabilecek.

Sonuç

MCP'yi ilk gördüğümde benim de aklımdaki soru oldukça basitti:

Zaten API'lerimiz var. Yeni bir protokole gerçekten ihtiyaç var mı?

Biraz daha inceleyince aslında MCP'nin farklı bir problemi çözmeye çalıştığı daha net görülüyor. API'ler yazılımlar arasındaki iletişim problemini uzun zamandır gayet iyi çözüyor. MCP ise yapay zeka modellerinin bir sistemde hangi yeteneklerin bulunduğunu keşfetmesini ve bu yetenekleri standart bir şekilde kullanmasını kolaylaştırıyor. Bu yüzden benim için konu artık:

MCP vs API

değil. Daha çok:

API → Software Integration
MCP → AI Tool Integration

şeklinde. Bence önümüzdeki dönemde backend geliştiriciler olarak asıl tartışacağımız konu API'lerin ortadan kalkıp kalkmayacağı olmayacak. Asıl konu, yıllardır geliştirdiğimiz servisleri ve domain capability'lerini AI agent'ların güvenli, kontrollü ve anlaşılır şekilde kullanabileceği yapılara nasıl dönüştüreceğimiz olacak.

Bu yazıyı AI ile tartış

Yazıdaki yaklaşımı kendi bağlamınla sınamak, örnek istemek veya karşı görüş üretmek için bir sohbet başlat.

Bu konudaki uygulama desteği için AI entegrasyonu ve otomasyon hizmetini inceleyin ya da diğer notlara devam edin.