TypeScript ile Üretim Odaklı MCP Sunucuları: Güvenlik ve Auth
YAPAY ZEKAMCPModel Context Protocol

TypeScript ile Üretim Odaklı MCP Sunucuları: Güvenlik ve Auth

calendar_today1 AĞU 2026
schedule10 DK OKUMA
boltİLERİ SEVİYE

TypeScript ile Canlıya Alınabilir MCP Sunucusu Geliştirme ve Güvenlik Rehberi

Büyük Dil Modelleri (LLM'ler) sohbet arayüzlerinden otonom yazılım ajanlarına evrilirken temel bir mühendislik problemi ortaya çıkar: Yapay zeka modelleri kurumsal veritabanları, iç API'ler, geliştirici araçları ve dosya sistemleriyle hassas altyapıyı riske atmadan nasıl güvenle etkileşime girebilir?

Anthropic tarafından açık kaynak olarak sunulan Model Context Protocol (MCP), yapay zeka host'larını (Claude Desktop, Cursor IDE ve özel agent sistemleri) dış veri kaynaklarına ve araçlara bağlayan mimari bir standarttır.

Basit MCP öğreticileri yerel stdio bağlantılarını gösterirken, canlı (production) ortamlarda çalışan MCP sunucuları sıkı girdi doğrulaması (input validation), katman güvenliği, kimlik doğrulama middleware'i, oran sınırlama (rate limiting) ve hata izolasyonu gerektirir.

Bu rehberde, TypeScript ve @modelcontextprotocol/sdk kullanarak canlıya alınabilir, güvenlik testlerinden geçmiş bir MCP sunucusunun mimarisini, Anthropic Agent SDK entegrasyonunu ve kimlik doğrulama adımlarını inceleyeceğiz.

[!IMPORTANT] Production MCP Güvenliği İçin Temel Mimari Çözüm: Anthropic Agent SDK ve Model Context Protocol (MCP) kimlik doğrulama mimarisi üç kritik savunma katmanına dayanır:

  1. Taşıma Katmanı Güvenliği (TLS + Bearer/OAuth2 Token): Ajan el sıkışmasından önce Server-Sent Events (SSE) uç noktalarını kimlik denetiminden geçirme.
  2. Zod Katı Şema Doğrulaması: SQL enjeksiyonu ve prompt injection saldırılarını engellemek için tüm LLM araç argümanlarını tip seviyesinde denetleme.
  3. Dizin Geçişi Koruması (Path Traversal Defense): Ajanların sunucu ana dizininden dışarı çıkmasını engelleyen path.resolve() kontrolleri.

MCP Güvenlik & Kimlik Doğrulama Matrisi

Boyut Stdio Transport Remote SSE Transport HTTP Stream Transport
Kimlik Doğrulama İşletim Sistemi Süreç Yetkisi Bearer Token / JWT / mTLS API Key Header / OAuth 2.0
Güvenlik Sınırı Yerel Sandbox / UID İzolasyonu Ağ Güvenlik Duvarı + CORS Ters Proxy / API Gateway
En İyi Kullanım Claude Desktop, Yerel IDE Bulut AI Ajanları, Mikroservisler Dağıtık Çoklu Ajan Sistemleri
Risk Faktörü Düşük (Kullanıcı yetkisine bağlı) Yüksek (Sıkı token koruması şart) Orta (Standart web güvenliği)

1. Model Context Protocol (MCP) Mimari Temelleri

MCP, LLM yürütmesini alt sistem kaynaklarından ayırmak için istemci-sunucu (client-server) mimarisini uygular:

  • Host (AI Host): LLM'in çalıştığı ortam (Örn: Claude Desktop, Cursor IDE, LangChain agent).
  • Client (MCP Client): Host içinde yer alan, protokol yeteneklerini yöneten ve araç çağrılarını ileten istemci.
  • Server (MCP Server): İstemciye açık Kaynaklar (Resources), Araçlar (Tools) ve Prompt'lar sunan bağımsız servis.
graph LR
    Host[AI Host / Claude / Cursor] <--> Client[MCP Client]
    Client <-->|Stdio / SSE / HTTP| Server[Production MCP Server]
    Server <--> Guard[Girdi Doğrulama & Zod Şeması]
    Guard <--> DB[(Canlı Veritabanı)]
    Guard <--> ExternalAPI[Harici API'ler]

MCP Tarafından Sunulan Temel Bileşenler

  1. Tools (Araçlar): LLM'in eylem gerçekleştirmesini sağlayan çalıştırılabilir fonksiyonlar (Örn: SQL sorgusu çalıştırma, güvenlik günlüğü tarama, webhook tetikleme).
  2. Resources (Kaynaklar): LLM'in okuma yetkisine sahip olduğu veri uç noktaları (Örn: yapılandırma dosyaları, sistem metrikleri, veritabanı kayıtları).
  3. Prompts (Şablonlar): Karmaşık ajan etkileşimlerini standartlaştıran parametreli istem şablonları.

2. Production TypeScript Projesinin Kurulumu

Kurumsal düzeyde bir MCP sunucusu geliştirmek için TypeScript projenizi sıkı tip güvenliği ve şema doğrulama bağımlılıklarıyla başlatın:

mkdir mcp-production-server
cd mcp-production-server
npm init -y
npm install @modelcontextprotocol/sdk zod dotenv express cors helmet
npm install -D typescript @types/node @types/express tsx

tsconfig.json dosyasını sıkı tip denetimi için yapılandırın:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"]
}

3. Canlıya Alınabilir MCP Sunucusunun Kodlanması

Güvenlik tespiti ve veri analizi yetenekleri sunan güvenli bir MCP sunucusu oluşturalım.

Adım 1: Sunucu Örneğinin Başlatılması

src/server.ts dosyasını oluşturun:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  ErrorCode,
  McpError,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

const server = new Server(
  {
    name: "production-security-mcp",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
      resources: {},
    },
  }
);

