AFETNET Afet Veri Omurgası

MCP — Açık Erişim

ilk72 v0.1.0 protokol 2024-11-05 51 çağrı işlendi

MCP (Model Context Protocol), bir yapay zekâ asistanının dış bir veri kaynağına bağlanmasını sağlayan açık standarttır. İLK72'nin afet veri omurgası bu protokolle dışarıya açıktır: bir STK, belediye ya da gönüllü grup kendi Claude'una bu sunucuyu ekleyip "Bağcılar'da hangi ihtiyaçlar karşılanmadı?" diye sorabilir, sahadan topladığı veriyi de aynı yerden sisteme yazabilir.

Afet verisi tek kurumun tekelinde olmamalı. Bu yüzden okuma araçları API anahtarı istemez — anahtar verirseniz çağrılarınız kurumunuz adına loglanır, vermezseniz de veri açıktır. Kişisel veri (hane kaydı) KVKK gereği maskelenerek döner.

İLK72 bir uygulama değil, bir afet işletim sistemi: insanlar panelleri kullanır, makineler ve yapay zekâ ajanları MCP'yi kullanır. Aşağıdaki iki senaryo tam olarak bunun için var.

İki gerçek ajan senaryosu

Bunlar temsili değil — aşağıdaki çağrılar bu sunucuda birebir çalışır.

Senaryo 1 — Saha ajanı

"Antakya'nın kuzeyinde jeneratör ihtiyacı olan ama henüz jeneratör gönderilmemiş noktaları getir."

{"method":"tools/call","params":{
  "name":"ihtiyac_ozet",
  "arguments":{
    "yon":"ihtiyac",
    "kalem":"jeneratör",
    "ilce":"Antakya",
    "sadece_karsilanmamis":true }}}
sadece_karsilanmamis = durumu hâlâ acik VE hiçbir arzla eşleşmemiş kayıtlar. Yani "oraya henüz kimse bir şey göndermedi". Dönen her nokta lat/lon, miktar, birim ve aciliyetle gelir.
Senaryo 2 — Lojistik ajanı

"Ankara'dan 20 jeneratörümüz var, optimum dağıt."

1) ihtiyac_ozet(yon="ihtiyac", kalem="jeneratör",
                sadece_karsilanmamis=true)
   → karşılanmamış noktalar + koordinat + aciliyet

2) yol_durumu(ilce="...")
   → hangi rota kapalı, bilgi kaç saatlik

3) kayit_ekle(kaynak="stk", ham_metin="20 jeneratör
   Ankara'dan yola çıktı, dağıtım: ...")
   → planı omurgaya geri yaz

4) olay_guncelle(kume_id=..., durum="ekip_atandi")
Ajan okuma + yazma döngüsünü tek sunucudan kapatır. Yazdığı plan başka ajanlar için anında görünür olur.

Veri bayatlar — her yanıt bunu söyler

Saat 09:00'da "yol kapalı" olan bilgi 13:00'te yanlış olabilir. Bir ajanın kaç saattir doğrulanmamış veriye baktığını bilmesi gerekir. Bu yüzden her okuma aracının döndürdüğü her satırda şu alanlar var:

son_dogrulama

Verinin son teyit edildiği damga.

yas_saat

O günden bu yana geçen saat.

tazelik

taze (≤3sa) · eskimeye_basladi (≤12sa) · bayat (>12sa)

guven

0-100. Kümede çok kaynaklı doğrulamayla artar.

yol_durumu ayrıca zaman-geçerli kayıt tutar: varsayılan olarak yalnızca hâlâ geçerli satırlar döner, gecmis_dahil=true ile "09:00 kapalı → 13:00 açıldı" izini sürebilirsiniz.

Uç nokta

Adres
https://afetnet.spatly.io/mcp/rpc
Taşıma
JSON-RPC 2.0 / HTTP POST
Kimlik
Bearer <api_anahtari> (opsiyonel)

Canlı deneme tezgâhı

