MCP server nedir, ne zaman gerçekten gerekir?
MCP (Model Context Protocol) server, bir yapay zekâ ajanının dış araç ve verilere standart bir arayüzle erişmesini sağlayan küçük bir sunucudur. Gerçekten gerekli olduğu durum bellidir: aynı aracı birden fazla oturumda veya ajanda tekrar kullanacaksanız. Tek seferlik iş için bir betik yeter. Yazı karar kuralını, TypeScript ile en küçük çalışan örneği ve güvenlik sınırlarını verir.
MCP server nedir?
Model Context Protocol (MCP), Anthropic tarafından açık standart olarak geliştirilen ve yapay zekâ modellerinin dış dünyadaki veri kaynakları ve araçlarla konuşmasını sağlayan iki yönlü bir protokoldür. Bir LLM tek başına yalnızca eğitildiği veriyi bilir; yerel dosya sisteminizdeki özel bir veritabanına, şirket içi bir REST API’ye veya harici bir servis sağlayıcıya doğrudan erişemez. Geleneksel yöntemde her model veya her platform için ayrı fonksiyon çağrısı (function calling) şablonları yazmak gerekirdi. MCP bu dağınıklığı ortadan kaldırarak USB benzeri evrensel bir bağlantı standardı sunar.
MCP’yi ilk incelediğimde gördüğüm şey, yazılım mühendisliğinde on yıllardır çözmeye çalıştığımız “standart arayüz (interface) ayrımı” prensibinin nihayet AI ajan dünyasına uyarlanmış olmasıydı.
Bir MCP mimarisinde üç temel aktör bulunur:
- Host (Ev Sahibi Uygulama): Claude Desktop, Claude Code gibi kullanıcının doğrudan etkileşim kurduğu istemci ortamı.
- Client (İstemci): Host içinde çalışan ve MCP protokolünü yürüten ara katman.
- Server (Sunucu): Dış veriyi veya aracı standart bir şemayla (JSON-RPC 2.0 üzerinden) dışa açan bağımsız, hafif bir süreç (process).
MCP sunucusu arka planda standart girdi/çıktı (stdio) veya Streamable HTTP üzerinden istemciyle haberleşir (eski HTTP+SSE taşıması kullanımdan kaldırıldı). Ajan çalışmaya başladığında sunucuya “Hangi araçlara ve verilere sahipsin?” diye sorar. Sunucu da JSON şemasıyla parametreleri tanımlanmış araç listesini döner. Böylece ajan, aracı nasıl çağıracağını ve hangi girdileri vermesi gerektiğini anında anlar.
Ne zaman MCP, ne zaman betik?
Geliştiricilerin en sık düştüğü yanılgılardan biri, her dış işlem için hemen bir MCP sunucusu yazmaya kalkışmaktır. Oysa bir MCP sunucusu geliştirmek; JSON-RPC protokol yönetimini, tip tanımlarını, hata yönetimini ve konfigürasyon bakımını beraberinde getirir. Tek seferlik bir veri dönüştürme işi veya tek bir projeye özel basit bir SQL sorgusu için MCP sunucusu kurmak gereksiz bir mühendislik yüküdür.
Doğru kararı vermek için aşağıdaki karşılaştırma tablosunu bir kontrol listesi olarak kullanabilirsiniz:
| Karar Kriteri | MCP Sunucusu | Yerel Betik (Script) |
|---|---|---|
| Kullanım Sıklığı | Birden fazla projede ve sürekli tekrarlanan işler | Tek seferlik ya da nadir çalıştırılan işlemler |
| İstemci Çeşitliliği | Hem Claude Desktop hem Claude Code gibi çoklu istemciler | Yalnızca o anki terminal oturumu |
| Araç Keşfi | Ajanın şemaya bakarak dinamik parametre üretmesi gerekir | Girdiler geliştirici tarafından elle verilir |
| Yetki ve Güvenlik | Katı sınırlandırılmış, okuma/yazma ayrımı yapılmış API’ler | Geliştiricinin kendi kabuk (shell) izinleri |
| Bakım Maliyeti | Bağımsız bir proje olarak sürümleme ve test gerektirir | Tek bir .py veya .ts dosyası olarak depoda kalır |
Eğer bir aracı sadece siz ve sadece o anki oturumda bir kez kullanacaksanız, basit bir kabuk betiği yazıp ajana çalıştırmasını söylemek en hızlısıdır. Ancak aracı farklı oturumlarda, farklı projelerde veya AI ajan iş akışı nasıl kurulur yazımda anlattığım döngüsel süreçlerde standart bir parça olarak çağıracaksanız, MCP sunucusu kaçınılmazdır.
En küçük çalışan MCP sunucusu neye benzer?
Bir MCP sunucusu yazmak gözünüzü korkutmasın. Resmi TypeScript SDK’sı (@modelcontextprotocol/sdk) sayesinde standart girdi/çıktı (stdio) üzerinden çalışan minimal bir sunucuyu birkaç satırda ayağa kaldırabilirsiniz.
Aşağıdaki örnek, yerel bir not defterine tarihli not ekleyen ve son notları listeleyen çalışan, minimal bir TypeScript MCP sunucusudur:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
// Basit bellek içi veri deposu
const notes: Array<{ timestamp: string; text: string }> = [];
const server = new Server(
{ name: "not-sunucusu", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
// 1. Ajanın keşfedeceği araçları listele
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "not_ekle",
description: "Zaman damgasıyla birlikte yeni bir not kaydeder.",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "Kaydedilecek not metni" },
},
required: ["text"],
},
},
{
name: "notlari_listele",
description: "Kaydedilmiş tüm notları kronolojik olarak döner.",
inputSchema: { type: "object", properties: {} },
},
],
};
});
// 2. Araç çağrısını işlet
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "not_ekle") {
const text = String(request.params.arguments?.text ?? "");
const entry = { timestamp: new Date().toISOString(), text };
notes.push(entry);
return {
content: [{ type: "text", text: `Not eklendi (${entry.timestamp})` }],
};
}
if (request.params.name === "notlari_listele") {
const output = notes.map((n) => `[${n.timestamp}] ${n.text}`).join("\n");
return {
content: [{ type: "text", text: output || "Henüz kaydedilmiş not yok." }],
};
}
throw new Error(`Bilinmeyen araç: ${request.params.name}`);
});
// 3. Stdio üzerinden istemciye bağlan
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
(Not: TradingView MCP’nin kurulumu ve sınırları için TradingView MCP ile Claude Code yazısına bakın.)
Claude Code bir MCP sunucusunu nasıl kullanır?
Claude Code, terminal tabanlı bir ajan olduğu için yerel veya uzak MCP sunucularını doğrudan yapılandırma dosyası üzerinden tanır. Claude Code ile ilk projeni kur adımlarını tamamladıktan sonra projenizin kök dizinine .mcp.json (proje kapsamı) koyabilir ya da claude mcp add komutuyla kullanıcı kapsamına (~/.claude.json) ekleyebilirsiniz.
Örnek bir Claude Code MCP konfigürasyonu şöyledir:
{
"mcpServers": {
"notlar": {
"command": "node",
"args": ["/Users/hasancelik/Workspace/Projects/mcp-notes/dist/index.js"],
"env": {
"NODE_ENV": "production"
}
}
}
}
Claude Code oturumu açıldığında arka planda node sürecini başlatır, stdio kanalı üzerinden el sıkışır ve not_ekle ile notlari_listele araçlarını ajan bağlamına enjekte eder. Siz terminalde “Bugün yaptığımız mimari değişiklikleri özetleyip notlara ekle” dediğinizde, model uygun parametrelerle bu aracı çalıştırır ve sonucu terminalinize basar.
Aynı stdio yapısıyla Python’da yazdığım youtube-mcp sunucusunun on dört aracı, yetki sınırları ve kota kararları YouTube MCP vakasında anlatılıyor.
Hangi araçlar ajana verilmemeli?
Bir ajana terminal ve araç yetkisi verirken benim benimsediğim temel ilke “en az yetki” (principle of least privilege) kuralıdır. Ajana yapamayacağı işlerin araçlarını vermek yalnızca hata riskini artırmaz, aynı zamanda güvenlik açığı oluşturur.
Şu araçlar kesinlikle ajanın doğrudan erişimine açılmamalıdır:
- Çekim (Withdrawal) yetkisi olan finansal API’ler: Bir borsaya veya ödeme sistemine bağlanan MCP sunucusunda transfer, para çekme ya da kredi kartı harcama yetkileri asla tanımlanmamalıdır.
- Geri alınamaz yıkıcı komutlar: Veritabanını tamamen silen (
DROP DATABASE), prodüksiyon sunucusunu kapatan veya git geçmişini zorla ezen (git push --force) araçlar ajana verilmez. - Filtresiz sistem kabuğu (arbitrary bash): Modele her türlü sistem komutunu çalıştırma yetkisi vermek yerine, yalnızca izin verilmiş belirli komutları çalıştıran kontrollü wrapper araçlar sunulmalıdır.
- Korumasız gizli anahtarlar: Ortam değişkenlerindeki hassas parolaları düz metin olarak okuyup ekrana basabilecek araçlar güvenlik riski taşır.
Yazılım & AI dünyasında güvenliğin temeli, yapay zekâya körü körüne güvenmek değil, sistem mimarisini hata yapamayacak şekilde sınırlandırmaktır. Bir aracın yapabileceği en kötü senaryoyu düşünün; eğer bu senaryo telafi edilemez bir zarar doğuruyorsa, o araç bir MCP fonksiyonu olmamalıdır.
Kaynaklar
- Model Context Protocol Resmi Dokümantasyonu, “Introduction to MCP”: https://modelcontextprotocol.io/introduction (erişim: 2026-09-28)
- Model Context Protocol Geliştirici Kılavuzu, “Build an MCP Server”: https://modelcontextprotocol.io/docs/develop/build-server (erişim: 2026-09-28)
- Anthropic Claude Code Dokümantasyonu, “Using MCP with Claude Code”: https://docs.anthropic.com/en/docs/claude-code/mcp (erişim: 2026-09-28)
Anahtar çıkarımlar
- MCP, aracı ajandan bağımsız yeniden kullanılabilir yapar.
- Tek seferlik iş için MCP değil betik yazılır.
- Ajana verilen her araç bir yetki kararıdır; en az yetki.
Sık sorulan sorular
MCP ile API arasındaki fark nedir?
API bir servisin arayüzüdür; MCP, ajanın herhangi bir API'yi aynı biçimde keşfedip çağırmasını sağlayan protokoldür. MCP sunucusu çoğu zaman bir API'yi sarar; değer, aracı tanımlayan şemanın ajana anlaşılır olmasından gelir.
Hasan Çelik