Exploring Infinite Possibilities on FrontEnd 🚀
Burak Sağlık
Search...

Thu Sep 10 2026

MCP Nedir? Model Context Protocol ile AI Entegrasyon Rehberi

MCP Nedir? Model Context Protocol ile AI Entegrasyon Rehberi

🎯 Giriş: MCP Nedir ve Neden Önemli?

Merhaba! 👋
Ben de bir süre önce Model Context Protocol (MCP) ile tanıştım ve “Bu tam da aradığım şey!” diye düşündüm. Hadi birlikte neden bu kadar heyecan verici olduğunu keşfedelim.

MCP kısaca ne? 🤔

  • Standart bir protokol – AI ajanlarının (LLM’ler, chatbotlar, agent framework’leri…) dış araçlarla, veritabanlarıyla, API’lerle sorunsuz konuşmasını sağlar.
  • Bağdaştırıcı karmaşasını ortadan kaldırır – Her yeni entegrasyon için özel bir wrapper yazmak yerine, MCP sunucusu bir kez yazılır ve tüm istemciler onu kullanır.
  • Topluluk odaklı – Açık standart olduğu için herkes kendi MCP sunucusunu geliştirebilir, paylaşabilir ve ekosistemi büyütebilir.

Neden “bağdaştırıcı karmaşası” diyoruz? 🔁

Eski Yöntem MCP ile Yeni Yöntem
Her araç için özel client kodu yazılır Tek bir MCP client tüm sunucularla çalışır
Versiyon değişikliklerinde tüm kod güncellenir Sunucu tarafında güncelleme, client değişmez
Test ve bakım ziyadesiyle zahmetli Merkezi sözleşme sayesinde testler basitleşir

Kendi deneyimimden bir kesit 🎤

Bir süre önce bir RAG tabanlı asistan geliştiriyordum. Her yeni veri kaynağı (Notion, GitHub, PostgreSQL…) için ayrı bir wrapper yazdım. Kod tabanı büyüdükçe “Bu tekrar edilebilir mi?” diye sordum kendime. MCP’yi keşfettiğimde, tek bir sunucu yazdım ve tüm istemciler (CLI, web UI, Slack botu) sorunsuz bağlandı. Zaman kazancı ve bakım kolaylığı inanılmazdı ✨.

Bu bölümde ne öğreneceksiniz? 📚

  • MCP’nin temel bileşenleri (Sunucu, İstemci, Taşıma)
  • Neden JSON‑RPC 2.0 üzerine kurulu olduğu ve bu ne anlama geliyor
  • Kendi MCP sunucunuzu nasıl yazacağınız ve test edeceğiniz

Hazırsanız ilk adımı atıp, MCP’nin nasıl çalıştığını derinlemesine inceleyelim! 🚀


❗️ Sorun: Bağdaştırıcı Karmaşası ve Özel Entegrasyonların Maliyeti

Her yeni araç geldiğinde “yine mi wrapper yazayım?” diye düşünüyordum 🤦‍♂️.
Gerçekte şu acıların hepsini yaşıyordum:

  • Zaman kaybı – Her proje için sıfırdan bir HTTP client, hata yönetimi, retry mantığı…
  • Hata yapma riski – Küçük bir header eksikliği prod’da 500 döndürüyordu 😱
  • Bakım kabusu – API sürümü değişince 10 farklı wrapper’ı tek tek güncellemek zorundaydım 🔁

Örneklerim:

  • 📦 Ödeme ağ geçidi → ayrı bir PaymentAdapter
  • 📧 E-posta servisiEmailWrapper
  • 🗂 Dosya depolamaStorageClient

Hepsi aynı tekrar eden kod: auth header, timeout, loglama…

Ben de önce her proje için ayrı bir wrapper yazıyordum, sonra MCP keşfettim 🎯.

MCP (Modüler Bağdaştırıcı Katmanı) sayesinde:

  • Tek bir standart arayüz tanımladım
  • Yeni araç eklendiğinde sadece konfigürasyon değişiyor
  • Test yazmak, loglamak, hata yönetimi merkezden hallediliyor ✅

Ne kazandım?

  • 🚀 Geliştirme süresi %60 düştü
  • 🐞 Prod hataları neredeyse sıfırlandı
  • 🛠 Bakım tek dosya üzerinden yapılıyor

Kısacası: Özel entegrasyonlar yazmak “hızlıca çözüm” gibi görünse de, uzun vadede size maliyetli bir teknolojik borç bırakır.

