Ana içeriğe atla

 

Claude Desktop ile XSOAR Entegrasyonu: CortexSynapse MCP Sunucusunun Sıfırdan Devreye Alınması

Bir Vaka Çalışması – Kâmil AKDAĞ, MSc

Bu makale, Cortex XSOAR 6.13'ün, CortexSynapse açık kaynak MCP sunucusu üzerinden Claude Desktop'a bağlanması; süreç boyunca karşılaşılan üç ardışık entegrasyon hatasının teşhisi ve kalıcı çözümünü içerir.

TL;DR (Çok Uzun; Okumadım)

Cortex XSOAR'ı Claude Desktop'a MCP üzerinden bağlamak için CortexSynapse Docker imajını kullanırken üç farklı sorunla karşılaşıldı:

  1. SSL sertifika doğrulama hatası: Yanlış env değişkeni ismi (XSOAR_VERIFY_SSL yerine kodda VERIFY_SSL bekleniyor).
  2. HTML 303 redirect cevapları: XSOAR_API_URL değerinin sonundaki / çift slash'a yol açıp XSOAR'ı API yerine UI'ya yönlendiriyor.
  3. HTTP 400 "string into Go value" hatası: MCP sunucusunun istek body'sini double-encode etmesi; codegen tarafından üretilen üç dosyada json=body yerine json=(json.loads(body) if isinstance(body, str) else body) patch'i gerekiyor; bu patch Dockerfile'a codegen adımının ardından yerleştirilmeli.

Üçü çözüldükten sonra get_incidents, xsiam_get_alerts, update_incident, xsoar_indicators_search gibi tüm MCP araçları çalışır hale geldi.

 

1. Mimari

Bir SOC için Cortex XSOAR, incident orkestrasyonunun merkezidir. Buna Claude Desktop'un doğal dil ara yüzünü bir LLM destekli SOC katmanı olarak eklediğinizde şu use-case'ler açılır:

  • "Son 24 saatte severity ≥ High açılan kapanmamış incident'ları getir, owner dağılımına göre özetle" gibi serbest sorgular.
  • Triage sırasında ilgili alert'lerin XQL tarafında karşılıklarını çekme.
  • İndikatör taraması, playbook tetikleme, endpoint isolate/unisolate gibi response aksiyonları.

Bunu sağlamak için MCP (Model Context Protocol) kullanılır. MCP, LLM client'ı (Claude Desktop/CoWork) ile harici sistemler (XSOAR, XSIAM, Splunk vb.) arasında standart bir köprü sunar. CortexSynapse, XSOAR/XSIAM API'sini MCP araçlarına dönüştüren açık kaynak bir Python sunucusudur ve Docker imajı olarak çalıştırılır.

Akış:

Kullanıcı (Claude Desktop UI)

  

  

Claude (LLM)

     MCP tool call (JSON-RPC)

  

Docker container: cortexsynapse  ──HTTPS──►  Cortex XSOAR API

  

  

JSON response (incident, alert, indicator vb.)

Claude Desktop her oturumda container'ı claude_desktop_config.json'daki tanıma göre docker run ile başlatır; oturum kapandığında --rm flag'i sayesinde container otomatik silinir.

 

2. Önkoşullar

Bu kurulumdan önce sahip olmanız gerekenler:

Bileşen

Sürüm

Amaç

Claude Desktop (desktop app)

Güncel

LLM client + MCP host

Docker Desktop for Windows

4.71.0

MCP sunucusunu container olarak çalıştırma

PowerShell

Komutları çalıştırma

Python

3.10 ve üzeri (Windows tarafında)

Patch script'lerini çalıştırmak ve direct API testleri için

Cortex XSOAR

6.x veya 8.x (XSIAM dahil)

API erişilebilir olmalı

XSOAR API Key

Web tipinde

Settings → Integrations → API Keys → "Get Your Key"

CortexSynapse kaynak kodu

https://github.com/amshamah419/CortexSynapse

İmajı build etmek için

Not: API key oluştururken minimum gerekli yetkilerle başlayın. Read-only test için "Read Only" rolü, response aksiyonları için ek izinler ekleyin. Key'i hiçbir transcript, screenshot veya log içinde paylaşmayın; sızdığını fark ederseniz revoke ve rotate edin.

 

 

