LLM Ajanınıza SMS Yeteneği Eklemenin Üç Yolu
LLM ajanları artık sadece soru cevaplamıyor; randevu hatırlatıyor, OTP gönderiyor, müşteriye onay alıyor. SMS bu aksiyonların büyük bölümünde devrede.
Peki bir AI ajanına SMS gönderme yeteneği nasıl eklenir? Üç yaklaşım var: function calling, MCP, ve webhook. Hepsi farklı problem çözer, çoğu üretim sisteminde ikisi birden çalışır. Bu yazıda üçünü Anthropic SDK örnekleriyle yan yana koyuyoruz.
Tüm örneklerde Claude (Anthropic SDK) ve iletiMerkezi REST API'si kullanıldı. Test hesabı yoksa panel.iletimerkezi.com üzerinden API anahtarı + hash alınır.
1. Function Calling: ajanın kendi tool kataloğu
En klasik yaklaşım. Ajanın kullanabileceği tool'ları kendiniz tanımlar, Anthropic SDK'ya tools array'i olarak geçirir, modelin tool_use cevabı geldiğinde HTTP çağrısını siz yaparsınız.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const tools = [
{
name: "send_sms",
description: "Verilen GSM numarasına SMS gönderir.",
input_schema: {
type: "object",
properties: {
to: { type: "string", description: "905XXXXXXXXX formatında numara" },
text: { type: "string", description: "Mesaj içeriği, max 160 karakter" },
sender: { type: "string", description: "Onaylı sender ID" }
},
required: ["to", "text", "sender"]
}
}
];
const response = await client.messages.create({
model: "claude-opus-4-7",
max_tokens: 1024,
tools,
messages: [{ role: "user", content: "Ahmet'e randevusunu hatırlat: yarın 14:00, 905XXXXXXXXX" }]
});
if (response.stop_reason === "tool_use") {
const toolUse = response.content.find(b => b.type === "tool_use");
if (!toolUse) {
throw new Error("Expected tool_use block in response");
}
await fetch("https://api.iletimerkezi.com/v1/send-sms/json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
request: {
authentication: {
key: process.env.ILETIMERKEZI_API_KEY,
hash: process.env.ILETIMERKEZI_API_HASH
},
order: {
sender: toolUse.input.sender,
iys: "0",
message: {
text: toolUse.input.text,
receipents: { number: [toolUse.input.to] }
}
}
}
})
});
}
Ne zaman doğru seçim:
- Tek bir model + tek bir uygulama
- Ajanın kullanacağı tool seti net ve dar
- Hash hesaplama, hata yönetimi ve retry'ı kendiniz yönetmek istiyorsunuz
- Tool implementasyonu uygulamanın iç sırlarına erişim gerektiriyor
Bedeli: her tool için tanım + HTTP çağrısı + hata yönetimi sizin sorumluluğunuzda. Yukarıdaki örnek bilgilendirme amaçlı iys: "0" gönderiyor; ticari (kampanya, promosyon) içerik gönderilecekse iys: "1" ve iysList: "BIREYSEL" veya "TACIR" eklenmesi zorunlu (detay: send-sms). iletiMerkezi'de 11 endpoint var; 11'ini de tool olarak yazmak istiyorsanız mantıklı bir bakım yükü.
2. MCP: paylaşılır tool kataloğu
Model Context Protocol, Anthropic'in çıkardığı açık standart. Tool tanımlarını uygulamadan ayırıp sunucu olarak çalıştırıyor; istemci (Claude Code, Cursor, Codex CLI, Gemini CLI, VS Code+Cline, Claude Desktop ya da kendi yazdığınız ajan) sunucuya bağlanıyor ve tool'ları otomatik keşfediyor.
iletiMerkezi tarafında @iletimerkezi/mcp-server bu işi sizin için yapıyor. Tek satır config'le 11 tool ajana açılıyor.
En hızlı yol — Claude Code (CLI) ile tek komut, user-scope:
claude mcp add iletimerkezi -s user \
-e ILETIMERKEZI_API_KEY=API_ANAHTARINIZ \
-e ILETIMERKEZI_API_HASH=HASH_DEGERINIZ \
-- npx -y @iletimerkezi/mcp-server
Cursor, Gemini CLI, VS Code+Cline ve Claude Desktop için aynı JSON şeması — örneğin Claude Desktop'ın claude_desktop_config.json dosyasına:
{
"mcpServers": {
"iletimerkezi": {
"command": "npx",
"args": ["-y", "@iletimerkezi/mcp-server"],
"env": {
"ILETIMERKEZI_API_KEY": "API_ANAHTARINIZ",
"ILETIMERKEZI_API_HASH": "HASH_DEGERINIZ"
}
}
}
}
Codex CLI ise TOML kullanır (~/.codex/config.toml). Tüm istemciler için kurulum: iim.to/mcp.
Önemli ön koşul: Panel'de Ayarlar → Güvenlik → Erişim İzinleri → API kullanımına izin ver seçeneği açık olmalı. Kapalıysa kurulum başarılı görünse de ilk tool çağrısı 401 döner.
Kendi Claude SDK ajanınızdan MCP sunucusuna bağlanmak da mümkün. Resmi @modelcontextprotocol/sdk client'ı ile MCP server'a bağlanır, tool listesini alırsınız; Anthropic SDK MCP helper'larıyla bu liste Claude API'nın tools formatına çevrilir. Tool tanımlarını elle yazmazsınız.
import { Client } from "@modelcontextprotocol/sdk/client";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio";
const transport = new StdioClientTransport({
command: "npx",
args: ["-y", "@iletimerkezi/mcp-server"],
env: {
ILETIMERKEZI_API_KEY: process.env.ILETIMERKEZI_API_KEY,
ILETIMERKEZI_API_HASH: process.env.ILETIMERKEZI_API_HASH
}
});
const mcpClient = new Client({ name: "my-agent", version: "1.0" });
await mcpClient.connect(transport);
const { tools } = await mcpClient.listTools();
Geri dönen MCP tool listesi Anthropic SDK MCP helper'ları ile Claude tools formatına çevrilerek kullanılabilir. 11 tool, manifest auto-discovery, hash hesaplama dahil.
Ne zaman doğru seçim:
- Birden fazla model veya ajan aynı yetenekleri paylaşacak
- Tool seti zamanla genişleyecek (yeni endpoint eklendikçe kod değişmeden gelmesini istiyorsunuz)
- Claude Desktop / Cursor gibi hazır istemcilerle de aynı tool'ları kullanmak istiyorsunuz
- Sağlayıcının (bu durumda iletiMerkezi'nin) tool tanımlarını ve hash hesaplamayı maintain etmesini tercih ediyorsunuz
Bedeli: ekstra bir process (MCP server). Ortam yönetimi function calling'e göre bir adım daha karmaşık.
3. Webhook: senkron değil, event-driven
Function calling ve MCP, ajanın çıkış kanalı. Webhook ise SMS sisteminden ajana doğru akan giriş kanalı.
Kullanım senaryoları:
- Bir DLR (Delivery Report) geldiğinde ajanın "müşteriye ulaşamadık, fallback olarak email at" diye karar vermesi
- Müşterinin gelen SMS yanıtının (
STOP, EVET, sayı kodu) ajan tarafından işlenmesi - Uzun süreli akışlar: ajan gönderir, dakikalar/saatler sonra cevap işlenir
iletiMerkezi tarafında webhook URL'i panel.iletimerkezi.com → Ayarlar → API → Bildirim Adresi altından tanımlanır. Her durum güncellemesinde belirttiğiniz URL'ye POST gelir; payload { report: { id, packet_id, status, to, body } } yapısındadır ve status değerleri accepted | delivered | undelivered. Webhook handler'ı genelde Cloudflare Worker, Vercel Function veya kendi backend'iniz olur:
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const payload = await request.json();
const report = payload.report;
if (report.status === "delivered" || report.status === "undelivered") {
await env.AGENT_QUEUE.send({
type: "sms_status",
id: report.id,
packetId: report.packet_id,
recipient: report.to,
status: report.status,
body: report.body
});
}
return new Response("OK", { status: 200 });
}
};
Detay: webhooks dokümantasyonu.
Ajan bu queue'dan event'leri okuyup karar verir. Tek bir HTTP turunda çözülemeyen, dakikalarca süren akışlarda webhook olmadan olmaz.
Ne zaman doğru seçim:
- DLR ve gelen mesajları ajan akışına dahil etmek istiyorsunuz
- "Gönder ve unut" yetmez, sonucu izlemek gerekir
- Ajanın multi-step bir akışta beklemesi gerekiyor (kullanıcı SMS ile cevap verene kadar)
Bedeli: ekstra altyapı (webhook handler + queue + state). Sadece outbound senaryoda overkill.
Karşılaştırma
| Function calling | MCP | Webhook |
|---|
| Yön | Outbound (ajan → SMS) | Outbound (ajan → SMS) | Inbound (SMS → ajan) |
| Tool tanımı | Sizde | Sağlayıcıda | Yok |
| Yeni endpoint | Kod değişikliği | Otomatik | Yok |
| Çoklu model uyumu | Modele bağlı | Standart | N/A |
| Kurulum maliyeti | Düşük | Çok düşük | Orta-yüksek |
| Asenkron geri dönüş / inbound event | Hayır | Hayır | Evet |
Pratik öneri
Çoğu üretim sistemi ikisini birden kullanıyor: MCP outbound + webhook inbound.
- Ajan, kullanıcı isteğine göre SMS gönderirken MCP üzerinden 11 tool'a erişir
- Sistem, DLR ve gelen yanıtları webhook ile alır, ajan akışına geri besler
- Function calling, MCP'nin örtmediği uygulama-özel iç tool'lar için (örn. CRM kaydı güncelleme) kullanılır
Tek bir model + dar bir akış kuruyorsanız function calling yeter. Birden fazla ajan veya istemci aynı SMS yeteneklerini paylaşacaksa MCP ile başlayın; tool seti büyüdükçe getirisi artar.
Kaynaklar
SMS API ile entegrasyona başlayın
Detaylı dokümantasyon ve örnek kodlarla dakikalar içinde entegre edin.
Dokümantasyona Git