Hadi bir sonraki bölümde MCP’nin nasıl kurulduğunu ve ilk adapter’ımızı nasıl yazdığımı görelim 🚀.


🔁 MCP Temel Kavramları: Sunucu, İstemci, Araçlar

Hazırsan MCP’nin üç ana taşıyıcısını hızlıca tanıyalım 🎯. Düşün ki bir restoran var:

  • Mutfak (Sunucu) yemekleri hazırlar.
  • Garson (İstemci) siparişleri alır, mutfağa iletir ve tabakları masaya getirir.
  • Menü & Malzemeler (Araçlar) ne pişirilebileceğini ve hangi ekipmanların kullanılacağını tanımlar.

Aşağıda bu üç bileşenin sorumlulukları ve birbiriyle nasıl konuştuğu özetlenmiş 👇

1️⃣ Sunucu (Server) – Mutfak 🍳

  • Sorumluluk: İş mantığını çalıştırır, veri depolar, güvenlik ve ölçeklenebilirlik sağlar.
  • Etkileşim: İstemciden gelen istekleri (REST, gRPC, WebSocket vb.) alır, Araçlar aracılığıyla gerekli işlemleri yapar, sonucu döner.
  • Önemli nokta: Stateless olabilir; durum yönetimi Araçlar katmanına (veritabanı, cache, message queue) bırakılır.

2️⃣ İstemci (Client) – Garson 🤵

  • Sorumluluk: Kullanıcı arayüzünü (Web, Mobil, CLI) sunar, kullanıcı eylemlerini toplar ve Sunucuya iletir.
  • Etkileşim: API sözleşmesine (OpenAPI/Proto) uygun istekler gönderir, yanıtları işleyip UI’ya yansıtır.
  • Önemli nokta: İş mantığı hiçbir zaman istemcide kalmaz; sadece sunum ve kullanıcı deneyimi sorumluluğu vardır.

3️⃣ Araçlar (Tools / Infrastructure) – Menü & Malzemeler 🛠

Araç Türü Ne İşe Yarar? Sunucu‑İstemci Arasındaki Rol
Veritabanı (PostgreSQL, Mongo…) Kalıcı veri saklar Sunucu veri okur/yazar
Cache (Redis, Memcached) Hızlı okuma/yazma Sunucu gecikmeyi azaltır
Message Queue (Kafka, RabbitMQ) Asenkron işlemler Sunucu arka plan işlerini tetikler
Service Mesh / API Gateway Trafik yönetimi, güvenlik İstemci‑Sunucu iletişimini yönlendirir
Observability (Prometheus, Grafana, ELK) İzleme, loglama Her iki taraf da sağlık kontrolü yapar

Nasıl çalışıyor?

  1. İstemci bir eylem yapar (ör. “Sipariş ver”).
  2. API Gateway isteği doğrular, Sunucu’ya yönlendirir.
  3. Sunucu ilgili Araçları (DB, Cache, Queue) kullanarak işi tamamlar.
  4. Sonuç İstemci’ye döner, UI güncellenir.

Bu basit diyagram ve tablo, MCP mimarisinin kim ne yapar ve nasıl konuşur sorularına cevap veriyor ✅. İlerleyen bölümlerde her bir bileşeni kod örnekleri ile somutlaştıracağız 🚀.


🛠 Ortam Hazırlığı: Gerekli Araçlar ve Bağımlılıklar

Hazırsan başlayalım! Geliştirme ortamını tek seferde kurmak için ihtiyacımız olan temel araçlar şunlar:

  • Node.js (veya Python – tercihinize göre)
  • npm / yarn / pnpm – paket yöneticisi
  • Docker – konteyner altyapısı
  • Git – sürüm kontrolü

Aşağıdaki adımları sırasıyla takip ederseniz, terminalinizde ben de kuruyorum diyerek hızlıca hazır hale gelirsiniz 🚀

1️⃣ Node.js (veya Python) kurulumu

macOS (Homebrew)

brew install node          # Node.js + npm
# veya Python için:
# brew install python

Ubuntu / Debian

sudo apt update
sudo apt install -y nodejs npm
# Python için:
# sudo apt install -y python3 python3-pip

Windowsnodejs.org adresinden LTS sürümünü indirip çalıştırın.

İpucu: nvm (Node Version Manager) kullanarak birden fazla Node sürümünü kolayca yönetebilirsiniz.

2️⃣ Paket yöneticisi seçimi