3. Sıfırdan Kurulum

Bu makaledeki hata-ayıklama sürecinden öğrendiklerimle düzenlenmiş, sorunlara denk gelmemeniz için iyileştirilmiş sıralama.

3.1. CortexSynapse kaynağını indir

GitHub'dan klonla veya ZIP indir, Desktop'a aç

cd C:\Users\<kullanıcı>\Desktop

Sonuç: C:\Users\<kullanıcı>\Desktop\CortexSynapse-main\ (Dockerfile, server/, codegen/, specs/ içerir)

3.2. Body double-encoding patch'ini Dockerfile'a ekle

CortexSynapse'in 1.27.0 sürümünde, MCP'nin body parametresi httpx istemcisine olduğu gibi iletildiğinde XSOAR çift kodlanmış JSON string olarak görüyor. Üretilmiş üç dosyaya (generated_xsoar_tools.py, generated_xsiam_tools.py, generated_unified_tools.py) tek satırlık bir patch yeterli ama bu dosyalar build sırasında python -m codegen.generator ile yeniden üretildiği için patch'i Dockerfile'a, codegen adımının hemen ardına eklemek gerekiyor.

PowerShell'de (kaynak klasörünün içindeyken):

cd C:\Users\<kullanıcı>\Desktop\CortexSynapse-main

@'

import pathlib

p = pathlib.Path("Dockerfile")

text = p.read_text(encoding="utf-8")

needle = "RUN python -m codegen.generator"

patch_line = "\nRUN sed -i \"s|json=body|json=(json.loads(body) if isinstance(body, str) else body)|g\" /app/server/generated_xsoar_tools.py /app/server/generated_xsiam_tools.py /app/server/generated_unified_tools.py"

if "json.loads(body)" in text:

    print("Dockerfile zaten patched")

else:

    p.write_text(text.replace(needle, needle + patch_line), encoding="utf-8")

    print("Dockerfile patched")

'@ | python

Bu blok Python'u çağırarak Dockerfile'ı güvenli şekilde değiştirir.

3.3. İmajı build et

docker build --no-cache -t cortexsynapse-patched .

--no-cache, eski layer'ların yanlışlıkla yeniden kullanılmasını engeller. Build sonunda Successfully tagged cortexsynapse-patched:latest görmelisiniz.

 

3.4. Patch'in imaja yansıdığını doğrula