Adım 2: Sıkı Zod Şeması ile Girdi Doğrulama

Girdi doğrulaması, Prompt Injection ve Veri Manipülasyonu saldırılarına karşı ilk savunma hattıdır. Tüm araç parametreleri için sıkı Zod şemaları tanımlayın:

const AuditLogQuerySchema = z.object({
  environment: z.enum(["production", "staging", "development"]),
  limit: z.number().int().min(1).max(100).default(20),
  severity: z.enum(["LOW", "MEDIUM", "HIGH", "CRITICAL"]).optional(),
  searchTerm: z.string().max(200).optional(),
});

type AuditLogQuery = z.infer<typeof AuditLogQuerySchema>;

Adım 3: Araç Kaydı ve Yetenek Bildirimi

Kapasite görüşmesi sırasında LLM'e kullanılabilir araçları bildirin:

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "query_audit_logs",
        description: "Kurumsal güvenlik denetim günlüklerini filtrelenmiş olarak getirir.",
        inputSchema: {
          type: "object",
          properties: {
            environment: {
              type: "string",
              enum: ["production", "staging", "development"],
              description: "İncelenecek hedef ortam",
            },
            limit: {
              type: "number",
              description: "Döndürülecek maksimum kayıt sayısı (1-100)",
            },
            severity: {
              type: "string",
              enum: ["LOW", "MEDIUM", "HIGH", "CRITICAL"],
              description: "Günlük önem derecesine göre filtreleme",
            },
            searchTerm: {
              type: "string",
              description: "Arama terimi (maks 200 karakter)",
            },
          },
          required: ["environment"],
        },
      },
    ],
  };
});

Adım 4: Güvenli Araç Çalıştırma Yöneticisi