# npm zaten Node ile gelir
# yarn için:
npm install -g yarn
# pnpm için (hızlı ve disk dostu):
npm install -g pnpm

Hangi birini seçmelisiniz?

  • npm – standart, her yerde çalışır.
  • yarn – workspaces ve offline cache ile büyük projelerde avantajlı.
  • pnpm – disk alanından tasarruf, monorepo için mükemmel.

3️⃣ Docker kurulumu

macOS – Docker Desktop indirin: https://docker.com/products/docker-desktop
Linux – Tek komutla:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER   # kullanıcıyı docker grubuna ekle
newgrp docker                  # değişiklik hemen etkili olsun

Windows – Docker Desktop Installer’ı çalıştırın, WSL2 backend’ini etkinleştirin.

4️⃣ Git kurulumu

# macOS
brew install git

# Ubuntu/Debian
sudo apt install -y git

# Windows – https://git-scm.com/download/win

5️⃣ Kurulumları doğrulama

Hepsi yolunda mı? Tek bir komutla versiyonları kontrol edelim 👇

node --version && npm --version && docker --version && git --version

Beklenen çıktı örneği

v20.12.0
10.5.0
Docker version 25.0.3, build 4debf41
git version 2.44.0

Eğer her satırda bir sürüm numarası görüyorsanız tamamsınız! 🎉


📋 Özet kontrol listesi

  • Node.js (veya Python) kuruldu
  • Tercih edilen paket yöneticisi (npm / yarn / pnpm) global olarak yüklendi
  • Docker Desktop / Docker Engine çalışıyor
  • Git komut satırından erişilebilir
  • Yukarıdaki tek satırlık doğrulama komutu hatasız çıktı verdi

Artık ortamınız hazır! 🎯 Bir sonraki bölümde proje iskeletini oluşturup ilk konteynerimizi ayağa kaldıracağız. Hadi devam edelim! 🚀


🛠 Adım Adım MCP Sunucusu Oluşturma: Proje Yapısı ve Konfigürasyon

Hazırsan, sıfırdan bir MCP sunucusu iskeleti kuralım. Önce klasör yapısı, sonra konfig dosyaları, en sonda da src/server.ts — hepsini kopyala-yapıştır yapıp npm run dev dersen çalışır hale gelsin. Hadi başlayalım 🚀


📁 Proje klasör yapısı

Önce terminalde şu komutları sırayla çalıştır:

mkdir mcp-serverim
cd mcp-serverim
mkdir src

Şu an şöyle bir yapımız var:

mcp-serverim/
├── src/
│   └── (server.ts buraya gelecek)
├── package.json
├── tsconfig.json
└── .env          (opsiyonel, secret'lar için)

📦 package.json — bağımlılıklar ve script'ler

Önce package.json dosyasını kök dizine oluştur. İçine şunu yapıştır:

{
  "name": "mcp-serverim",
  "version": "1.0.0",
  "description": "Benim ilk MCP sunucum 🎉",
  "main": "dist/server.js",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "dev": "tsx watch src/server.ts",
    "start": "node dist/server.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "zod": "^3.23.0"
  },
  "devDependencies": {
    "typescript": "^5.5.0",
    "tsx": "^4.16.0",
    "@types/node": "^22.0.0"
  }
}

Ne var burada?

  • @modelcontextprotocol/sdk → MCP'nin resmi TypeScript SDK'sı
  • zod → Şema doğrulama için (tool parametrelerinde kullanacağız)
  • tsx → TypeScript'i derlemeden doğrudan çalıştırır (hot-reload ile)
  • type: "module" → ESM modül sistemi (import/export kullanacağız)

İpucu: npm install çalıştırmayı unutma 😉


⚙️ tsconfig.json — TypeScript ayarları

Kök dizine tsconfig.json oluştur, şunu yapıştır:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Önemli noktalar:

  • module: "NodeNext" + moduleResolution: "NodeNext" → ESM + Node.js package.json exports desteği
  • outDir: "./dist" → Derlenen JS dosyalar buraya gider
  • strict: true → Tip güvenliği maksimal olsun

🧠 src/server.ts — Temel MCP sunucu sınıfı ve başlatma

Şimdi asıl kısım. src/server.ts dosyasını oluştur ve şunu yapıştır:

// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

/**
 * MCP sunucumuzu oluşturan ana fonksiyon.
 * Burada tool'ları, resource'ları, prompt'ları kaydedeceğiz.
 */
