#!/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);
});