Araç çalıştırma işleyicisini hata sınırları (error boundaries) ve veri dezenfeksiyonu ile uygulayın:

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "query_audit_logs") {
    // Parametreleri Zod şemasına göre doğrula
    const parseResult = AuditLogQuerySchema.safeParse(args);
    if (!parseResult.success) {
      throw new McpError(
        ErrorCode.InvalidParams,
        `Geçersiz araç parametreleri: ${parseResult.error.message}`
      );
    }

    const { environment, limit, severity, searchTerm } = parseResult.data;

    try {
      // Doğrulanmış sorguyu altyapıda çalıştır
      const logs = await fetchSecurityAuditLogs({
        environment,
        limit,
        severity,
        searchTerm,
      });

      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(logs, null, 2),
          },
        ],
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Bilinmeyen veritabanı hatası";
      return {
        content: [
          {
            type: "text",
            text: `Çalıştırma başarısız: ${errorMessage}`,
          },
        ],
        isError: true,
      };
    }
  }

  throw new McpError(ErrorCode.MethodNotFound, `Bilinmeyen araç: ${name}`);
});

4. Canlı (Production) MCP Dağıtımlarında Güvenlik Sıkılaştırma

MCP sunucularını canlı ortamda çalıştırmak özel güvenlik gereksinimleri doğurur:

A. Girdi Dezenfeksiyonu ve Path Traversal Engelleme

LLM araç argümanlarından gelen ham metinleri doğrudan dosya yollarına veya kabuk (shell) komutlarına iletmeyin:

import path from "path";

export function sanitizeFilePath(baseDir: string, userPath: string): string {
  const safePath = path.normalize(userPath).replace(/^(\.\.[\/\\])+/, "");
  const resolvedPath = path.resolve(baseDir, safePath);
  
  if (!resolvedPath.startsWith(baseDir)) {
    throw new Error("Güvenlik Uyarısı: Path traversal girişimi tespit edildi.");
  }
  return resolvedPath;
}

B. Taşıma Katmanı Güvenliği: Stdio vs SSE

  • Stdio Transport: Yerel çalıştırma için idealdir (Claude Desktop, Cursor). İşletim sistemi süreç izolasyonu doğal güvenlik sınırı sağlar.
  • Server-Sent Events (SSE) Transport: Bulut dağıtımları için gereklidir. TLS (HTTPS), CORS kısıtlamaları ve Bearer Token / OAuth2 kimlik doğrulama başlıkları ile korunmalıdır.

C. Uzaktan SSE Taşıma Katmanı İçin Kimlik Doğrulama Middleware'i

MCP sunucusunu HTTP/SSE üzerinden sunarken taşıma katmanını Express kimlik doğrulama korumasıyla sarmalayın:

import express from "express";
import helmet from "helmet";
import cors from "cors";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";

const app = express();
app.use(helmet());
app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(",") || ["https://gucluyumhe.dev"] }));

// Kimlik Doğrulama Koruması
app.use("/sse", (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
    res.status(401).json({ error: "Yetkisiz: Geçersiz veya eksik Bearer token" });
    return;
  }
  
  const token = authHeader.substring(7);
  if (token !== process.env.MCP_SECRET_KEY) {
    res.status(403).json({ error: "Yasaklandı: Geçersiz MCP gizli anahtarı" });
    return;
  }
  
  next();
});

let sseTransport: SSEServerTransport;

app.get("/sse", async (req, res) => {
  sseTransport = new SSEServerTransport("/messages", res);
  await server.connect(sseTransport);
});

app.post("/messages", async (req, res) => {
  await sseTransport.handlePostMessage(req, res);
});

app.listen(3001, () => {
  console.log("Production MCP Sunucusu 3001 portunda SSE ile çalışıyor.");
});

5. Anthropic Agent SDK & TypeScript Güvenlik Mimarisi

Otonom ajanları Anthropic Agent SDK (@anthropic-ai/sdk) ve MCP ile TypeScript üzerinde çalıştırırken, ajanı güvenli bir MCP istemcisi (client) olarak yapılandırmalısınız:

import Anthropic from "@anthropic-ai/sdk";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

// Şifrelenmiş Bearer Token ile MCP İstemcisi Başlatma
const mcpTransport = new SSEClientTransport(
  new URL("https://mcp.gucluyumhe.dev/sse"),
  {
    eventSourceInit: {
      headers: {
        Authorization: `Bearer ${process.env.MCP_BEARER_TOKEN}`,
        "X-Agent-Identifier": "anthropic-agent-sdk-prod",
      },
    },
  }
);

const mcpClient = new Client(
  {
    name: "KurumsalGuvenlikAjani",
    version: "1.0.0",
  },
  {
    capabilities: {
      prompts: {},
      resources: {},
      tools: {},
    },
  }
);

// Araçları yürütmeden önce istemci bağlantısını tamamlayın
await mcpClient.connect(mcpTransport);

// Anthropic Claude İstemcisini Başlatın
const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

// Doğrulanmış şemaları listeleyin
const availableTools = await mcpClient.listTools();

console.log(`${availableTools.tools.length} adet güvenli MCP aracı başarıyla bağlandı.`);

Dinamik Ajan Kimlik Doğrulama & Yetkilendirme İçin McpAuthMetadataRouter Kullanımı

Farklı yetki katmanlarına sahip çoklu otonom ajanların çalıştığı kurumsal sistemlerde McpAuthMetadataRouter tasarım desenini kullanın. Bu yönlendirici, gelen istekteki Bearer token'ı ve ajan kimliğini çözer, oturum süresini (TTL) doğrular ve ajanın sadece yetkili olduğu araçları (tools) çalıştırmasına izin verir:

import { Request, Response, NextFunction } from "express";

export interface McpAgentAuthContext {
  agentId: string;
  role: "admin" | "security_auditor" | "readonly_agent";
  allowedTools: string[];
  expiresAt: number;
}

/**
 * McpAuthMetadataRouter
 * Anthropic Agent SDK ve MCP sunucu araç çağrıları için dinamik auth ve yetki yönlendirmesi sağlar.
 */
export class McpAuthMetadataRouter {
  private static sessions = new Map<string, McpAgentAuthContext>();

  public static registerSession(bearerToken: string, context: McpAgentAuthContext): void {
    this.sessions.set(bearerToken, context);
  }

  public static authorize(bearerToken: string, requestedTool: string): boolean {
    const session = this.sessions.get(bearerToken);
    if (!session) return false;

    // Oturum süresi kontrolü (TTL)
    if (Date.now() > session.expiresAt) {
      this.sessions.delete(bearerToken);
      return false;
    }

    // Joker karakter yetkisi veya hedeflenen araca özel yetki denetimi
    return session.allowedTools.includes("*") || session.allowedTools.includes(requestedTool);
  }

  public static middleware() {
    return (req: Request, res: Response, next: NextFunction): void => {
      const authHeader = req.headers.authorization;
      if (!authHeader?.startsWith("Bearer ")) {
        res.status(401).json({ error: "McpAuthMetadataRouter: Bearer Token eksik veya geçersiz" });
        return;
      }

      const token = authHeader.substring(7);
      const requestedTool = req.headers["x-mcp-tool-target"] as string;

      if (requestedTool && !McpAuthMetadataRouter.authorize(token, requestedTool)) {
        res.status(403).json({
          error: `McpAuthMetadataRouter: Ajanın "${requestedTool}" aracını çalıştırma yetkisi bulunmuyor`,
        });
        return;
      }

      next();
    };
  }
}