docker run --rm cortexsynapse-patched grep -c "json.loads(body)" `

  /app/server/generated_xsoar_tools.py `

  /app/server/generated_xsiam_tools.py `

  /app/server/generated_unified_tools.py

Beklenen çıktı:

/app/server/generated_xsoar_tools.py:1

/app/server/generated_xsiam_tools.py:1

/app/server/generated_unified_tools.py:8

0 görüyorsanız Dockerfile patch satırı işlememiş demektir; 3.2'deki Python bloğunu yeniden çalıştırın.

3.5. Claude Desktop MCP konfigürasyonunu yaz

Dosya yolu: %APPDATA%\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json

{

  "mcpServers": {

    "cortex-xsoar": {

      "command": "docker",

      "args": [

        "run", "-i", "--rm", "--read-only",

        "--security-opt=no-new-privileges",

        "-e", "XSOAR_API_URL",

        "-e", "XSOAR_API_KEY",

        "-e", "VERIFY_SSL=false",

        "cortexsynapse-patched"

      ],

      "env": {

        "XSOAR_API_URL": "https://xsoar.ornek.com",

        "XSOAR_API_KEY": "<API_KEY_BURAYA>"

      }

    }

  }

}

Üç kritik nokta:

  • XSOAR_API_URL değeri trailing slash içermemeli (https://xsoar.example.com/ -- hatalı kullanım). Sondaki / çift slash'a yol açıp 303 redirect üretiyor.
  • Env değişkeni VERIFY_SSL (kod bu ismi okuyor); XSOAR_VERIFY_SSL ya da INSECURE çalışmıyor.
  • İmaj adı cortexsynapse-patched olmalı (orijinal cortexsynapse patch içermiyor).

 

3.6. Claude Desktop'u tamamen yeniden başlat

  • Claude Desktop penceresini kapatmak yetmez. Görev yöneticisinden ya da sistem tray ikon üzerinden kapatın.
  • Görev Yöneticisi'nde Claude.exe veya benzeri kalan süreçleri "End task" ile sonlandırın.
  • Claude Desktop'u tekrar açın.

İlk soruda Claude cortexsynapse-patched imajıyla yeni bir container başlatır ve XSOAR araçları kullanılabilir hale gelir.

3.7. Doğrulama sorgusu

Claude Desktop'ta yazın:

"XSOAR'daki son 5 incident'ı listele"

Beklenen sonuç: id, name, severity, status, owner, created kolonlarıyla bir tablo. Hata gelirse sonraki bölümde yer alan analizlere odaklanın.

4. Vaka Analizi: Karşılaşılan 3 Sorun ve Tespit Yöntemleri

Bu bölüm, sorunlar ortaya çıkarsa nasıl tanılayacağınızı gösterir. Sıralama, gerçek hata-ayıklama sürecindeki sırayla aynıdır, biri çözülmeden bir sonrakine geçilemiyor.

Sorun 1 — [SSL: CERTIFICATE_VERIFY_FAILED] self-signed certificate

Tanılama: İlk MCP çağrısında SSL doğrulama hatası.

İlk çözüm: Container XSOAR_VERIFY_SSL=false yok diye doğrulamaya kalkıyor. Claude Desktop config'ine XSOAR_VERIFY_SSL=false eklendi, ama hata aynı kaldı.

Kritik tanılama: Container'ın gerçekten hangi env değişkenini okuduğunu bulmak için kaynak kodda arandı:

docker exec <container_adı> sh -c "grep -rniE 'verify_ssl|verify=' /app/server 2>/dev/null"

Çıktı:

/app/server/security.py:132: "verify_ssl": os.getenv("VERIFY_SSL", "true").lower() == "true"

/app/server/generated_xsoar_tools.py:27: verify = os.getenv("VERIFY_SSL", "true").lower() == "true"

Öğrenilen: Kod VERIFY_SSL okuyor, prefix'siz. Yanlış env adı set edildiği görüldü.

Çözüm: Claude Desktop config'inde VERIFY_SSL=false (3.5'teki nihai konfigürasyondaki gibi).

Çıkarılan ders: "Env değişkeni set ettim ama kod onu görmüyor" şüphesinde, container'ın kaynak kodunda env okuma satırını grep'leyin. Başka bir tartışmaya yer kalmaz.

Sorun 2 — Boş cevap veya <a href="/#/404">See Other</a>

Tanılama: SSL düzeldikten sonra MCP çağrıları boş string ya da 303 redirect ile UI'ya yönlendirme dönüyor.

Kritik tanılama: Direkt API çağrısı ile MCP'yi devreden çıkarıp ham HTTP cevabı incelendi:

Powershell üzerinde

@'

import os, httpx

key = os.getenv("XSOAR_API_KEY")

for u in ["https://10.10.20.20//incidents/search", "https://10.10.20.20/incidents/search"]:

    r = httpx.post(u,

        headers={"Authorization": key, "Content-Type":"application/json", "Accept":"application/json"},

        json={"filter":{"size":1}}, verify=False, follow_redirects=False, timeout=10)

    print(u, "->", r.status_code, "LEN", len(r.text), "LOC:", r.headers.get("location",""))

'@ | docker exec -i <container_adı> python

Sonuç:

https://10.10.20.20//incidents/search -> 307 LEN 0 LOC: /incidents/search   ← çift slash, redirect

https://10.10.20.20/incidents/search  -> 200 LEN 5865 LOC:                  ← tek slash, başarılı

Öğrenilen: XSOAR_API_URL=https://10.10.20.20/ değerinde sondaki / ile birleştirilen /incidents/search route'u https://10.10.20.20//incidents/search üretiyor. XSOAR çift slash'ı 307 redirect ile temiz path'e yönlendiriyor; CortexSynapse'in httpx istemcisi default follow_redirects=False çalıştığı için cevabı boş alıyor.

Çözüm: Claude Desktop config'indeki XSOAR_API_URL değerinden sondaki / silindi.

Çıkarılan ders: API URL'lerinde trailing slash yorucu olabilir.

 

 

 

Sorun #3 — 400 Bad Request: json: cannot unmarshal string into Go value

Tanılama: SSL ve URL düzeldi, MCP artık XSOAR'a başarıyla bağlanıyor ama her body alan endpoint'te şu hata:

{"id": "bad_request", "status": 400, "title": "Bad request",

 "detail": "Request body is not well-formed. It must be JSON.",

 "error": "json: cannot unmarshal string into Go value of type entities.SearchIncidentsData"}

XSOAR gönderilen body'yi JSON-encoded string olarak görüyor, beklediği object değil.

Kritik tanılama: İstek dispatch kodu okundu:

# /app/server/generated_xsoar_tools.py

async def handler(arguments: Dict[str, Any]) -> List[types.TextContent]:

    body = arguments.get("body")

    ...

    resp = await client.request(

        method=method, url=url,

        params=_sanitize_query(query),

        headers=_sanitize_headers(headers),

        json=body,

    )

Body normalde JSON nesnesi olarak gitmeli. Ama bizim tarafta önce yazıya çevriliyor. Sonra httpx bunu tekrar JSON’a çevirince XSOAR’a beklenen JSON değil, JSON gibi görünen bir yazı gidiyor. Bu yüzden XSOAR body’yi okuyamıyor.

Çözüm: Sunucu tarafında body string ise parse et.

json=(json.loads(body) if isinstance(body, str) else body)

Önemli Nokta: İnce ama önemli bir detay var: Bu düzeltmeyi sadece host üzerindeki .py dosyalarına yapmak yeterli değil. Çünkü CortexSynapse Docker imajı build edilirken RUN python -m codegen.generator komutu çalışıyor ve bu üç dosyayı container içinde yeniden oluşturuyor. Yani host tarafında patch’lediğimiz dosyaların üzerine build sırasında tekrar yazılıyor.

Doğru çözüm: Patch'i Dockerfile'a, codegen adımının hemen ardına ek bir RUN sed -i ... satırı olarak yerleştirmek. Bölüm 3.2'deki Python script'i tam olarak bunu yapıyor.

5. Nihai Patched Dockerfile (İlgili Kısım)

Patch uygulandıktan sonra builder stage şöyle görünür:

# ... (önceki adımlar)

COPY server/   server/

COPY codegen/  codegen/

COPY specs/    specs/

 

RUN python -m codegen.generator

 

# ↓↓↓ EKLENEN SATIR ↓↓↓

RUN sed -i "s|json=body|json=(json.loads(body) if isinstance(body, str) else body)|g" \

    /app/server/generated_xsoar_tools.py \

    /app/server/generated_xsiam_tools.py \

    /app/server/generated_unified_tools.py

# ↑↑↑ EKLENEN SATIR ↑↑↑

 

RUN python -m build

# ... (stage-1 ile devam)

Bu satır, üretim adımı bittikten sonra üç jeneratör çıktısındaki json=body ifadesini koşullu parse edici hale dönüştürür. Build cache'leniyorsa --no-cache ile tekrar build alın.

 

6. Uçtan Uca Doğrulama

Patch uygulanmış imaj çalıştığında MCP üzerinden bu örnek dönecektir:

Claude Desktop sorgusu:

XSOAR'daki son 5 incident'ı listele

Beklenen MCP çağrısı (özet):

tool: get_incidents

platform: xsoar

body: {"filter": {"page": 0, "size": 5, "sort": [{"field": "created", "asc": false}]}}

Beklenen sonuç (örnek tablo):

ID

Name

Severity

Status

Owner

Created (UTC)

34763

Test

3 (High)

1 (Active)

L1-L1

2026-04-16 12:06

34748

test3

0 (Unknown)

0 (Pending)

L1-L1

2026-03-19 08:27

34747

test2

0 (Unknown)

0 (Pending)

L1-L1

2026-03-19 08:26

34746

test1

0 (Unknown)

0 (Pending)

L1-L1

2026-03-19 08:26

34740

test cti 2

1 (Low)

1 (Active)

L1-L1

2026-03-13 15:48

Severity referansı (Cortex XSOAR): 0=Unknown, 0.5=Informational, 1=Low, 2=Medium, 3=High, 4=Critical Status referansı: 0=Pending, 1=Active, 2=Closed, 3=Archived

 

7. Tanılama Araç Kutusu

Aşağıdaki komutlar bu projede defalarca işe yaradı. Bir SOC engineer'ın MCP entegrasyon problemlerinde başvurabileceği "first responder" set'i:

# Çalışan container'ları gör

docker ps --format "{{.Names}} {{.Image}}"

 

# Container'ın aktif env değişkenleri

docker exec <NAME> env | findstr /I "XSOAR VERIFY API"

 

# MCP server log'u (initialize, tool list, hata mesajları)

docker logs --tail 100 <NAME>

 

# Container'ın kaynak kodunda bir terimi grep'le

docker exec <NAME> sh -c "grep -rniE 'pattern' /app/server"

 

# Direct API testi (MCP'yi devreden çıkar)

@'

import os, httpx

url = os.getenv("XSOAR_API_URL").rstrip("/") + "/incidents/search"

r = httpx.post(url,

    headers={"Authorization": os.getenv("XSOAR_API_KEY"),

             "Content-Type":"application/json", "Accept":"application/json"},

    json={"filter":{"size":1}}, verify=False, timeout=10)

print(r.status_code, r.text[:300])

'@ | docker exec -i <NAME> python

 

# Imaj içinde patch var mı?

docker run --rm <IMAGE> grep -c "json.loads(body)" /app/server/generated_xsoar_tools.py

8. Güvenlik Tedbirleri

  • API key yönetimi: claude_desktop_config.json plaintext key barındırır. Endpoint protection (Cortex, CrowdStrike, Defender) bu dosyayı taramalı, MFA-protected disk encryption (BitLocker) zorunlu olmalı.
  • Container hardening: Config'deki --read-only, --rm, --security-opt=no-new-privileges flag'leri olduğu gibi korunmalı. Read-only filesystem, --rm ile birlikte container'da yapılan herhangi bir değişikliğin kalıcı olmasını engeller.
  • Network segmentation: XSOAR API'si genelde yönetim VLAN'inde. Claude Desktop'un çalıştığı endpoint'in oraya direkt erişimi varsa lateral movement riski artar. Mümkünse jump host veya bastion üzerinden tünellenmeli.
  • Audit log: XSOAR'da MCP entegrasyonu için ayrı bir API key oluşturup audit log'unu (Settings → Audit Trail) bu key'in aktivitesi açısından izlemek, anomali tespitini kolaylaştırır.
  • API key minimum yetki: Read-only test için "Read Only" rolü, response aksiyonları (isolate, quarantine vb.) için ek izinleri kademeli ekleyin. "Admin" rolü ile MCP key oluşturmaktan kaçının.

9. SOC Use-Case Çıkarımı

CortexSynapse-patched çalışır hale geldikten sonra MCP üzerinden kullanılabilen tool'ların bir kısmı:

Tool

Senaryo

get_incidents

"Son 24 saatte yüksek severity'li, owner'ı atanmamış incident'ları listele"

update_incident

"ID 34763'ü 'In Progress' yap ve owner'ı bana ata"

xsoar_indicators_search

"Son 7 gün içinde feed'lerden gelen IP indicator'larını getir, reputation'a göre filtrele"

xsiam_get_alerts

"Endpoint X üzerinde son 1 saatte tetiklenen alert'leri çek"

xsiam_start_xql_query

Doğal dilden XQL sorgusu kurma (LLM-assisted hunt)

xsiam_isolate / xsiam_unisolate

Endpoint izolasyonu / geri alma

xsiam_run_script

Belirli endpoint'lerde script çalıştırma (DFIR triage)

LLM-assisted SOC operasyonlarına ilgi duyan ekipler için doğal başlangıç noktaları:

  • Triage kısaltma: Yeni gelen incident'ı (get_incident_extra_data) çekip alert pattern'ini önceki kapatılmış incident'larla karşılaştırma; benzer geçmiş kararları öneri olarak sunma.
  • Detection coverage map: XSOAR'daki incident type dağılımını MITRE ATT&CK technique mapping'i ile çapraz kontrol, kapsam boşluklarını çıkarma.
  • Threat hunt explainer: Verilen bir XQL hunt sorgusunu (saia_explain_spl benzeri) doğal dile çevirme, çıktıyı geçen ay ile karşılaştırma.

 

10. Sonuç

Bu vaka, açık kaynak bir MCP sunucusunun gerçek bir kurumsal XSOAR ortamına entegrasyonunda karşılaşılan üç farklı katmandaki sorunun (env adı uyuşmazlığı, URL trailing slash, body double-encoding, multi-stage build patch konumu) sırasıyla nasıl tanımlanıp çözüldüğünü gösterdi. Bu hatalardan hiçbiri kaynaklarda yazmıyordu; her biri kaynak kodu okuyarak, direct API testleriyle ve Docker build davranışını tersine çevirerek ortaya çıktı.

SOC otomasyonunda LLM katmanını orkestrasyona bağlamak herkesin söylediği kadar tak-çalıştır bir iş değil ama hangi katmanda neyin nasıl çalıştığını bir kez kavradığınızda, tekrar kuruluşu oldukça kısalıyor.

Yorumlar

Bu blogdaki popüler yayınlar

  Splunk'ı Claude'a Bağlamak   Yapay zekâ bir SIEM'in içine girdiğinde ne olur? Doğal dil ile indeks sorgulama, sourcetype keşfi ve canlı healthcheck, gerçek bir lab ortamından notlar. *   Giriş: "Terminal Yorgunluğu" ve Bir Fikir   SOC'de yeterince yıl geçirdikten sonra fark edersiniz: asıl yorgunluk alarm sayısından değil, bağlam değiştirme maliyetinden gelir. Splunk'ta bir sorgu açarsınız, sonucu analiz edersiniz, başka bir sekmeye geçersiniz, tekrar dönersiniz. Bu döngü saatlerce sürer. Bir gün şunu düşündüm: Splunk'a doğal dil ile konuşabilsem ne olurdu? " Son 24 saatte 4625 eventlerini getir, system kullanıcılarını dışla " diyebilsem? Cevap, Model Context Protocol (MCP) ile geldi. Bu makale o serüveni anlatıyor, kurulumdan, canlı ortamdaki gerçek bulgulara kadar.   MCP Nedir? Neden Önemli?   MCP (Model Context Protocol), büyük dil modellerini dış araçlara ve veri kaynaklarına bağlayan açık bir standarttır. Anthro...
AI Entegrasyonlarında Güvenlik Riski   Bir geliştirici yeni bir Claude Desktop eklentisi keşfediyor. Kuruyor, config'e ekliyor, uygulamayı yeniden başlatıyor. Birkaç saniye içinde saldırgan sistemin tam kontrolünü ele geçiriyor, hiçbir tıklama, hiçbir onay gerekmeden. Bu makale, tam olarak bunun nasıl gerçekleştiğini anlatıyor. MCP protokolü yapay zekaya gerçek dünya ile etkileşim gücü verirken, her yeni bağlantı noktası potansiyel bir saldırı vektörü haline gelir ve sadece “veri sızıntısı” tehdidi ile karşı karşıya kalmazsınız. MCP’yi Anlamak Anthropic tarafından geliştirilen Model Bağlam Protokolünün sitesinde yer alan tanımı şöyledir: Bugün, yapay zekâ asistanlarını içerik depoları, iş araçları ve geliştirme ortamları da dahil olmak üzere verilerin bulunduğu sistemlere bağlamak için yeni bir standart olan  Model Bağlam Protokolü'nü  (MCP) açık kaynaklı hale getiriyoruz. Amacı, öncü modellerin daha iyi ve daha alakalı yanıtlar üretmesine yardımcı olmaktır [1] ...