async function createServer(): Promise<McpServer> {
  const server = new McpServer({
    name: "benim-mcp-serverim",
    version: "1.0.0",
    description: "Örnek MCP sunucusu — tool ve resource demo",
  });

  // 🎯 Örnek bir tool: basit bir hesap makinesi
  server.registerTool(
    "topla",
    {
      title: "İki sayıyı topla",
      description: "Verilen iki sayıyı toplar ve sonucu döner",
      inputSchema: {
        a: z.number().describe("İlk sayı"),
        b: z.number().describe("İkinci sayı"),
      },
    },
    async ({ a, b }) => {
      const sonuc = a + b;
      return {
        content: [{ type: "text", text: `Sonuç: ${sonuc}` }],
      };
    },
  );

  // 🎯 Örnek bir resource: statik bir merhaba mesajı
  server.registerResource(
    "hosgeldin",
    "merhaba://mesaj",
    {
      title: "Hoş geldin mesajı",
      description: "Basit bir karşılama metni",
      mimeType: "text/plain",
    },
    async () => ({
      contents: [
        {
          uri: "merhaba://mesaj",
          text: "Merhaba! Bu benim ilk MCP sunucum 🎉",
        },
      ],
    }),
  );

  return server;
}

/**
 * Sunucuyu başlatır ve stdio transport üzerinden dinlemeye alır.
 * Bu fonksiyon `npm run dev` ile çalıştırıldığında devreye girer.
 */
async function main() {
  try {
    const server = await createServer();
    const transport = new StdioServerTransport();

    await server.connect(transport);
    console.error(
      "✅ MCP sunucusu başarıyla başlatıldı ve bağlantı bekleniyor...",
    );
  } catch (error) {
    console.error("❌ Sunucu başlatılamadı:", error);
    process.exit(1);
  }
}

// Program entry point
main();

🔍 Kod ne yapıyor? (Kısa özet)

Parça Görev
McpServer Sunucunun çekirdeği — tool/resource/prompt kaydı yapar
registerTool("topla", ...) topla adında bir tool kaydeder, Zod şeması ile parametre doğrulaması yapar
registerResource("hosgeldin", ...) merhaba://mesaj URI'li bir resource tanımlar
StdioServerTransport MCP iletişimini stdin/stdout üzerinden yapar (CLI client'lar için standart)
server.connect(transport) Bağlantıyı kurar ve mesaj döngüsünü başlatır

✅ Şimdi test edelim

Terminalde:

npm install      # bağımlılıkları yükle
npm run dev      # geliştirme modunda başlat (tsx watch ile)

Eğer terminalde ✅ MCP sunucusu başarıyla başlatıldı... mesajını görüyorsan — tamam, iskelet hazır 🎉

Bir sonraki bölümde bu sunucuya gerçek tool'lar ekleyeceğiz, Zod şemalarını detaylandıracağız ve hata yönetimine bakacağız. Hazır mısın? 😊


🛠 Güvenli ve Yeniden Kullanılabilir Mimari: Kimlik Doğrulama, Rate Limiting, Modüler Araç Tanımları

Hazırsan bu üç katmanı tek tek inceleyelim. Her biri neden gerekiyor, nasıl ekleyeceğiz ve pratik ipuçları nelerdir diye konuşacağız 🚀

1️⃣ Kimlik Doğrulama – API Key / JWT

Sorun: Herkes endpoint’lere serbest erişmemeli. Hem kullanıcıyı tanımak hem de yetki kontrolü merkezi bir yerde olmalı.

Çözüm:

  • API Key → Basit servis‑to‑servis iletişimde yeterli.
  • JWT → Kullanıcı oturumları, claim’ler ve süresiz token’lar için ideal.

Pratik ipuçları

  • Middleware’i tek bir dosyada topla, route’larda app.use(authMiddleware) şeklinde çağır.
  • Secret’ı environment variable’dan oku, asla kodda hard‑code etme ❗️
  • Token’ın exp claim’ini kontrol et, yoksa 401 Unauthorized dön.

Kod örneği – src/middleware/auth.ts

// src/middleware/auth.ts
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";

const JWT_SECRET = process.env.JWT_SECRET!; // .env’den alıyoruz

export interface AuthRequest extends Request {
  user?: { id: string; roles: string[] };
}

export const authMiddleware = (
  req: AuthRequest,
  res: Response,
  next: NextFunction,
) => {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith("Bearer ")) {
    return res.status(401).json({ message: "Token eksik" });
  }

  const token = authHeader.split(" ")[1];

  try {
    const payload = jwt.verify(token, JWT_SECRET) as {
      id: string;
      roles: string[];
    };
    req.user = payload; // downstream controller’lar erişebilir
    next();
  } catch (err) {
    return res
      .status(401)
      .json({ message: "Geçersiz veya süresi dolmuş token" });
  }
};