Ajan SDK Dağıtımları İçin Güvenlik Kontrol Listesi

  • Sıfır Güven (Zero-Trust) Yetkilendirme: Ajan rolü için yalnızca zorunlu araçları kaydedin (McpAuthMetadataRouter ile En Az Yetki Prensibi).
  • Zaman Aşımı Sınırları: Askıda kalan alt süreçleri ve servis dışı bırakma riskini önlemek için her araca en fazla 15 saniyelik limit koyun.
  • Değiştirilemez Denetim Günlüğü (Audit Logging): Her araç çağrısını, girdi parametrelerini ve dönen yanıt özetlerini güvenli log sistemine yazın.

6. Canlıya Alma Stratejileri (Vercel, Railway, Docker)

Docker ve Railway / AWS ECS Dağıtımı

Süreç izolasyonu sağlamak için kapalı bir Dockerfile hazırlayın:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json tsconfig.json ./
RUN npm ci
COPY src ./src
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist

USER node
EXPOSE 3001
CMD ["node", "dist/server.js"]

Sıkça Sorulan Sorular (FAQ)

Model Context Protocol (MCP) TypeScript ile kimlik doğrulamayı nasıl sağlar?

TypeScript ile MCP kimlik doğrulaması taşıma katmanı (transport middleware) üzerinden yürütülür. Çekirdek protokol kendi başına bir auth standardı dayatmaz; ancak uzak sunucu bağlantılarında Server-Sent Events (SSE) veya HTTP akışları Bearer Token (JWT), OAuth2 veya karşılıklı TLS (mTLS) header'ları ile güvenceye alınır. Yerel Stdio taşımalarında ise işletim sistemi süreç yetkileri geçerlidir.

Anthropic Agent SDK uzak MCP sunucularına bağlanırken nasıl korunur?

Anthropic Agent SDK'yı korumak için SSEClientTransport başlıklarına şifrelenmiş Bearer token'lar verilmeli, uzak ağ geçidinde TLS 1.3 zorunlu tutulmalı, sıkı CORS politikaları uygulanmalı ve prompt injection saldırılarını bertaraf etmek için Zod şema doğrulaması kullanılmalıdır.

MCP'de Stdio ve SSE taşıma güvenliği arasındaki fark nedir?

Stdio taşımacılığı yerel ana makinedeki standart girdi/çıktı boruları üzerinden çalışır, yani araçlar ağa maruz kalmadan kullanıcının işletim sistemi yetkileriyle yürütülür. SSE (Server-Sent Events) taşımacılığı ise JSON-RPC paketlerini HTTP/HTTPS üzerinden ilettiğinden harici güvenlik duvarı, oran sınırlama (rate limit) ve token doğrulaması gerektirir.

MCP araçlarında prompt injection ve dizin geçişi saldırıları nasıl önlenir?

Gelen tüm parametreler Zod şemalarıyla doğrulanmalı, kaçış karakterleri (../) engellenmeli, dosya yolları path.resolve() ile izin verilen ana dizin altında kontrol edilmeli ve araç süreçleri root olmayan Docker konteynerlerinde çalıştırılmalıdır.


Sonuç

Model Context Protocol (MCP), statik LLM'leri kurumsal yapay zeka ajanlarına dönüştüren devrim niteliğinde bir standarttır. Sıkı Zod doğrulaması, dosya yolu dezenfeksiyonu, kimlik doğrulamalı SSE taşıma katmanı ve izole çalıştırma ortamları uygulayarak MCP sunucularınızı canlıya güvenle alabilirsiniz.

Tüm kaynak kodları ve açık kaynak araçları incelemek için GitHub profilimi ziyaret edebilir veya gucluyumhe.dev üzerinden iletişime geçebilirsiniz.

Ömer Özbay
YAZAN

Ömer Özbay

Yüksek performanslı arka yüz mimarilerini piksel hassasiyetinde ön yüz deneyimleriyle birleştirmede uzmanlaşmış Tam Yığın Geliştirici. Yapay zeka ve modern web teknolojileriyle geleceği inşa ediyor.

MİMARİ SÜREKLİLİK

İlgili Mimariler & Teknik Yazılar

Tüm Yazıları Oku