Kurulum yapmadan deneyin: aşağıdaki istek gerçekten POST /mcp/rpc adresine gider, yanıt bu sayfada görünür ve çağrı aşağıdaki kullanım kaydına düşer.

Hazır.

Henüz çağrı yapılmadı.

Araçlar

11 araç. Açıklamalar LLM'in hangi soruda hangi aracı seçeceğini anlaması için yazıldı.

kayit_ekle YAZMA

Sahadan gelen HAM bir ihbarı/bilgiyi İLK72 omurgasına yazar. STK, gönüllü grup, telsiz operatörü ya da vatandaş elindeki bilgiyi buraya girer. Metni olduğu gibi gönder — normalize etmeye çalışma, sistemin LLM triyajı kategoriyi, ilçeyi, aciliyeti çıkarır ve mükerrerse mevcut olay kümesine bağlar. KULLAN: kullanıcı 'şunu sisteme gir / şu ihbarı ilet / elimde şu bilgi var' dediğinde.

Parametre Tip Zorunlu Açıklama
kaynak string evet Bilginin geldiği kanal. stk=sivil toplum kuruluşu, telsiz=amatör telsiz, saha_ekibi=arama kurtarma/AFAD ekibi, vatandas=doğrudan vatandaş, twitter=sosyal medya.
stk | telsiz | saha_ekibi | vatandas | twitter | cagri_merkezi | mcp
ham_metin string evet İhbarın ham metni. Adres, kişi sayısı, ihtiyaç ne varsa olduğu gibi yaz. Kısaltma/özetleme yapma.
kaynak_ref string hayır İsteğe bağlı iz kaydı: tweet id, telsiz frekans/saat, STK kayıt numarası. API anahtarıyla gelindiyse otomatik doldurulur.
Gerçek sunucuya JSON-RPC isteği gider.
kayit_ara OKUMA

HAM kayıtlarda arama yapar (henüz kümelenmemiş olanlar dahil). Serbest metin, ilçe, kategori ve kaynağa göre filtreler. KULLAN: 'X mahallesinde ne bildirilmiş', 'jeneratör talebi var mı', 'telsizden ne geldi' gibi ham veri sorularında. Doğrulanmış/tekilleştirilmiş olay listesi istiyorsan bunun yerine kume_listele kullan.

Parametre Tip Zorunlu Açıklama
sorgu string hayır Serbest metin (ham metin, adres ve ihtiyaç kaleminde aranır).
ilce string hayır İlçe adı, örn. Bağcılar.
kategori string hayır LLM triyajının atadığı kategori.
enkaz_altinda | yarali | ihtiyac | arz | yol_durumu | bina_hasari | kayip | bilgi | alakasiz
kaynak string hayır Sadece bu kanaldan gelenler.
stk | telsiz | saha_ekibi | vatandas | twitter | cagri_merkezi | mcp
elenenler_dahil boolean hayır true ise troll/alakasız diye elenen kayıtlar da döner (şeffaflık denetimi için).
limit integer hayır Kaç kayıt dönsün (varsayılan 20, en fazla 200).
Gerçek sunucuya JSON-RPC isteği gider.
kume_listele OKUMA

DOĞRULANMIŞ olay kümelerini listeler. Aynı olaya ait mükerrer ihbarlar tek kümede birleştirilmiştir; kaç kayıttan ve kaç FARKLI kaynak türünden doğrulandığı görünür (çok kaynak = yüksek güven). Karar vermek, ekip yönlendirmek, öncelik sıralamak için asıl kullanılacak araç budur. KULLAN: 'nerede acil müdahale gerekiyor', 'Bağcılar'da açık olaylar neler', 'güveni yüksek ihbarlar' sorularında.

Parametre Tip Zorunlu Açıklama
durum string hayır acik=henüz ekip yok, ekip_atandi=yolda, cozuldu=kapandı.
acik | ekip_atandi | cozuldu
min_guven integer hayır 0-100. Örn. 70 verirsen sadece çok kaynaklı doğrulanmış kümeler döner.
ilce string hayır İlçe adı.
kategori string hayır enkaz_altinda, ihtiyac, yol_durumu vb.
limit integer hayır Varsayılan 20, en fazla 200.
Gerçek sunucuya JSON-RPC isteği gider.
sessiz_bolgeler OKUMA

