mcp-openapi-demo
README.md
# mcp-openapi-demo
Model Context Protocol
“LLM function calling” mekanizması ile MCP’yi otomatik tetikleyen küçük bir demo.
## 📂 Proje Dizini
```
mcp-openapi-demo/
│
├── server.js # Node.js tarafı → MCP Server (Petstore API)
├── package.json # Node bağımlılıkları
├── .env # Ortam değişkenleri (API anahtarı vs.)
└── python-client/
├── client.py # Python tarafı → MCP Client (OpenAI entegrasyonu ile)
```
## Proje Nasıl Çalışır
👉 Modele sadece “Find available pets” denir.
👉 Model, kendi isteğiyle function call yapacak.
👉 Python kodu, bu function call’u yakalayacak, MCP server’a yönlendirecek, cevabı alacak.
👉 Sonucu tekrar modele verip son yanıtı yazdıracak.
---
# 🚀 Adım 1: MCP Server’ı Çalıştır
Önce Node.js tarafını aç ve terminalde:
```bash
cd mcp-openapi-demo
node server.js
```
Eğer doğruysa:
```
🚀 MCP Server running on http://localhost:4000
```
mesajını görmen lazım ✅
---
# 🚀 Adım 2: Python Ortamını Kur
Python client klasörüne geç:
```bash
cd python-client
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install requests openai
```
---
# 🚀 Adım 3: OpenAI API Key Ayarla
API anahtarını `.env` dosyasına yazabilirsin:
```
OPENAI_API_KEY=senin_api_key
```
Python kodunda anahtarı almak için `python-dotenv` paketini kur:
```bash
pip install python-dotenv
```
Ve `client.py` içinde şöyle ekle:
```python
from dotenv import load_dotenv
load_dotenv()
```
Artık anahtar otomatik olarak `.env` dosyasından alınacak.
---
# 🚀 Adım 4: Python Client Çalıştır
```bash
python client.py
```
Beklenen çıktı:
1. Önce **Petstore API’den gelen JSON** → yani “available pets” listesi.
2. Ardından **OpenAI modelinin doğal dilde özeti** → mesela “There are 20 available pets, most are dogs and cats...” gibi.
📌 Özetle:
* Node.js tarafı → Petstore MCP Server
* Python tarafı → Hem MCP’den veri çekiyor hem de OpenAI modeline verip yorum alıyor
## LLM Function Calling Mekanizması Nasıl Çalışır?
👉 Modelin `"find_available_pets"` fonksiyonunu çağırması **senin yazdığın prompt + ona verdiğin `tools` tanımı sayesinde** oluyor. Yani bu çağrı **senin API çağrının bir yanıtı olarak, modelin output’unda** gerçekleşiyor.
### 📍 Nerede olur?
OpenAI’nin `chat.completions.create` cevabında olur.
Örneğin Python’da:
```python
from openai import OpenAI
client = OpenAI()
tools = [
{
"type": "function",
"function": {
"name": "find_available_pets",
"description": "Find pets in the Petstore API by status",
"parameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["available", "pending", "sold"]
}
},
"required": ["status"],
},
}
}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Can you show me all available pets?"}
],
tools=tools
)
print(response.choices[0].message)
```
### 📍 Modelin cevabı nasıl olur?
Model sana düz metin dönmez, **function call döner**:
```json
{
"role": "assistant",
"tool_calls": [
{
"id": "call_1",
"type": "function",
"function": {
"name": "find_available_pets",
"arguments": "{ \"status\": \"available\" }"
}
}
]
}
```
### 📍 Sen ne yaparsın?
1. Buradaki `function.name` ve `arguments` değerini alırsın.
2. Bu bilgiyi MCP server’a **JSON-RPC request** olarak gönderirsin (`pet/findByStatus`).
3. Dönen cevabı tekrar modele verirsin →
```python
client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Can you show me all available pets?"},
response.choices[0].message, # function call çıktısı
{
"role": "tool",
"tool_call_id": response.choices[0].message.tool_calls[0].id,
"content": json.dumps(mcp_result)
}
]
)
```
✅ Yani “find\_available\_pets” çağrısı **senin kodunda değil, modelin output’unda gerçekleşiyor.**
Sen sadece bu function call’u yakalayıp **gerçekten çalıştırıyorsun** (MCP’ye gönderiyorsun).
### tam zincir:
kullanıcı → LLM → function call → MCP → sonuç → tekrar LLM
## Tool tanımındaki description mı süreci etkiliyor?
Aynen öyle ✅ — tool tanımındaki **description** kısmı sürecin en kritik parçalarından biri.
LLM, kullanıcı mesajını alıyor → sonra kendisine senin verdiğin **tool schema**yı inceliyor.
Tool’un **adı**, **parametreleri** ve özellikle **description** kısmı, modelin hangi durumda o tool’u çağıracağına karar vermesini sağlıyor.
🔎 **Detaylı olarak etkileyen faktörler:**
1. **Tool adı (`name`)**
* Model için bir “anahtar kelime”.
* Ama tek başına yeterli değil, çünkü kullanıcı hep “find pets” demeyebilir.
* Örn: kullanıcı *“show me all dogs available for adoption”* derse → model description’a bakıp “bu tool adoption için available pets getiriyor” diye eşleştirir.
2. **Description (Açıklama)**
* Modelin karar verme sürecinde en güçlü sinyal.
* Buraya yazdığın açıklama ne kadar açık, görev tanımı ne kadar iyi olursa model o kadar doğru karar verir.
* Örn:
```json
"description": "Find pets that are currently available in the Petstore API. Use this function if the user asks about pets, animals, or available pets."
```
Böyle yazarsan, model daha doğru tetikler.
* Eğer description zayıfsa, model yanlış tool’u seçebilir ya da hiç tool çağırmayabilir.
3. **Parameters (şema)**
* Modelin doğru argüman üretmesini sağlar.
* Mesela enum `["available", "pending", "sold"]` dersen, model bu üç değerden birini seçecektir.
* Bu da seni gereksiz validation’dan kurtarır.
📌 **Özet:**
* **Evet, description doğrudan etkiliyor.**
* Description, modelin “hangi tool ne işe yarıyor” bilgisini anlaması için kritik.
* İyi yazılmış description → doğru tool seçimi ve doğru parametreler.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues