UNPKG

mcp-emre-kalem

Version:

Test amaçlı MCP server - liste arama işlemleri

302 lines (267 loc) 7.44 kB
#!/usr/bin/env node import dotenv from 'dotenv'; import path from 'path'; // .env dosyasını mevcut çalışma dizininde ara dotenv.config({ path: path.join(process.cwd(), '.env') }); import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { sampleData } from "./data.js"; import { initializeAuth, requireAuth, getAuthStatus } from "./auth.js"; // MCP Server oluşturma const server = new Server( { name: "mcp-sample-server", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); // Araçları listeleme server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "search_items", description: "Liste içinde arama yapar. İsim, kategori, açıklama ve etiketlerde arama yapabilir.", inputSchema: { type: "object", properties: { query: { type: "string", description: "Aranacak metin", }, category: { type: "string", description: "Belirli bir kategoride arama yapmak için (opsiyonel)", }, difficulty: { type: "string", description: "Belirli bir zorluk seviyesinde arama yapmak için (opsiyonel)", }, }, required: ["query"], }, }, { name: "get_item_by_id", description: "ID'ye göre öğe getirir", inputSchema: { type: "object", properties: { id: { type: "number", description: "Getirilecek öğenin ID'si", }, }, required: ["id"], }, }, { name: "list_all_items", description: "Tüm öğeleri listeler", inputSchema: { type: "object", properties: {}, }, }, { name: "get_categories", description: "Mevcut kategorileri listeler", inputSchema: { type: "object", properties: {}, }, }, { name: "filter_by_tags", description: "Belirli etiketlere sahip öğeleri filtreler", inputSchema: { type: "object", properties: { tags: { type: "array", items: { type: "string", }, description: "Filtrelenecek etiketler", }, }, required: ["tags"], }, }, { name: "auth_status", description: "Giriş durumunu kontrol eder", inputSchema: { type: "object", properties: {}, }, }, ], }; }); // Araç çağrılarını işleme server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { // Her araç çağrısında auth kontrolü const user = requireAuth(); console.error(`🔧 Araç kullanımı: ${name} - Kullanıcı: ${user.username}`); switch (name) { case "search_items": return await searchItems(args.query, args.category, args.difficulty); case "get_item_by_id": return await getItemById(args.id); case "list_all_items": return await listAllItems(); case "get_categories": return await getCategories(); case "filter_by_tags": return await filterByTags(args.tags); case "auth_status": return await authStatus(); default: throw new Error(`Bilinmeyen araç: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `Hata: ${error.message}`, }, ], }; } }); // Arama fonksiyonu async function searchItems(query, category = null, difficulty = null) { const searchTerm = query.toLowerCase(); let results = sampleData.filter(item => { const matchesQuery = item.name.toLowerCase().includes(searchTerm) || item.description.toLowerCase().includes(searchTerm) || item.tags.some(tag => tag.toLowerCase().includes(searchTerm)); const matchesCategory = !category || item.category.toLowerCase() === category.toLowerCase(); const matchesDifficulty = !difficulty || item.difficulty.toLowerCase() === difficulty.toLowerCase(); return matchesQuery && matchesCategory && matchesDifficulty; }); return { content: [ { type: "text", text: `Arama sonuçları "${query}" için:\n\n${formatResults(results)}`, }, ], }; } // ID'ye göre öğe getirme async function getItemById(id) { const item = sampleData.find(item => item.id === id); if (!item) { throw new Error(`ID ${id} ile öğe bulunamadı`); } return { content: [ { type: "text", text: formatSingleItem(item), }, ], }; } // Tüm öğeleri listeleme async function listAllItems() { return { content: [ { type: "text", text: `Tüm öğeler (${sampleData.length} adet):\n\n${formatResults(sampleData)}`, }, ], }; } // Kategorileri listeleme async function getCategories() { const categories = [...new Set(sampleData.map(item => item.category))]; return { content: [ { type: "text", text: `Mevcut kategoriler:\n${categories.map(cat => `• ${cat}`).join('\n')}`, }, ], }; } // Etiketlere göre filtreleme async function filterByTags(tags) { const results = sampleData.filter(item => tags.some(tag => item.tags.some(itemTag => itemTag.toLowerCase().includes(tag.toLowerCase()) ) ) ); return { content: [ { type: "text", text: `"${tags.join(', ')}" etiketlerine sahip öğeler:\n\n${formatResults(results)}`, }, ], }; } // Sonuçları formatlama function formatResults(items) { if (items.length === 0) { return "Sonuç bulunamadı."; } return items.map(item => formatSingleItem(item)).join('\n---\n'); } // Tek öğeyi formatlama function formatSingleItem(item) { return `🆔 ID: ${item.id} 📛 İsim: ${item.name} 📂 Kategori: ${item.category} 📝 Açıklama: ${item.description} ⚡ Zorluk: ${item.difficulty} 🏷️ Etiketler: ${item.tags.join(', ')}`; } // Auth durumu async function authStatus() { const status = getAuthStatus(); return { content: [ { type: "text", text: status.authenticated ? `✅ Giriş yapılmış\n👤 Kullanıcı: ${status.name}\n📧 Email: ${status.user}` : "❌ Giriş yapılmamış", }, ], }; } // Server'ı başlatma async function main() { console.error("🚀 MCP Server başlatılıyor..."); // Microsoft auth kontrolü const authSuccess = await initializeAuth(); if (!authSuccess) { console.error("❌ Authentication başarısız - Server kapatılıyor"); process.exit(1); } const transport = new StdioServerTransport(); await server.connect(transport); console.error("✅ MCP Server başlatıldı ve Microsoft auth aktif!"); } main().catch((error) => { console.error("Server hatası:", error); process.exit(1); });