SİNYAL YOKLUĞUNU veri olarak okur. İBB 7.5 senaryosuna göre yüksek etki beklenen (çok sayıda geçici barınma ihtiyacı, ağır hasar) ama sahadan hiç/çok az kayıt gelen mahalleleri risk skoruna göre sıralar. Sinyal gelmemesi 'orada sorun yok' demek değildir — 'oraya ULAŞILAMIYOR' demek olabilir; keşif ekibi bu listeye göre yönlendirilir. KULLAN: 'nereye ekip göndermeliyiz', 'unuttuğumuz yer var mı', 'hiç haber alamadığımız yerler' sorularında.

Parametre Tip Zorunlu Açıklama
ilce string hayır Tek ilçeye daralt.
esik_kayit integer hayır Bu sayıdan az kayıt gelen mahalleler sessiz sayılır (varsayılan 2).
limit integer hayır Varsayılan 20.
Gerçek sunucuya JSON-RPC isteği gider.
ihtiyac_ozet OKUMA

İhtiyaç ↔ arz verisini iki düzeyde döner: (a) noktalar — tek tek talep/arz kayıtları, lat/lon, miktar, birim, aciliyet ve 'karsilanmamis' bayrağıyla; (b) acik_kalemler / fazla_kalemler — ilçe+kalem bazında toplam denge. KULLAN: 'Antakya'nın kuzeyinde jeneratör ihtiyacı olan ama henüz jeneratör gönderilmemiş noktaları getir' → yon='ihtiyac', kalem='jeneratör', sadece_karsilanmamis=true. 'Ankara'dan 20 jeneratörümüz var, optimum dağıt' → aynı çağrıyla karşılanmamış noktaları koordinat ve aciliyetle al, sonra kendi dağıtım planını kur. 'Elimizde fazla ne var' → fazla_kalemler'e bak. Sadece arzları görmek için yon='arz'.

Parametre Tip Zorunlu Açıklama
yon string hayır ihtiyac=talepler, arz=eldeki kaynaklar. Boş bırakırsan ikisi de.
ihtiyac | arz
ilce string hayır İlçeye daralt, örn. Bağcılar.
kalem string hayır Kalem adı filtresi, örn. 'jeneratör', 'mama', 'su', 'çadır'.
sadece_karsilanmamis boolean hayır true ise sadece durumu 'acik' olan, yani henüz eşleşmemiş/gönderilmemiş kayıtlar döner. 'Henüz kimsenin göndermediği yerler' sorusunun cevabı budur.
min_aciliyet integer hayır 0-100. Örn. 70 verirsen sadece kritik talepler.
limit integer hayır Nokta sayısı tavanı (varsayılan 100, en fazla 500).
Gerçek sunucuya JSON-RPC isteği gider.
yol_durumu OKUMA

Yolların açık/kapalı/kısıtlı durumunu döner — lojistik ve sevkiyat rotası için. Yol bilgisi en hızlı bayatlayan veridir; her satırda kaç saattir doğrulanmadığı (yas_saat, tazelik) gelir, 'bayat' satırlara güvenip rota kurma. KULLAN: 'X ilçesine araç girebiliyor mu', 'hangi yollar kapalı', 'sevkiyat rotası planla' sorularında. Yol tablosu henüz kurulmadıysa boş liste ve yönlendirme döner (o durumda kume_listele(kategori='yol_durumu') kullan).

Parametre Tip Zorunlu Açıklama
ilce string hayır İlçeye daralt.
durum string hayır Yolun durumu.
acik | kapali | kismi | bilinmiyor
sorgu string hayır Yol adı / açıklamada serbest metin arama, örn. 'D400'.
gecmis_dahil boolean hayır Varsayılan false — sadece HÂLÂ GEÇERLİ kayıtlar döner (kapanmış ya da yerine yenisi geçmiş kayıtlar hariç). true yaparsan yolun geçmiş durum değişimlerini de görürsün ('09:00 kapalı → 13:00 açıldı' izini sürmek için).
limit integer hayır Varsayılan 50.
Gerçek sunucuya JSON-RPC isteği gider.
olay_guncelle YAZMA

