Skip to main content
Glama
chrisleekr

MCP Server Boilerplate

by chrisleekr
context.ts2.9 kB
import { AsyncLocalStorage } from 'async_hooks'; import { logger, LoggerInterface, LogLevel } from '@/utils/logger'; // References: // https://nodejs.org/api/async_context.html // https://betterstack.com/community/guides/scaling-nodejs/async-hooks-explained/ export interface AsyncLocalStorageLoggingContext { readonly requestId: string; readonly ipAddress: string; readonly mcpSessionId?: string; readonly mcpProtocolVersion?: string; readonly userAgent?: string; readonly requestStartTime: number; // Allow additional dynamic properties readonly [key: string]: unknown; } // Create a new AsyncLocalStorage instance to store the context const asyncLocalStorage = new AsyncLocalStorage<AsyncLocalStorageLoggingContext>(); export interface LoggingContextInterface { init: ( context: AsyncLocalStorageLoggingContext, callback: () => void ) => void; log: ( level: LogLevel, message: string, data?: Record<string, unknown> ) => void; getContext: () => AsyncLocalStorageLoggingContext | undefined; setContextValue: (key: string, value: unknown) => void; getContextValue: <T>(key: string) => T | undefined; } export const LoggingContext = ( logger: LoggerInterface ): LoggingContextInterface => { return { init: ( context: AsyncLocalStorageLoggingContext, callback: () => void ): void => { asyncLocalStorage.run(context, () => { callback(); }); }, log: ( level: LogLevel, message: string, data?: Record<string, unknown> ): void => { const context = asyncLocalStorage.getStore(); if (!context) { // If no context, log the message without the context logger.getLogger()[level]({ ...data }, message); return; } // If context, log the message with the context const timestamp = Date.now(); const requestElapsedTime = context.requestStartTime > 0 && context.requestStartTime > 0 ? timestamp - context.requestStartTime : undefined; logger.getLogger()[level]( { ...data, ...context, timestamp, requestElapsedTime, }, message ); }, getContext: (): AsyncLocalStorageLoggingContext | undefined => { return asyncLocalStorage.getStore(); }, setContextValue: (key: string, value: unknown): void => { const context = asyncLocalStorage.getStore(); if (!context) { return; } const updatedContext = { ...context, [key]: value }; asyncLocalStorage.enterWith(updatedContext); }, getContextValue: <T>(key: string): T | undefined => { const context = asyncLocalStorage.getStore(); if (!context) { return undefined; } return context[key] as T | undefined; }, }; }; export const loggingContext = LoggingContext(logger);

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/chrisleekr/mcp-server-boilerplate'

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