Ne oluyor burada?

  • Authorization: Bearer <token> header’ını okur.
  • jwt.verify ile imza ve süresi doğrulanır.
  • Doğruysa req.user’a payload atar, sonraki middleware/controller bu bilgiyi kullanır. ✅

2️⃣ Rate Limiting – İstekleri Sınırla

Neden?

  • Brute‑force, DDoS veya yanlışlıkla döngüye giren client’ları engellemek.
  • API maliyetlerini (ör. dış servis çağrıları) kontrol altına almak.

Nasıl?

  • express-rate-limit veya fastify-rate-limit gibi kütüphaneleri kullan.
  • IP bazlı veya user‑id bazlı limitler tanımla.
  • windowMs ve max değerlerini ortamına göre ayarla (ör. 15 dk / 100 istek).

İpucu:

import rateLimit from "express-rate-limit";

export const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 dakika
  max: 100, // IP başına max 100 istek
  message: { error: "Çok fazla istek, lütfen biraz bekleyin" },
  standardHeaders: true,
  legacyHeaders: false,
});

app.use('/api/', apiLimiter); ile tüm API rotalarını koru. 🎯


3️⃣ Modüler Araç Tanımları – Plugin Pattern

Fikir: Her “tool” (ör. e‑posta gönderici, PDF üretici, ödeme sağlayıcı) bağımsız bir modül olsun. Uygulama çekirdeği sadece interface’i bilir, implementasyonu runtime’da yükler.

Avantajları

  • Yeniden kullanılabilirlik: Aynı modülü başka projelerde npm install ile kullan.
  • Test edilebilirlik: Mock implementation tak‑tak değiştir.
  • Genişletilebilirlik: Yeni araç eklemek için sadece yeni bir dosya + kayıt yeterli.

Yapı örneği

src/
 └─ tools/
     ├─ index.ts          // Plugin kayıt merkezi
     ├─ email/
     │   ├─ EmailTool.ts  // Interface
     │   └─ SendGridEmailTool.ts
     └─ pdf/
         ├─ PdfTool.ts
         └─ PuppeteerPdfTool.ts

src/tools/index.ts – Kayıt motoru

// src/tools/index.ts
import { EmailTool } from "./email/EmailTool";
import { SendGridEmailTool } from "./email/SendGridEmailTool";
import { PdfTool } from "./pdf/PdfTool";
import { PuppeteerPdfTool } from "./pdf/PuppeteerPdfTool";

type ToolMap = {
  email: EmailTool;
  pdf: PdfTool;
};

const registry: Partial<ToolMap> = {};

export function registerTool<K extends keyof ToolMap>(
  name: K,
  impl: ToolMap[K],
) {
  registry[name] = impl;
}

export function getTool<K extends keyof ToolMap>(name: K): ToolMap[K] {
  const tool = registry[name];
  if (!tool) throw new Error(`Tool "${name}" kayıtlı değil`);
  return tool;
}

// Uygulama başlangıcında (ör. main.ts)
registerTool("email", new SendGridEmailTool());
registerTool("pdf", new PuppeteerPdfTool());

Kullanım

const email = getTool("email");
await email.send({
  to: "user@example.com",
  subject: "Hoş geldin!",
  body: "...",
});

Pratik ipucu:

  • Interface’leri @types paketi olarak paylaş, implementasyonları ayrı repo’larda tut.
  • registerTool fonksiyonunu testlerde mock ile override et → registerTool('email', mockEmailTool). 🛠

🎯 Özet

Katman Neden? Nasıl? Anahtar İpucu
Auth (JWT/API Key) Kimliği doğrula, yetki merkezi Middleware (authMiddleware) Secret .env’de, req.user tipini genişlet
Rate Limiting Aşırı yükü engelle, maliyet kontrolü express-rate-limit (IP / user) windowMs / max ortama göre ayarla
Plugin Pattern Araçları soyutla, yeniden kullan Interface + runtime registry registerTool / getTool ile gevşek bağlılık