Bir olay kümesinin durumunu sahadan gelen bilgiyle günceller: ekip atandı mı, çözüldü mü, aciliyeti değişti mi, ek not var mı. Güncelleme aynı zamanda DOĞRULAMA sayılır — olayın tazelik damgası yenilenir, böylece diğer ajanlar bayat veriye bakmaz. KULLAN: 'bu olaya ekibimizi gönderdik', 'X numaralı olay çözüldü', 'olay hâlâ geçerli, teyit ettik' dendiğinde. kume_id'yi önce kume_listele ile al.

Parametre Tip Zorunlu Açıklama
kume_id integer evet kume_listele'den gelen olay id'si.
durum string hayır Yeni durum.
acik | ekip_atandi | cozuldu
atanan_ekip string hayır Sahaya giden ekibin adı, örn. 'AKUT-3' veya STK adı.
aciliyet integer hayır 0-100, sahadan gelen yeni aciliyet değerlendirmesi.
not_metni string hayır Olayın özetine iz kaydı olarak eklenecek not (kim/ne zaman damgalanır).
Gerçek sunucuya JSON-RPC isteği gider.
barinak_durum OKUMA

Barınakların kapasite/doluluk durumunu ve özel imkânlarını (engelli erişimi, bebek dostu, evcil hayvan kabulü, sağlık birimi) listeler. Bir haneyi yerleştirirken önce buradan uygun barınak bulunur. KULLAN: 'boş yer var mı', 'engelli erişimli barınak nerede', 'evcil hayvanıyla gelen aileyi nereye' sorularında.

Parametre Tip Zorunlu Açıklama
ilce string hayır İlçeye daralt.
tip string hayır
cadir_kent | konteyner | yurt | spor_salonu | otel
sadece_bos boolean hayır true ise sadece boş kapasitesi olanlar.
engelli_erisim boolean hayır true ise sadece engelli erişimli.
bebek_dostu boolean hayır true ise sadece bebek dostu.
evcil_kabul boolean hayır true ise sadece evcil hayvan kabul edenler.
saglik_birimi boolean hayır true ise sadece sağlık birimi olanlar.
limit integer hayır Varsayılan 50.
Gerçek sunucuya JSON-RPC isteği gider.
hane_sorgula OKUMA KVKK MASKELİ

Hane kodu (HANE-XXXXXX, QR'da yazan kod) ile bir hanenin kaydını, özel ihtiyaçlarını (bebek/gebe/yaşlı/engelli/kronik hasta/evcil), hak pusulasını ve barınak yerleşimini getirir. KVKK gereği ad-soyad ve telefon MASKELENEREK döner (Ay*** Y***, 053*****67); MCP üzerinden kişisel veri ham haliyle dışarı verilmez. KULLAN: 'HANE-000123 nerede kaldı', 'bu hanenin hakları neler', 'kuyrukta kaçıncı sırada' sorularında.

Parametre Tip Zorunlu Açıklama
kod string evet Hane kodu, örn. HANE-000123.
Gerçek sunucuya JSON-RPC isteği gider.
istatistik OKUMA

Sistem geneli özet: toplam/işlenen/bekleyen/elenen ham kayıt, kaynak ve kategori dağılımı, olay kümeleri, mükerrer eleme kazancı, açık ihtiyaç-arz satırları, barınma kapasitesi, sessiz bölge/keşif görevi sayısı ve MCP çağrı istatistiği. KULLAN: 'durum ne', 'genel tablo', 'kaç ihbar geldi' sorularında ya da başka bir araca dalmadan önce ölçek almak için.

Parametre almaz.

Gerçek sunucuya JSON-RPC isteği gider.
sor OKUMA

Afet durumu hakkında SERBEST TÜRKÇE SORU sor. Sistem soruyu anlar, kendi veri tabanından doğru veriyi bulur ve KAYNAĞIYLA birlikte cevaplar. Örnek: 'Antakya'nın kuzeyinde jeneratör ihtiyacı olan ama henüz gönderilmemiş noktalar hangileri?' Nasıl çalışır: soruya göre sistemin veri yeteneklerinden biri seçilir (sessiz bölgeler, olay kümeleri, ham ihbar arama, ihtiyaç/arz dengesi, barınak kapasitesi, yol durumu, gönüllü hunisi, görevler, hak pusulası, genel istatistik), sabit ve parametreli sorgularla çalıştırılır — model SQL YAZMAZ. Çıktıda cevabın yanında hangi yeteneğin hangi parametrelerle çağrıldığı ve dayanak alınan HAM VERİ döner; veri yoksa cevap uydurulmaz. KULLAN: hangi aracı çağıracağından emin olmadığın her doğal dil sorusunda, ya da tek soruda birden çok tabloya bakılması gerektiğinde bunu ilk adım olarak kullan. Belirli bir alanı zaten biliyorsan (ör. sadece yol durumu) o özel aracı kullanmak daha hızlıdır.

Parametre Tip Zorunlu Açıklama
soru string evet Serbest Türkçe soru. Kısaltma yapma, kullanıcının sorusunu olduğu gibi ilet; ilçe/mahalle/ihtiyaç kalemi geçiyorsa cümlede kalsın — sistem onları parametreye çevirir.
Gerçek sunucuya JSON-RPC isteği gider.

Kendi Claude'una bağla

Kopyala-yapıştır. Sunucu HTTP taşımalı olduğu için mcp-remote köprüsü kullanılır (Node 18+ gerekir).

Claude Desktop — claude_desktop_config.json
{
  "mcpServers": {
    "ilk72": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://afetnet.spatly.io/mcp/rpc",
        "--transport", "http-only"
      ]
    }
  }
}
Claude Code — tek komut
claude mcp add ilk72 -- \
  npx -y mcp-remote \
  https://afetnet.spatly.io/mcp/rpc \
  --transport http-only

# API anahtarınız varsa (çağrılar kurumunuz
# adına loglanır, okuma için şart değil):
claude mcp add ilk72 -- \
  npx -y mcp-remote \
  https://afetnet.spatly.io/mcp/rpc \
  --transport http-only \
  --header "Authorization: Bearer STK_ANAHTARINIZ"

Bağlandıktan sonra Claude'a şunu sorabilirsiniz: "İLK72'de Bağcılar'da açık olan, güveni 70'in üstündeki olayları listele ve hangi ihtiyaç kalemleri karşılanmamış söyle."

Çalışan curl örnekleri

1 — El sıkışma (initialize)
curl -s https://afetnet.spatly.io/mcp/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2024-11-05",
                 "clientInfo":{"name":"stk-demo","version":"1.0"}}}'
{"jsonrpc":"2.0","id":1,"result":{
  "protocolVersion":"2024-11-05",
  "capabilities":{"tools":{"listChanged":false},"logging":{}},
  "serverInfo":{"name":"ilk72","version":"0.1.0"}, ...}}
2 — Araç listesi (tools/list)
curl -s https://afetnet.spatly.io/mcp/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | python3 -c 'import sys,json;[print("-",t["name"]) for t in json.load(sys.stdin)["result"]["tools"]]'
- kayit_ekle
- kayit_ara
- kume_listele
- sessiz_bolgeler
- ihtiyac_ozet
- yol_durumu
- olay_guncelle
- barinak_durum
- hane_sorgula
- istatistik
3 — Sahadan veri gir (kayit_ekle)
curl -s https://afetnet.spatly.io/mcp/rpc \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer STK_ANAHTARINIZ' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
        "name":"kayit_ekle",
        "arguments":{"kaynak":"stk",
          "ham_metin":"Bağcılar Kirazlı Mah. 3 katlı bina yıkık, 2 kişi enkaz altında, jeneratör lazım."}}}'
{"content":[{"type":"text","text":"{
  \"kayit_id\": 41,
  \"durum\": \"kuyruğa alındı\",
  \"islendi\": 0,
  \"not\": \"Kayıt ham haliyle saklandı. LLM triyajı normalize edip mükerrerse mevcut kümeye bağlayacak.\"
}"}],"isError":false}
4 — Sessiz bölgeler (sessiz_bolgeler) — projenin en güçlü argümanı
curl -s https://afetnet.spatly.io/mcp/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{
        "name":"sessiz_bolgeler","arguments":{"limit":3}}}'
