Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
securityMonitor.tsโ€ข6.05 kB
/** * Security Monitor for DollhouseMCP * * Centralized security event logging and monitoring system * for tracking and alerting on security-related events. */ import { logger } from '../utils/logger.js'; export interface SecurityEvent { type: 'CONTENT_INJECTION_ATTEMPT' | 'YAML_INJECTION_ATTEMPT' | 'PATH_TRAVERSAL_ATTEMPT' | 'TOKEN_VALIDATION_FAILURE' | 'UPDATE_SECURITY_VIOLATION' | 'RATE_LIMIT_EXCEEDED' | 'YAML_PARSING_WARNING' | 'YAML_PARSE_SUCCESS' | 'TOKEN_VALIDATION_SUCCESS' | 'PATH_VALIDATION_SUCCESS' | 'RATE_LIMIT_WARNING' | 'TOKEN_CACHE_CLEARED' | 'YAML_UNICODE_ATTACK' | 'UNICODE_DIRECTION_OVERRIDE' | 'UNICODE_MIXED_SCRIPT' | 'UNICODE_VALIDATION_ERROR' | 'CONTENT_SIZE_EXCEEDED' | 'INCLUDE_DEPTH_EXCEEDED' | 'TEMPLATE_RENDERED' | 'TEMPLATE_INCLUDE' | 'TEMPLATE_LOADED' | 'TEMPLATE_SAVED' | 'TEMPLATE_DELETED' | 'MEMORY_CREATED' | 'MEMORY_ADDED' | 'MEMORY_SEARCHED' | 'SENSITIVE_MEMORY_DELETED' | 'RETENTION_POLICY_ENFORCED' | 'MEMORY_CLEARED' | 'MEMORY_LOADED' | 'MEMORY_SAVED' | 'MEMORY_DELETED' | 'MEMORY_LOAD_FAILED' | 'MEMORY_SAVE_FAILED' | 'MEMORY_LIST_ITEM_FAILED' | 'MEMORY_IMPORT_FAILED' | 'MEMORY_DESERIALIZE_FAILED' | 'MEMORY_INTEGRITY_VIOLATION' | 'MEMORY_UNICODE_VALIDATION_FAILED' | 'MEMORY_DUPLICATE_DETECTED' | 'ELEMENT_CREATED' | 'ELEMENT_DELETED' | 'AGENT_DECISION' | 'RULE_ENGINE_CONFIG_UPDATE' | 'RULE_ENGINE_CONFIG_VALIDATION_ERROR' | 'GOAL_TEMPLATE_APPLIED' | 'GOAL_TEMPLATE_VALIDATION' | 'ENSEMBLE_CIRCULAR_DEPENDENCY' | 'ENSEMBLE_RESOURCE_LIMIT_EXCEEDED' | 'ENSEMBLE_ACTIVATION_TIMEOUT' | 'ENSEMBLE_SUSPICIOUS_CONDITION' | 'ENSEMBLE_NESTED_DEPTH_EXCEEDED' | 'ENSEMBLE_CONTEXT_SIZE_EXCEEDED' | 'ENSEMBLE_SAVED' | 'ENSEMBLE_IMPORTED' | 'ENSEMBLE_DELETED' | 'PORTFOLIO_INITIALIZATION' | 'PORTFOLIO_POPULATED' | 'FILE_COPIED' | 'DIRECTORY_MIGRATION' | 'PORTFOLIO_CACHE_INVALIDATION' | 'PORTFOLIO_FETCH_SUCCESS' | 'TEST_DATA_BLOCKED' | 'TEST_PATH_SECURITY_RISK' | 'TEST_PRODUCTION_ACCESS_BLOCKED' | 'TEST_PATH_INVALID' | 'TEST_ENVIRONMENT_PRODUCTION_PATH' | 'TEST_ENVIRONMENT_DEPRECATED_VAR' | 'TOOL_CACHE_INVALIDATED'; severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; source: string; details: string; userAgent?: string; ip?: string; additionalData?: Record<string, any>; metadata?: Record<string, any>; } export interface SecurityLogEntry extends SecurityEvent { timestamp: string; id: string; } export class SecurityMonitor { private static eventCount = 0; private static readonly events: SecurityLogEntry[] = []; private static readonly MAX_EVENTS = 1000; // Keep last 1000 events in memory /** * Logs a security event */ static logSecurityEvent(event: SecurityEvent): void { const logEntry: SecurityLogEntry = { ...event, timestamp: new Date().toISOString(), id: `SEC-${Date.now()}-${++this.eventCount}`, }; // Store in memory (circular buffer) this.events.push(logEntry); if (this.events.length > this.MAX_EVENTS) { this.events.shift(); } // In MCP servers, we cannot write to stderr/stdout as it breaks the JSON-RPC protocol // Security events are stored in memory and can be retrieved via API // Only send critical alerts via the proper channel if (event.severity === 'CRITICAL') { this.sendSecurityAlert(logEntry); } } /** * Sends security alerts for critical events */ private static sendSecurityAlert(event: SecurityLogEntry): void { // In a production environment, this would integrate with: // - Slack webhooks // - Email alerts // - PagerDuty // - Security Information and Event Management (SIEM) systems // Log critical security alerts with structured data // DO NOT use console.error in MCP servers as it breaks the JSON-RPC protocol logger.error('๐Ÿšจ CRITICAL SECURITY ALERT ๐Ÿšจ', { type: event.type, details: event.details, timestamp: event.timestamp, id: event.id }); // If in production mode with proper config, send actual alerts if (process.env.DOLLHOUSE_SECURITY_ALERTS === 'true') { // TODO: Implement actual alert mechanisms } } /** * Gets recent security events for analysis */ static getRecentEvents(count: number = 100): SecurityLogEntry[] { return this.events.slice(-count); } /** * Gets events by severity */ static getEventsBySeverity(severity: SecurityEvent['severity']): SecurityLogEntry[] { return this.events.filter(event => event.severity === severity); } /** * Gets events by type */ static getEventsByType(type: SecurityEvent['type']): SecurityLogEntry[] { return this.events.filter(event => event.type === type); } /** * Generates a security report */ static generateSecurityReport(): { totalEvents: number; eventsBySeverity: Record<string, number>; eventsByType: Record<string, number>; recentCriticalEvents: SecurityLogEntry[]; } { const eventsBySeverity: Record<string, number> = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0, }; const eventsByType: Record<string, number> = {}; for (const event of this.events) { eventsBySeverity[event.severity]++; eventsByType[event.type] = (eventsByType[event.type] || 0) + 1; } return { totalEvents: this.events.length, eventsBySeverity, eventsByType, recentCriticalEvents: this.getEventsBySeverity('CRITICAL').slice(-10), }; } /** * Clears old events (for memory management) */ static clearOldEvents(daysToKeep: number = 7): void { const cutoffDate = new Date(); cutoffDate.setDate(cutoffDate.getDate() - daysToKeep); const cutoffTimestamp = cutoffDate.toISOString(); const index = this.events.findIndex(event => event.timestamp >= cutoffTimestamp); if (index > 0) { this.events.splice(0, index); } } }

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/DollhouseMCP/DollhouseMCP'

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