Skip to main content
Glama

MCP Agent TypeScript Port

by waldzellai
context.js9.04 kB
"use strict"; /** * Central context object to store global state shared across the application */ Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanupContextEffect = exports.initializeContextEffect = exports.Context = exports.ContextCleanupError = exports.ContextInitializationError = void 0; exports.initializeContext = initializeContext; exports.cleanupContext = cleanupContext; const events_1 = require("events"); const effect_1 = require("effect"); const exceptions_1 = require("./exceptions"); const index_1 = require("../executor/index"); class ContextInitializationError extends effect_1.Data.TaggedError('ContextInitializationError') { } exports.ContextInitializationError = ContextInitializationError; class ContextCleanupError extends effect_1.Data.TaggedError('ContextCleanupError') { } exports.ContextCleanupError = ContextCleanupError; const formatUnknown = (cause) => { if (cause instanceof Error) { return cause.message; } if (typeof cause === 'string') { return cause; } try { return JSON.stringify(cause); } catch { return String(cause); } }; const toError = (cause, fallback) => { if (cause instanceof Error) { return cause; } const message = typeof cause === 'string' && cause.length > 0 ? cause : fallback; const error = new Error(message); error.cause = cause; return error; }; /** * Central context object containing all shared application state */ class Context extends events_1.EventEmitter { app_name; settings; logger; executor; server_registry; activity_registry; signal_registry; workflow_registry; decorator_registry; model_selector; token_counter; // Callback handlers human_input_callback; elicitation_callback; signal_wait_callback; // Application reference app; // MCPApp instance static instance; initialized = false; constructor(settings = {}) { super(); this.app_name = settings.app_name || 'mcp-agent'; this.settings = settings; // Initialize with console logger by default this.logger = this.createDefaultLogger(); } /** * Get or create the singleton context instance */ static getInstance(settings) { if (!Context.instance) { Context.instance = new Context(settings || {}); } return Context.instance; } /** * Initialize the context with all required components */ initializeEffect() { const self = this; return (0, effect_1.pipe)(effect_1.Effect.gen(function* (_) { if (self.initialized) { return; } yield* effect_1.Effect.sync(() => self.logger.info('Initializing context...')); if (self.settings.executor_type === 'temporal') { yield* effect_1.Effect.sync(() => self.logger.info('Temporal executor initialization not yet implemented')); } else { self.executor = new BasicExecutorAdapter(new index_1.BaseExecutor()); yield* effect_1.Effect.tryPromise({ try: () => self.executor.start(), catch: cause => new ContextInitializationError({ cause }) }); yield* effect_1.Effect.sync(() => self.logger.info('Default executor initialized')); } self.initialized = true; yield* effect_1.Effect.sync(() => { self.logger.info('Context initialized successfully'); self.emit('initialized'); }); }), effect_1.Effect.tapError(cause => effect_1.Effect.sync(() => { self.logger.error('Failed to initialize context', cause); })), effect_1.Effect.mapError(cause => cause instanceof ContextInitializationError ? cause : new ContextInitializationError({ cause }))); } async initialize() { try { await effect_1.Effect.runPromise(this.initializeEffect()); } catch (error) { if (error instanceof ContextInitializationError) { const configurationError = new exceptions_1.ConfigurationError(`Context initialization failed: ${formatUnknown(error.cause)}`); configurationError.cause = error.cause; throw configurationError; } throw error; } } /** * Clean up context resources */ cleanupEffect() { const self = this; return (0, effect_1.pipe)(effect_1.Effect.gen(function* (_) { yield* effect_1.Effect.sync(() => self.logger.info('Cleaning up context...')); if (self.executor) { yield* effect_1.Effect.tryPromise({ try: () => self.executor.stop(), catch: cause => new ContextCleanupError({ cause }) }); } self.initialized = false; yield* effect_1.Effect.sync(() => { self.emit('cleanup'); self.logger.info('Context cleanup completed'); }); }), effect_1.Effect.tapError(cause => effect_1.Effect.sync(() => { self.logger.error('Error during context cleanup', cause); })), effect_1.Effect.mapError(cause => cause instanceof ContextCleanupError ? cause : new ContextCleanupError({ cause }))); } async cleanup() { try { await effect_1.Effect.runPromise(this.cleanupEffect()); } catch (error) { if (error instanceof ContextCleanupError) { throw toError(error.cause, 'Context cleanup failed'); } throw error; } } /** * Create a default console logger */ createDefaultLogger() { const level = this.settings.logging?.level || 'info'; const levels = ['debug', 'info', 'warn', 'error']; const currentLevelIndex = levels.indexOf(level); return { debug: (message, ...args) => { if (currentLevelIndex <= 0) { console.debug(`[${this.app_name}] DEBUG:`, message, ...args); } }, info: (message, ...args) => { if (currentLevelIndex <= 1) { console.info(`[${this.app_name}] INFO:`, message, ...args); } }, warn: (message, ...args) => { if (currentLevelIndex <= 2) { console.warn(`[${this.app_name}] WARN:`, message, ...args); } }, error: (message, ...args) => { console.error(`[${this.app_name}] ERROR:`, message, ...args); } }; } /** * Update context settings */ updateSettings(settings) { this.settings = { ...this.settings, ...settings }; this.emit('settings-updated', this.settings); } /** * Check if context is properly initialized */ isInitialized() { return this.initialized; } } exports.Context = Context; /** * Global context initialization helper */ const initializeContextEffect = (settings) => effect_1.Effect.gen(function* (_) { const context = Context.getInstance(settings); yield* context.initializeEffect(); return context; }); exports.initializeContextEffect = initializeContextEffect; async function initializeContext(settings) { try { return await effect_1.Effect.runPromise((0, exports.initializeContextEffect)(settings)); } catch (error) { if (error instanceof ContextInitializationError) { const configurationError = new exceptions_1.ConfigurationError(`Context initialization failed: ${formatUnknown(error.cause)}`); configurationError.cause = error.cause; throw configurationError; } throw error; } } /** * Global context cleanup helper */ const cleanupContextEffect = () => Context.getInstance().cleanupEffect(); exports.cleanupContextEffect = cleanupContextEffect; async function cleanupContext() { try { await effect_1.Effect.runPromise((0, exports.cleanupContextEffect)()); } catch (error) { if (error instanceof ContextCleanupError) { throw toError(error.cause, 'Context cleanup failed'); } throw error; } } /** * Adapter to bridge BaseExecutor to the Context.Executor interface */ class BasicExecutorAdapter { type = 'asyncio'; base; constructor(base) { this.base = base; } async start() { // No-op for in-process executor } async stop() { // Wait for running tasks to complete; no explicit shutdown needed await this.base.waitForAllTasks(); } async execute(task) { const id = `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; return this.base.enqueueTask({ id, name: id, execute: task }); } }

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/waldzellai/mcp-agent-ts'

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