"bolgeler": [{
  "mahalle": "Sessizköy", "ilce": "Avcılar",
  "beklenen_barinma": 4200, "gelen_kayit": 0, "risk_skoru": 100,
  "yorum": "Sessizköy (Avcılar): 4200 kişilik geçici barınma beklenirken
            sahadan 0 kayıt geldi. Hiç sinyal yok — ulaşılamaz varsayılmalı.",
  "oneri": "Keşif görevi aç"
}]

Canlı MCP trafiği

Son 20 çağrı. Bu tablo, "dışarıdan herkes veri girip çekebiliyor" iddiasının kanıtıdır — her satır gerçek bir dış çağrı.

Zaman İstemci Araç Özet
16:33:42 api ajan:durum_ozeti Operasyon durum özeti
16:18:36 anonim kume_durum küme 4 -> ekip_atandi (Belediye Saha Ekibi)
16:18:16 anonim triyaj_calistir 0 kayıt -> 0 küme (0 birleşti, mod=yedek)
16:08:01 anonim yol_durumu {} → 5 sonuç
16:08:01 anonim ihtiyac_ozet {} → 17 sonuç
16:08:00 anonim sessiz_bolgeler {} → 20 sonuç
16:05:59 anonim kume_durum küme 3 -> ekip_atandi (AFAD Arama Kurtarma-2)
16:04:45 anonim triyaj_calistir 0 kayıt -> 0 küme (0 birleşti, mod=yedek)
16:04:40 anonim kume_durum küme 7 -> ekip_atandi (-)
16:04:34 anonim triyaj_calistir 0 kayıt -> 0 küme (0 birleşti, mod=yedek)
16:03:15 anonim kume_durum küme 1 -> ekip_atandi (AKUT-3)
16:02:56 anonim kume_listele {"limit": 3} → 3 sonuç
16:02:55 anonim istatistik {}
16:01:35 anonim kume_durum küme 1 -> ekip_atandi (-)
15:40:23 anonim kume_durum küme 1 -> ekip_atandi (-)
15:40:19 anonim kume_durum küme 7 -> ekip_atandi (-)
15:17:08 report#35->kume#17 karar:BIRLESTIR report #35 -> #17 İLE BİRLEŞTİR (%87 aynı olay)
15:17:08 report#34->kume#17 karar:BIRLESTIR report #34 -> #17 İLE BİRLEŞTİR (%87 aynı olay)
15:17:08 report#33->kume#17 karar:BIRLESTIR report #33 -> #17 İLE BİRLEŞTİR (%87 aynı olay)
15:17:08 report#32->kume#17 karar:YENI_OLAY_OLUSTUR report #32 -> YENİ OLAY #17: Gülsuyu Mahallesi Çökmüş Yapı — Maltepe/Gülsuyu

Neden açık?

Depremin ilk 72 saatinde veriyi bekletmenin bedeli can. Bu yüzden İLK72 kapalı bir kurum yazılımı değil, üstüne herkesin bağlanabildiği bir omurga olarak tasarlandı: kurumlar kendi sistemlerini bunun üstüne kurabilir, STK'lar kendi verilerini besleyebilir, gönüllü geliştiriciler yeni senaryolar ekleyebilir. Şema ve MCP sunucusu açık; sahiplenmek için izin almanız gerekmiyor.