Skip to main content
Glama
index.js41.5 kB
#!/usr/bin/env node import 'dotenv/config'; 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 { generateToken, verifyToken, hashPassword, comparePassword, extractUserFromToken, checkPermissionWithToken, validateRole } from './auth.js'; import { readDatabase, writeDatabase, generateId, searchUsers } from './database.js'; import { PERMISSIONS, ROLES, hasPermission, requirePermission, getUserPermissions } from './permissions.js'; import { auditLogger, getAllAuditLogs, getUserAuditLogs, getAuditLogsByCategory, getAuditLogsByDateRange, AUDIT_CATEGORIES, AUDIT_LEVELS } from './audit.js'; // MCP Server oluştur const server = new Server( { name: 'json-database', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); // Tool listesi server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ // Kimlik doğrulama araçları { name: 'register', description: 'Yeni kullanıcı kaydı oluşturur', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Kullanıcı adı' }, email: { type: 'string', description: 'E-posta adresi' }, password: { type: 'string', description: 'Şifre' }, department: { type: 'string', description: 'Departman' }, position: { type: 'string', description: 'Pozisyon' }, role: { type: 'string', enum: ['admin', 'manager', 'employee'], description: 'Kullanıcı rolü' } }, required: ['name', 'email', 'password', 'department', 'position'] } }, { name: 'login', description: 'Kullanıcı giriş yapar ve JWT token alır', inputSchema: { type: 'object', properties: { email: { type: 'string', description: 'Kullanıcı e-posta adresi' }, password: { type: 'string', description: 'Kullanıcı şifresi' } }, required: ['email', 'password'] } }, { name: 'verify_token', description: 'JWT token\'ın geçerliliğini kontrol eder', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' } }, required: ['token'] } }, { name: 'change_password', description: 'Kullanıcı şifresini değiştirir', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, oldPassword: { type: 'string', description: 'Mevcut şifre' }, newPassword: { type: 'string', description: 'Yeni şifre' } }, required: ['token', 'oldPassword', 'newPassword'] } }, { name: 'get_my_permissions', description: 'Kullanıcının sahip olduğu yetkileri listeler', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' } }, required: ['token'] } }, // Telefon Transkript Yönetimi { name: 'list_call_transcripts', description: 'Telefon görüşmeleri transkriptlerini listeler', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, limit: { type: 'number', description: 'Gösterilecek kayıt sayısı (varsayılan: 50)' }, category: { type: 'string', description: 'Kategori filtresi (destek, satış, şikayet)' }, sentiment: { type: 'string', description: 'Duygu durumu filtresi (positive, negative, neutral)' } }, required: ['token'] } }, { name: 'get_call_transcript_by_id', description: 'ID\'ye göre telefon transkripti getirir', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, id: { type: 'number', description: 'Transkript ID\'si' } }, required: ['token', 'id'] } }, { name: 'search_call_transcripts', description: 'Transkriptlerde anahtar kelime arama yapar', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, query: { type: 'string', description: 'Aranacak kelime veya cümle' }, searchIn: { type: 'string', description: 'Arama alanı (transcript, callerName, keywords)', enum: ['transcript', 'callerName', 'keywords', 'all'] } }, required: ['token', 'query'] } }, { name: 'add_call_transcript', description: 'Yeni telefon görüşmesi transkripti ekler', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, callerPhone: { type: 'string', description: 'Arayan telefon numarası' }, callerName: { type: 'string', description: 'Arayan kişi adı' }, callerCompany: { type: 'string', description: 'Arayan şirket' }, transcript: { type: 'string', description: 'Konuşma transkripti' }, duration: { type: 'number', description: 'Görüşme süresi (saniye)' }, category: { type: 'string', description: 'Kategori (destek, satış, şikayet)' }, priority: { type: 'string', description: 'Öncelik (low, normal, high, urgent)' }, keywords: { type: 'array', items: { type: 'string' }, description: 'Anahtar kelimeler' } }, required: ['token', 'callerPhone', 'callerName', 'transcript', 'duration', 'category'] } }, { name: 'update_call_transcript', description: 'Mevcut transkripti günceller', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, id: { type: 'number', description: 'Transkript ID\'si' }, resolution: { type: 'string', description: 'Çözüm durumu' }, followUpRequired: { type: 'boolean', description: 'Takip gerekli mi?' }, assignedTo: { type: 'number', description: 'Atanan kullanıcı ID\'si' } }, required: ['token', 'id'] } }, { name: 'get_call_analytics', description: 'Çağrı analitikleri ve istatistikleri getirir', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, date: { type: 'string', description: 'Analiz tarihi (YYYY-MM-DD)' }, period: { type: 'string', description: 'Analiz periyodu (daily, weekly, monthly)', enum: ['daily', 'weekly', 'monthly'] } }, required: ['token'] } }, // Kullanıcı yönetimi araçları { name: 'list_users', description: 'Tüm kullanıcıları listeler (Yetki gerekli)', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token (yetki kontrolü için)' } }, required: ['token'] } }, { name: 'get_user_by_id', description: 'ID\'ye göre kullanıcı bilgilerini getirir (Yetki gerekli)', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Kullanıcı ID\'si' }, token: { type: 'string', description: 'JWT token (yetki kontrolü için)' } }, required: ['id', 'token'] } }, { name: 'search_users', description: 'Kullanıcıları ad, email, departman veya pozisyona göre arar', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Arama terimi' } }, required: ['query'] } }, { name: 'add_user', description: 'Yeni kullanıcı ekler', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Kullanıcı adı' }, email: { type: 'string', description: 'E-posta adresi' }, department: { type: 'string', description: 'Departman' }, position: { type: 'string', description: 'Pozisyon' }, joinDate: { type: 'string', description: 'İşe giriş tarihi (YYYY-MM-DD formatında)' }, salary: { type: 'number', description: 'Maaş (opsiyonel)' }, birthDate: { type: 'string', description: 'Doğum tarihi (YYYY-MM-DD formatında, opsiyonel)' }, phone: { type: 'string', description: 'Telefon numarası (opsiyonel)' }, address: { type: 'string', description: 'Adres (opsiyonel)' }, skills: { type: 'array', items: { type: 'string' }, description: 'Yetenekler listesi (opsiyonel)' } }, required: ['name', 'email', 'department', 'position', 'joinDate'] } }, { name: 'update_user', description: 'Mevcut kullanıcı bilgilerini günceller', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Güncellenecek kullanıcının ID\'si' }, name: { type: 'string', description: 'Yeni kullanıcı adı' }, email: { type: 'string', description: 'Yeni e-posta adresi' }, department: { type: 'string', description: 'Yeni departman' }, position: { type: 'string', description: 'Yeni pozisyon' } }, required: ['id'] } }, { name: 'delete_user', description: 'Kullanıcıyı siler', inputSchema: { type: 'object', properties: { id: { type: 'number', description: 'Silinecek kullanıcının ID\'si' } }, required: ['id'] } }, // Audit Log yönetimi araçları { name: 'get_my_audit_logs', description: 'Kullanıcının kendi audit loglarını getirir', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, limit: { type: 'number', description: 'Gösterilecek log sayısı (varsayılan: 50)' } }, required: ['token'] } }, { name: 'get_all_audit_logs', description: 'Tüm audit logları getirir (Sadece admin)', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, limit: { type: 'number', description: 'Gösterilecek log sayısı (varsayılan: 200)' } }, required: ['token'] } }, { name: 'get_audit_logs_by_category', description: 'Belirli kategorideki audit logları getirir (Admin/Manager)', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, category: { type: 'string', description: 'Log kategorisi (authentication, user_management, data_access, permission, system, security)' }, limit: { type: 'number', description: 'Gösterilecek log sayısı (varsayılan: 100)' } }, required: ['token', 'category'] } }, { name: 'get_audit_logs_by_date', description: 'Belirli tarih aralığındaki audit logları getirir (Admin/Manager)', inputSchema: { type: 'object', properties: { token: { type: 'string', description: 'JWT token' }, startDate: { type: 'string', description: 'Başlangıç tarihi (YYYY-MM-DD)' }, endDate: { type: 'string', description: 'Bitiş tarihi (YYYY-MM-DD)' }, limit: { type: 'number', description: 'Gösterilecek log sayısı (varsayılan: 100)' } }, required: ['token', 'startDate', 'endDate'] } }, ] }; }); // Tool çalıştırma işleyicisi server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { const db = await readDatabase(); switch (name) { // Kimlik doğrulama işlemleri case 'register': { const { name: userName, email, password, department, position, role = 'employee' } = args; // E-posta kontrolü const existingUser = db.users.find(u => u.email === email); if (existingUser) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Bu e-posta adresi zaten kayıtlı' }) }] }; } // Şifreyi hash'le const hashedPassword = await hashPassword(password); // Yeni kullanıcı oluştur const newUser = { id: generateId(db.users), name: userName, email, password: hashedPassword, department, position, role, joinDate: new Date().toISOString().split('T')[0] }; db.users.push(newUser); await writeDatabase(db); return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'Kullanıcı başarıyla kaydedildi', user: { id: newUser.id, name: userName, email, role } }) }] }; } case 'login': { const { email, password } = args; // Kullanıcıyı bul const user = db.users.find(u => u.email === email); if (!user) { // Başarısız login denemesini logla await auditLogger.loginFailed(email, { reason: 'user_not_found' }); return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Kullanıcı bulunamadı' }) }] }; } // Şifreyi kontrol et const isPasswordValid = await comparePassword(password, user.password); if (!isPasswordValid) { // Başarısız login denemesini logla await auditLogger.loginFailed(email, { reason: 'invalid_password', userId: user.id }); return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Geçersiz şifre' }) }] }; } // JWT token oluştur const token = generateToken(user.id, user.email, user.role); // Başarılı login'i logla await auditLogger.loginSuccess(user.id, user.role, { email, loginTime: new Date().toISOString(), tokenGenerated: true }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'Giriş başarılı', token, user: { id: user.id, name: user.name, email: user.email, role: user.role, department: user.department, position: user.position } }) }] }; } case 'verify_token': { const { token } = args; try { const decoded = verifyToken(token); return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'Token geçerli', user: decoded }) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message }) }] }; } } case 'change_password': { const { token, oldPassword, newPassword } = args; try { const decoded = verifyToken(token); const user = db.users.find(u => u.id === decoded.userId); if (!user) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Kullanıcı bulunamadı' }) }] }; } // Eski şifreyi kontrol et const isOldPasswordValid = await comparePassword(oldPassword, user.password); if (!isOldPasswordValid) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Mevcut şifre yanlış' }) }] }; } // Yeni şifreyi hash'le ve güncelle user.password = await hashPassword(newPassword); await writeDatabase(db); return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'Şifre başarıyla değiştirildi' }) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message }) }] }; } } case 'get_my_permissions': { const { token } = args; try { const user = extractUserFromToken(token); if (!user) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Geçersiz token' }) }] }; } const permissions = getUserPermissions(user.role); return { content: [{ type: 'text', text: JSON.stringify({ success: true, user: { id: user.userId, email: user.email, role: user.role }, permissions: permissions, totalPermissions: permissions.length, roleDescription: { [ROLES.ADMIN]: 'Sistem yöneticisi - Tüm yetkilere sahip', [ROLES.MANAGER]: 'Yönetici - Çoğu yönetim yetkilerine sahip', [ROLES.EMPLOYEE]: 'Çalışan - Temel yetkilere sahip' }[user.role] }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message }) }] }; } } // Kullanıcı yönetimi işlemleri case 'list_users': { const { token } = args; try { // Yetki kontrolü const user = checkPermissionWithToken(token, PERMISSIONS.USER_LIST); const usersWithoutPasswords = db.users.map(user => { const { password, ...userWithoutPassword } = user; return userWithoutPassword; }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: usersWithoutPasswords, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { // Yetki reddedilmesini audit log'a kaydet const failedUser = extractUserFromToken(args.token); if (failedUser) { await auditLogger.permissionDenied(failedUser.userId, failedUser.role, 'list_users', PERMISSIONS.USER_LIST); } return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.USER_LIST }) }] }; } } case 'get_user_by_id': { const { id, token } = args; try { // Yetki kontrolü const requestUser = checkPermissionWithToken(token, PERMISSIONS.USER_READ); const user = db.users.find(u => u.id === id); if (!user) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Kullanıcı bulunamadı' }) }] }; } // Kendi bilgilerini görüntüleme veya yetki kontrolü if (requestUser.userId !== id && !hasPermission(requestUser.role, PERMISSIONS.USER_READ)) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Bu kullanıcının bilgilerini görüntüleme yetkiniz yok' }) }] }; } const { password, ...userWithoutPassword } = user; return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: userWithoutPassword, requestedBy: { id: requestUser.userId, role: requestUser.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.USER_READ }) }] }; } } case 'search_users': { const { query } = args; const results = searchUsers(db.users, query); const resultsWithoutPasswords = results.map(user => { const { password, ...userWithoutPassword } = user; return userWithoutPassword; }); return { content: [{ type: 'text', text: JSON.stringify(resultsWithoutPasswords, null, 2) }] }; } case 'add_user': { const newUser = { id: generateId(db.users), ...args }; db.users.push(newUser); await writeDatabase(db); return { content: [{ type: 'text', text: JSON.stringify({ success: true, user: newUser }) }] }; } case 'update_user': { const { id, ...updates } = args; const userIndex = db.users.findIndex(u => u.id === id); if (userIndex === -1) { return { content: [{ type: 'text', text: JSON.stringify({ error: 'Kullanıcı bulunamadı' }) }] }; } db.users[userIndex] = { ...db.users[userIndex], ...updates }; await writeDatabase(db); const { password, ...userWithoutPassword } = db.users[userIndex]; return { content: [{ type: 'text', text: JSON.stringify({ success: true, user: userWithoutPassword }) }] }; } case 'delete_user': { const { id } = args; const userIndex = db.users.findIndex(u => u.id === id); if (userIndex === -1) { return { content: [{ type: 'text', text: JSON.stringify({ error: 'Kullanıcı bulunamadı' }) }] }; } db.users.splice(userIndex, 1); await writeDatabase(db); return { content: [{ type: 'text', text: JSON.stringify({ success: true, message: 'Kullanıcı silindi' }) }] }; } // Audit Log işlemleri case 'get_my_audit_logs': { const { token, limit = 50 } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.AUDIT_READ); const logs = await getUserAuditLogs(user.userId, limit); // Kendi audit log erişimini logla await auditLogger.dataAccessed(user.userId, user.role, 'my_audit_logs', { limit }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: logs, total: logs.length, requestedBy: { id: user.userId, role: user.role }, note: 'Kendi audit loglarınız gösteriliyor' }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.AUDIT_READ }) }] }; } } case 'get_all_audit_logs': { const { token, limit = 200 } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.AUDIT_READ_ALL); const logs = await getAllAuditLogs(limit); // Tüm audit log erişimini logla (kritik) await auditLogger.sensitiveDataAccessed(user.userId, user.role, 'all_audit_logs', { limit }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: logs, total: logs.length, requestedBy: { id: user.userId, role: user.role }, warning: 'Bu tüm sistem audit loglarını içerir - Gizli bilgiler içerebilir' }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.AUDIT_READ_ALL, note: 'Tüm audit loglar sadece admin tarafından görüntülenebilir' }) }] }; } } case 'get_audit_logs_by_category': { const { token, category, limit = 100 } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.AUDIT_READ); // Geçerli kategori kontrolü const validCategories = Object.values(AUDIT_CATEGORIES); if (!validCategories.includes(category)) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Geçersiz kategori', validCategories }) }] }; } const logs = await getAuditLogsByCategory(category, limit); // Kategori bazlı audit log erişimini logla await auditLogger.dataAccessed(user.userId, user.role, 'audit_logs_by_category', { category, limit }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: logs, category, total: logs.length, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.AUDIT_READ }) }] }; } } case 'get_audit_logs_by_date': { const { token, startDate, endDate, limit = 100 } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.AUDIT_READ); // Tarih format kontrolü const start = new Date(startDate); const end = new Date(endDate); if (isNaN(start.getTime()) || isNaN(end.getTime())) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Geçersiz tarih formatı. YYYY-MM-DD formatını kullanın' }) }] }; } const logs = await getAuditLogsByDateRange(startDate, endDate, limit); // Tarih bazlı audit log erişimini logla await auditLogger.dataAccessed(user.userId, user.role, 'audit_logs_by_date', { startDate, endDate, limit }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: logs, dateRange: { startDate, endDate }, total: logs.length, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.AUDIT_READ }) }] }; } } // Telefon Transkript işlemleri case 'list_call_transcripts': { const { token, limit = 50, category, sentiment } = args; try { console.error('DEBUG: list_call_transcripts called with token:', token ? 'PROVIDED' : 'MISSING'); console.error('DEBUG: PERMISSIONS.TRANSCRIPT_LIST:', PERMISSIONS.TRANSCRIPT_LIST); const user = checkPermissionWithToken(token, PERMISSIONS.TRANSCRIPT_LIST); console.error('DEBUG: User permission check passed:', user); let transcripts = db.call_transcripts; console.error('DEBUG: Total transcripts in DB:', transcripts.length); // Employee sadece kendi atandığı çağrıları görebilir if (user.role === ROLES.EMPLOYEE) { transcripts = transcripts.filter(t => t.assignedTo === user.userId); console.error('DEBUG: Filtered for employee, remaining:', transcripts.length); } // Filtreler if (category) { transcripts = transcripts.filter(t => t.category === category); } if (sentiment) { transcripts = transcripts.filter(t => t.sentiment === sentiment); } // Limit uygula transcripts = transcripts.slice(0, limit); await auditLogger.dataAccessed(user.userId, user.role, 'call_transcripts_list', { limit, category, sentiment }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: transcripts, total: transcripts.length, filters: { category, sentiment }, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { console.error('DEBUG: Error in list_call_transcripts:', error.message); return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.TRANSCRIPT_LIST, debug: { errorType: error.constructor.name, hasToken: !!token, permissionRequired: PERMISSIONS.TRANSCRIPT_LIST } }) }] }; } } case 'get_call_transcript_by_id': { const { token, id } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.TRANSCRIPT_READ); const transcript = db.call_transcripts.find(t => t.id === id); if (!transcript) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Transkript bulunamadı' }) }] }; } // Employee sadece kendi atandığı çağrıları görebilir if (user.role === ROLES.EMPLOYEE && transcript.assignedTo !== user.userId) { await auditLogger.permissionDenied(user.userId, user.role, 'get_call_transcript_by_id', PERMISSIONS.TRANSCRIPT_READ); return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: 'Bu transkripti görüntüleme yetkiniz yok' }) }] }; } await auditLogger.dataAccessed(user.userId, user.role, 'call_transcript_detail', { transcriptId: id }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: transcript, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.TRANSCRIPT_READ }) }] }; } } case 'search_call_transcripts': { const { token, query, searchIn = 'all' } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.TRANSCRIPT_SEARCH); let transcripts = db.call_transcripts; // Employee sadece kendi atandığı çağrıları arayabilir if (user.role === ROLES.EMPLOYEE) { transcripts = transcripts.filter(t => t.assignedTo === user.userId); } const searchQuery = query.toLowerCase(); const results = transcripts.filter(transcript => { switch (searchIn) { case 'transcript': return transcript.transcript.toLowerCase().includes(searchQuery); case 'callerName': return transcript.callerName.toLowerCase().includes(searchQuery); case 'keywords': return transcript.keywords.some(keyword => keyword.toLowerCase().includes(searchQuery)); case 'all': default: return transcript.transcript.toLowerCase().includes(searchQuery) || transcript.callerName.toLowerCase().includes(searchQuery) || transcript.keywords.some(keyword => keyword.toLowerCase().includes(searchQuery)) || transcript.callerCompany.toLowerCase().includes(searchQuery); } }); await auditLogger.dataAccessed(user.userId, user.role, 'call_transcript_search', { query, searchIn, resultCount: results.length }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: results, searchQuery: query, searchIn, total: results.length, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.TRANSCRIPT_SEARCH }) }] }; } } case 'add_call_transcript': { const { token, callerPhone, callerName, callerCompany = "Bilinmiyor", transcript, duration, category, priority = "normal", keywords = [] } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.TRANSCRIPT_CREATE); const newTranscript = { id: generateId(db.call_transcripts), callId: `CALL_${new Date().toISOString().slice(0, 10).replace(/-/g, '')}_${String(db.call_transcripts.length + 1).padStart(3, '0')}`, callerPhone, callerName, callerCompany, receiverPhone: "+90 555 123 4567", // Sabit receiver phone receiverName: user.role === ROLES.EMPLOYEE ? db.users.find(u => u.id === user.userId)?.name : "Müşteri Hizmetleri", receiverDepartment: "Müşteri Hizmetleri", callDate: new Date().toISOString().slice(0, 10), callTime: new Date().toTimeString().slice(0, 8), duration, callType: "incoming", status: "completed", category, priority, transcript, keywords, sentiment: "neutral", // Default sentiment resolution: "pending", followUpRequired: false, assignedTo: user.userId, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; db.call_transcripts.push(newTranscript); await writeDatabase(db); await auditLogger.dataAccessed(user.userId, user.role, 'call_transcript_created', { transcriptId: newTranscript.id, category }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: newTranscript, message: 'Transkript başarıyla eklendi', requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.TRANSCRIPT_CREATE }) }] }; } } case 'get_call_analytics': { const { token, date, period = 'daily' } = args; try { const user = checkPermissionWithToken(token, PERMISSIONS.TRANSCRIPT_ANALYTICS); let analytics = db.call_analytics; if (date) { analytics = analytics.filter(a => a.date === date); } await auditLogger.dataAccessed(user.userId, user.role, 'call_analytics', { date, period }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, data: analytics, period, requestedBy: { id: user.userId, role: user.role } }, null, 2) }] }; } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ success: false, message: error.message, requiredPermission: PERMISSIONS.TRANSCRIPT_ANALYTICS }) }] }; } } default: return { content: [{ type: 'text', text: JSON.stringify({ error: 'Bilinmeyen tool: ' + name }) }] }; } } catch (error) { return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }] }; } }); // Server'ı başlat async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('MCP JSON Database Server başlatıldı'); // Sistem başlangıcını audit log'a kaydet await auditLogger.systemStarted({ timestamp: new Date().toISOString(), nodeVersion: process.version, platform: process.platform }); } main().catch(async (error) => { console.error('Server başlatma hatası:', error); // Sistem hatalarını audit log'a kaydet await auditLogger.logAudit(null, null, 'SYSTEM_START_ERROR', AUDIT_CATEGORIES.SYSTEM, AUDIT_LEVELS.CRITICAL, { error: error.message, stack: error.stack }); process.exit(1); });

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yusuferenkt/mcp-database'

If you have feedback or need assistance with the MCP directory API, please join our Discord server