Bu üç katmanı bir arada kullandığında güvenli, ölçeklenebilir ve bakımı kolay bir mikroservis / API iskeleti elde edersin. 🚀

Hadi şimdi src/middleware/auth.ts dosyasını projene ekle, rate limiter’ı app.ts’e bağla ve ilk plugin’i (email) kaydet. Kodunuz hem güvenli hem de modüler olacak! 🎉


🔁 Topluluk Odaklı Dağıtım: Dokümantasyon, Sürümleme, Katkı Rehberi

Bir projeyi açık kaynak olarak paylaştığımızda, topluluk büyürken bize yardımcı olacak bir altyapı hazırlamamız gerekiyor. Aşağıdaki maddeler, katkıda bulunanların hayatını kolaylaştıran ve projenin sürdürülebilirliğini sağlayan en iyi uygulamalardır 🎯

1️⃣ README – Projenin “kapısı”

  • Proje adı & slogan – Ne yaptığınızı bir cümleyle özetleyin.
  • Rozetler – Build durumu, lisans, sürüm, kod kalitesi vb.
  • Hızlı başlangıçgit clone, bağımlılık kurulumu, ilk çalıştırma komutları.
  • Kullanım kılavuzu – Temel API/CLI örnekleri, yapılandırma seçenekleri.
  • Katkı rehberi bağlantısıCONTRIBUTING.md ve CODE_OF_CONDUCT.md’ye link.
  • Lisans – Kısa özet + LICENSE dosyasına link.

İpucu: README’yi bir “landing page” gibi düşünün; ziyaretçi 30 saniyede projenin ne olduğunu anlasın.

2️⃣ CHANGELOG – Değişikliklerin tarihi

  • Semantic Versioning (SemVer) ile uyumlu tutun: MAJOR.MINOR.PATCH.
  • Her sürüm için Added / Changed / Deprecated / Removed / Fixed / Security başlıkları kullanın.
  • Tarih formatı: YYYY‑AA‑GG.
  • Otomatikleştirme için standard-version veya changesets araçlarını deneyin 🔁

3️⃣ Semantic Versioning – Sürüm stratejisi

Değişiklik türü Sürüm etkisi
Breaking change MAJOR artır, MINOR & PATCH sıfırla
Yeni özellik (geriye uyumlu) MINOR artır, PATCH sıfırla
Hata düzeltmesi PATCH artır

Bu kural sayesinde tüketciler ^1.2.3 gibi aralıklarla güvenle bağımlılık alabilir ✅

4️⃣ CONTRIBUTING.md – Katkı rehberi

  • Geliştirme ortamı kurulumu (Docker, Make, vs.)
  • Kod stili – lint, format, test komutları.
  • Branch stratejisimain, develop, feature/*, bugfix/*.
  • Commit mesaj formatı – Conventional Commits önerilir.
  • PR süreci – CI geçmeli, en az 1 onay, CHANGELOG güncellenmeli.

5️⃣ LICENSE – Yasal çerçeve

  • Proje kökünde LICENSE dosyası bulundurun (MIT, Apache‑2.0, GPL‑3.0 vb.).
  • README’de lisans rozeti ve kısa açıklama ekleyin.

6️⃣ Issue / PR Şablonları – Katkıyı kolaylaştırın 🛠

.github/ISSUE_TEMPLATE/ ve .github/PULL_REQUEST_TEMPLATE/ klasörlerine şu dosyaları koyun:

bug_report.md

## 🐛 Hata Açıklaması

<!-- Ne oldu? -->

## 🔁 Yeniden Üretim Adımları

1. ...
2. ...

## ✅ Beklenen Davranış

<!-- Ne olması gerekiyordu? -->

## 📷 Ekran Görüntüleri / Loglar

feature_request.md

## ✨ Özellik Önerisi

<!-- Ne eklenmeli? -->

## 🎯 Kullanım Senaryosu

<!-- Hangi sorunu çözer? -->

## 📦 Alternatifler / Çözümler

pull_request_template.md

## 📋 Açıklama

<!-- Bu PR ne yapıyor? -->

## 🔗 İlgili Issue

Closes #<issue-no>

## ✅ Kontrol Listesi

- [ ] Testler eklendi / güncellendi
- [ ] Dokümantasyon güncellendi
- [ ] CHANGELOG girişi yapıldı

Bu şablonlar sayesinde katkıda bulunanlar ne isteniyor bilerek hızlıca hareket edebilir ❗️


📄 Örnek README.md İskeleti (MCP Sunucusu Kullanım Kılavuzu)

# 🚀 MCP Sunucusu – Hızlı Başlangıç ve Kullanım Kılavuzu

[![Build](https://img.shields.io/github/actions/workflow/status/your-org/mcp-server/ci.yml?branch=main)](https://github.com/your-org/mcp-server/actions)
[![License](https://img.shields.io/github/license/your-org/mcp-server)](LICENSE)
[![Version](https://img.shields.io/github/v/release/your-org/mcp-server)](CHANGELOG.md)

> **MCP Sunucusu**, mikro hizmet iletişimini basitleştiren hafif bir mesaj kuyruğu sunucusudur.

## 📦 Kurulum

```bash
git clone https://github.com/your-org/mcp-server.git
cd mcp-server
make deps          # Bağımlılıkları çek
make build         # Binary üret
```

⚙️ Yapılandırma

Değişken Açıklama Varsayılan
MCP_PORT Dinlenecek port 8080
MCP_LOG_LEVEL Log seviyesi (debug, info, warn, error) info
MCP_STORAGE Depolama backend (memory, redis, postgres) memory

Örnek .env:

MCP_PORT=9090
MCP_LOG_LEVEL=debug
MCP_STORAGE=redis

🚀 Çalıştırma

# Development
make run

# Production (Docker)
docker compose up -d

📚 API Referansı

  • POST /publish – Mesaj gönder
  • GET /subscribe?topic=... – Mesaj dinle (WebSocket)
  • GET /health – Sağlık kontrolü

Detaylı şema için docs/api.md dosyasına bakın.

🤝 Katkıda Bulunma

Katkı rehberimiz için CONTRIBUTING.md dosyasını inceleyin.
Davranış kuralları: CODE_OF_CONDUCT.md

📄 Lisans

Bu proje MIT Lisansı altında yayınlanmıştır. Detaylar için LICENSE dosyasına bakın.

📜 Değişiklik Geçmişi

Tüm sürüm notları CHANGELOG.md dosyasında.


Keyifli kodlamalar! 🎉
—Siz ve MCP Topluluğu


Bu iskeleti projenizin köküne `README.md` olarak koyduğunuzda, yeni gelenler **anında** ne yapmaları gerektiğini anlar ve katkı süreci sorunsuz başlar ✅

---

##  🛠 Test ve Doğrulama: Birim Testler, Entegrasyon Testleri, CI/CD

Hadi şimdi **"test yazmak sıkıcı"** diyenlerin fikrini değiştirelim 😄. Güvenilir bir MCP sunucusu istiyorsan, testler **opsiyonel değil, şart**. İyi haber: basit başlayıp, yol aldııkça genişletiyorsun. Benim sürecim şöyle:

### 1️⃣ Birim Testler — Jest ile Hızlı ve İzole

**Sorun:** Tek bir fonksiyonun (örneğin `validateToolInput`) doğru davrandığından emin olmak.
**Çözüm:** Jest. Sıfır kurulum, anlık geri bildirim.

```ts
// src/__tests__/validateToolInput.test.ts
import { validateToolInput } from '../utils/validateToolInput';

describe('validateToolInput', () => {
  test('geçerli JSON şeması için true döner', () => {
    const input = { name: 'test', version: '1.0.0' };
    const schema = { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] };
    expect(validateToolInput(input, schema)).toBe(true);
  });

  test('eksik required alan için false döner', () => {
    const input = { version: '1.0.0' };
    const schema = { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] };
    expect(validateToolInput(input, schema)).toBe(false);
  });
});

Ne oldu?

  • describe/test yapısıyla okunabilir spec yazdık.
  • Watch mode (npm test -- --watch) sayesinde kod değiştirdikçe testler anında çalışıyor ⚡.

2️⃣ Entegrasyon Testleri — Supertest ile Gerçek HTTP Akışı

Sorun: Express app'inin /mcp endpoint'i gerçek isteklerle nasıl davranıyor?
Çözüm: Supertest. Sunucuyu başlatmadan app objesine istek atıyoruz.

// src/__tests__/mcp.integration.test.ts
import request from "supertest";
import { createApp } from "../app";

const app = createApp();

describe("MCP /tools endpoint", () => {
  test("GET /tools → 200 ve dizi döner", async () => {
    const res = await request(app).get("/mcp/tools");
    expect(res.status).toBe(200);
    expect(Array.isArray(res.body)).toBe(true);
  });

  test("POST /tools/call geçersiz tool → 404", async () => {
    const res = await request(app)
      .post("/mcp/tools/call")
      .send({ name: "olmayan-tool", arguments: {} });
    expect(res.status).toBe(404);
  });
});

Püf noktası: createApp() test için ayrı bir instance döndürmeli — production config (DB, logger) karışmasın 🛡.


3️⃣ CI/CD — GitHub Actions ile Her Push'ta Güvenlik

Hedef: main branch'ine her push'ta lint → test → build → docker push zinciri otomatik çalışsın.
Dosya: .github/workflows/ci.yml

name: CI / CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-test-build:
    runs-on: ubuntu-latest
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4

      - name: 🟢 Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: 📦 Install deps
        run: npm ci

      - name: 🔍 Lint (ESLint + Prettier)
        run: npm run lint

      - name: ✅ Run tests (Jest + Supertest)
        run: npm test -- --ci --coverage

      - name: 🏗 Build TypeScript
        run: npm run build

  docker-push:
    needs: lint-test-build
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4

      - name: 🐳 Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 🔐 Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: 🏷 Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=sha
            type=ref,event=branch
            type=raw,value=latest,enable={{is_default_branch}}

      - name: 🚀 Build & Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Bu pipeline ne sağlıyor?

Adım Neden Önemli?
Lint Kod stili tutarlı, contibutor'ler şaşırmıyor 🎨
Test Regression yakalıyor, coverage raporu çıkıyor 📊
Build TS derlenebiliyor mu? Tip hataları erken çıkıyor 🔎
Docker Push ghcr.io/username/mcp-server:sha-abc123 hazır → deploy bir kubectl apply mesafesinde 🚢

🎯 Özet: Test Kültürü Nasıl Alışkanlık Olur?

  1. Küçük başla — bir fonksiyon, bir test.
  2. Watch mode açık tut — anında feedback.
  3. CI'ye bağla — push atdığında her şey kontrol ediliyor.
  4. Badge ekle — README'ye ![CI](https://github.com/.../workflows/CI/badge.svg) koy, takip et 🏷.

Artık "test yazmak sıkıcı" demezsin; "test yazmadığımda geceleri rahat uyuyamam" dersin 😴➡️😴✅.

Sonraki bölümde bu Docker image'ı Kubernetes'e deploy edip, Helm chart ile canlıya almayı anlatacağız. Hazır mısın? 🚀


🎯 Sonuç ve Bonus Tavsiye: Gelecek Geliştirmeler ve Toplulukla Büyüme

Harika bir yolculuktan geçtik, değil mi? 🎉

MCP sayesinde araçlarımızı standartlaştırdık, güvenli bir mimari kurguladık ve hepsini topluluk odaklı bir şekilde dağıtmayı öğrendik. Artık elinizde production-ready, ölçeklenebilir ve başkalarının da kullanabileceği bir altyapı var.

Şimdi sıra sizde. 🚀

Kendi MCP sunucunuzu yazın, kırın, düzeltin, paylaşın. Hata yapmaktan çekinmeyin — en iyi öğrenme yolu o zaten. Toplulukla etkileşime girin, issue açın, PR gönderin. Her katkı, ekosistemin biraz daha güçlenmesi demek.


💡 Bonus Tavsiyeler: Bir Sonraki Adımlar

  • 📦 Marketplace'e yayınlayın — npm, PyPI ya da GitHub Packages'e pushlayın. publish komutu bir bazen tek tık, ama erişiminiz binlerce geliştiriciye oluyor.
  • 📊 Telemetri ekleyin — OpenTelemetry ile metrik, log ve trace toplayın. Ne kadar kullanıldığını, nerede yorduğunu bilmeden iyileştiremezsiniz.
  • 🔄 Geri bildirim döngüsü kurun — GitHub Discussions, Discord ya da basit bir Google Form. Kullanıcılarınızın sesini duymak, roadmap'inizi onlardan çok daha iyi çizer.
  • 🧪 CI/CD'ye entegre edin — Her PR'de test, lint, security scan. Güven, otomasyondan gelir.
  • 📚 Dokümantasyonu canlı tutun — README, CHANGELOG, migration guide. İyi doküman, destek talebinin yarısını azaltır.

Hadi, klavyeyi başınıza koyun ve bir şeyler üretmeye başlayın. 🛠

Toplulukta görüşmek üzere! 👋


Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.

Burak Sağlık

Burak Saglik

©2024 Desing and Developed by @Burak Sağlık

All rights reserved