Skip to main content
Glama

Role-Specific Context MCP Server

by Chris-June
contextManager.ts11.3 kB
import { ContextType, ContextPriority, ContextState, ContextTrigger, ContextSwitchRequest, ContextSwitchResponse, ContextStack, MultiModalContext } from './types'; import { v4 as uuidv4 } from 'uuid'; import { config } from '../config'; import { MemoryManager } from '../memory/memoryManager'; import { ImportanceLevel, MemoryType } from '../memory/types'; /** * Manager for handling real-time context switching */ export class ContextManager { private contextStacks: Map<string, ContextStack> = new Map(); private contextTriggers: Map<string, ContextTrigger> = new Map(); private memoryManager: MemoryManager; constructor(memoryManager: MemoryManager) { this.memoryManager = memoryManager; this.initializeDefaultTriggers(); } /** * Initialize default context triggers from config */ private initializeDefaultTriggers(): void { if (config.context && config.context.triggers) { // Process task triggers if (config.context.triggers.task) { for (const pattern of config.context.triggers.task) { const trigger: ContextTrigger = { id: uuidv4(), pattern, contextType: ContextType.TASK, contextValue: 'specific', description: `Task trigger for pattern: ${pattern}`, isActive: true }; this.contextTriggers.set(trigger.id, trigger); } } // Process tone triggers if (config.context.triggers.tone) { for (const pattern of config.context.triggers.tone) { const trigger: ContextTrigger = { id: uuidv4(), pattern, contextType: ContextType.TONE, contextValue: pattern.includes('formal') ? 'formal' : pattern.includes('casual') ? 'casual' : pattern.includes('professional') ? 'professional' : pattern.includes('creative') ? 'creative' : pattern.includes('technical') ? 'technical' : 'neutral', description: `Tone trigger for pattern: ${pattern}`, isActive: true }; this.contextTriggers.set(trigger.id, trigger); } } // Process domain triggers if (config.context.triggers.domain) { for (const pattern of config.context.triggers.domain) { const trigger: ContextTrigger = { id: uuidv4(), pattern, contextType: ContextType.DOMAIN, contextValue: pattern.includes('marketing') ? 'marketing' : pattern.includes('technical') ? 'technical' : pattern.includes('creative') ? 'creative' : 'general', description: `Domain trigger for pattern: ${pattern}`, isActive: true }; this.contextTriggers.set(trigger.id, trigger); } } } } /** * Initialize a context stack for an agent if it doesn't exist */ private ensureContextStack(agentId: string): ContextStack { if (!this.contextStacks.has(agentId)) { // Create default context states for each type const defaultContexts: Record<ContextType, ContextState> = { [ContextType.TONE]: { id: uuidv4(), type: ContextType.TONE, value: 'neutral', priority: ContextPriority.MEDIUM, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.TASK]: { id: uuidv4(), type: ContextType.TASK, value: 'general', priority: ContextPriority.HIGH, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.ROLE]: { id: uuidv4(), type: ContextType.ROLE, value: 'assistant', priority: ContextPriority.HIGH, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.DOMAIN]: { id: uuidv4(), type: ContextType.DOMAIN, value: 'general', priority: ContextPriority.MEDIUM, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.USER]: { id: uuidv4(), type: ContextType.USER, value: 'default', priority: ContextPriority.HIGH, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.ENVIRONMENT]: { id: uuidv4(), type: ContextType.ENVIRONMENT, value: 'default', priority: ContextPriority.LOW, createdAt: Date.now(), updatedAt: Date.now() }, [ContextType.MULTIMODAL]: { id: uuidv4(), type: ContextType.MULTIMODAL, value: 'none', priority: ContextPriority.MEDIUM, createdAt: Date.now(), updatedAt: Date.now() } }; const contextStack: ContextStack = { agentId, stack: Object.values(defaultContexts), current: defaultContexts }; this.contextStacks.set(agentId, contextStack); } return this.contextStacks.get(agentId)!; } /** * Switch context for an agent */ public async switchContext(request: ContextSwitchRequest): Promise<ContextSwitchResponse> { const { agentId, contextType, contextValue, priority = ContextPriority.MEDIUM, metadata = {} } = request; // Ensure context stack exists const contextStack = this.ensureContextStack(agentId); // Get previous context const previousContext = contextStack.current[contextType]; // Create new context const newContext: ContextState = { id: uuidv4(), type: contextType, value: contextValue, priority, metadata, createdAt: Date.now(), updatedAt: Date.now() }; // Update context stack contextStack.stack.push(newContext); contextStack.current[contextType] = newContext; // Store context change in memory await this.memoryManager.storeMemory({ roleId: agentId, content: `Context switched: ${contextType} from '${previousContext.value}' to '${contextValue}'`, type: MemoryType.SESSION, importance: ImportanceLevel.MEDIUM, metadata: { type: 'context_switch', contextType, previousValue: previousContext.value, newValue: contextValue, priority } }); return { success: true, message: `Context switched: ${contextType} from '${previousContext.value}' to '${contextValue}'`, previousContext, newContext }; } /** * Get current context for an agent */ public getCurrentContext(agentId: string): Record<ContextType, ContextState> { const contextStack = this.ensureContextStack(agentId); return contextStack.current; } /** * Get context history for an agent */ public getContextHistory(agentId: string): ContextState[] { const contextStack = this.ensureContextStack(agentId); return [...contextStack.stack]; } /** * Add a new context trigger */ public addContextTrigger(trigger: Omit<ContextTrigger, 'id'>): ContextTrigger { const newTrigger: ContextTrigger = { ...trigger, id: uuidv4(), isActive: true }; this.contextTriggers.set(newTrigger.id, newTrigger); return newTrigger; } /** * Update an existing context trigger */ public updateContextTrigger(triggerId: string, updates: Partial<Omit<ContextTrigger, 'id'>>): ContextTrigger { const existingTrigger = this.contextTriggers.get(triggerId); if (!existingTrigger) { throw new Error(`Trigger with ID ${triggerId} not found`); } const updatedTrigger: ContextTrigger = { ...existingTrigger, ...updates }; this.contextTriggers.set(triggerId, updatedTrigger); return updatedTrigger; } /** * Delete a context trigger */ public deleteContextTrigger(triggerId: string): boolean { return this.contextTriggers.delete(triggerId); } /** * Get all context triggers */ public getAllContextTriggers(): ContextTrigger[] { return Array.from(this.contextTriggers.values()); } /** * Check input for context triggers and apply if matched */ public async checkAndApplyTriggers(agentId: string, input: string): Promise<ContextSwitchResponse[]> { const responses: ContextSwitchResponse[] = []; for (const trigger of this.contextTriggers.values()) { if (!trigger.isActive) continue; const pattern = trigger.pattern instanceof RegExp ? trigger.pattern : new RegExp(trigger.pattern, 'i'); if (pattern.test(input)) { // Trigger matched, apply context switch const response = await this.switchContext({ agentId, contextType: trigger.contextType, contextValue: trigger.contextValue, triggerId: trigger.id }); responses.push(response); } } return responses; } /** * Generate context-aware prompt modifications */ public generateContextPromptModifiers(agentId: string): string { const contextStack = this.ensureContextStack(agentId); const currentContext = contextStack.current; let modifiers = ''; // Add tone context if (currentContext[ContextType.TONE]) { modifiers += `\n\nTone: Please respond in a ${currentContext[ContextType.TONE].value} tone.`; } // Add task context if (currentContext[ContextType.TASK]) { modifiers += `\n\nTask: You are currently focused on ${currentContext[ContextType.TASK].value}.`; } // Add role context if (currentContext[ContextType.ROLE]) { modifiers += `\n\nRole: You are acting as a ${currentContext[ContextType.ROLE].value}.`; } // Add domain context if (currentContext[ContextType.DOMAIN]) { modifiers += `\n\nDomain: Prioritize knowledge about ${currentContext[ContextType.DOMAIN].value}.`; } // Add user context if (currentContext[ContextType.USER]) { modifiers += `\n\nUser: Consider the user's preferences: ${currentContext[ContextType.USER].value}.`; } // Add environment context if (currentContext[ContextType.ENVIRONMENT]) { modifiers += `\n\nEnvironment: Consider the current environment: ${currentContext[ContextType.ENVIRONMENT].value}.`; } // Add multimodal context if (currentContext[ContextType.MULTIMODAL] && currentContext[ContextType.MULTIMODAL].value !== 'none') { modifiers += `\n\nMultimodal: Consider the multimodal context: ${currentContext[ContextType.MULTIMODAL].value}.`; } return modifiers; } /** * Handle multi-modal context */ public async handleMultiModalContext(agentId: string, context: MultiModalContext): Promise<void> { // Store multi-modal context in memory await this.memoryManager.storeMemory({ roleId: agentId, content: context.text || 'Multi-modal context added', type: MemoryType.SESSION, importance: ImportanceLevel.MEDIUM, metadata: { type: 'multi_modal_context', imageUrls: context.imageUrls, priority: context.priority, ...context.metadata } }); } }

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/Chris-June/MCP-Server'

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