Skip to main content
Glama

Demo MCP Server

by kylekanouse
my-mcp-server.ts5.72 kB
/** * MCP Server Wrapper * * This class encapsulates the MCP SDK server components and provides * a clean interface using dependency injection patterns. */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import type { IMCPServerWrapper, MCPServerConfig, IModuleLoaderService } from "../types/index.js"; import { ModuleLoaderService } from "../services/index.js"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; /** * Abstract base class for MCP server implementations */ export abstract class BaseMCPServer { protected abstract createServer(config: MCPServerConfig): McpServer; protected abstract createTransport(): any; abstract initialize(): Promise<void>; abstract connect(): Promise<void>; abstract shutdown(): Promise<void>; } /** * Concrete implementation of MCP Server with SDK adapter */ export class MyMCPServer extends BaseMCPServer implements IMCPServerWrapper { private server: McpServer | null = null; private transport: any = null; private moduleLoader: IModuleLoaderService; private config: MCPServerConfig; private isInitialized = false; private isConnected = false; constructor( config: MCPServerConfig, moduleLoader?: IModuleLoaderService ) { super(); this.config = config; this.moduleLoader = moduleLoader || new ModuleLoaderService(); } /** * Create and configure the MCP server instance */ protected createServer(config: MCPServerConfig): McpServer { console.log(`Creating MCP server: ${config.name} v${config.version}`); return new McpServer({ name: config.name, version: config.version }); } /** * Create the transport layer (stdio by default) */ protected createTransport(): StdioServerTransport { console.log("Creating StdioServerTransport"); return new StdioServerTransport(); } /** * Initialize the server and register all components */ async initialize(): Promise<void> { if (this.isInitialized) { console.log("Server already initialized"); return; } console.log("Initializing MCP Server..."); try { // Create server instance this.server = this.createServer(this.config); // Create transport this.transport = this.createTransport(); // Load and register all components await this.registerAllComponents(); this.isInitialized = true; console.log("✓ MCP Server initialization completed"); } catch (error) { console.error("✗ Failed to initialize MCP Server:", error); throw error; } } /** * Connect the server to the transport */ async connect(): Promise<void> { if (!this.isInitialized) { throw new Error("Server must be initialized before connecting"); } if (this.isConnected) { console.log("Server already connected"); return; } if (!this.server || !this.transport) { throw new Error("Server or transport not properly initialized"); } try { console.log("Connecting MCP Server to transport..."); await this.server.connect(this.transport); this.isConnected = true; console.log("✓ MCP Server connected successfully"); } catch (error) { console.error("✗ Failed to connect MCP Server:", error); throw error; } } /** * Shutdown the server and cleanup resources */ async shutdown(): Promise<void> { console.log("Shutting down MCP Server..."); try { if (this.transport && typeof this.transport.close === 'function') { await this.transport.close(); } this.isConnected = false; this.isInitialized = false; console.log("✓ MCP Server shutdown completed"); } catch (error) { console.error("✗ Error during server shutdown:", error); throw error; } } /** * Register all MCP components from their respective directories */ private async registerAllComponents(): Promise<void> { if (!this.server) { throw new Error("Server not initialized"); } const currentDir = dirname(fileURLToPath(import.meta.url)); const srcDir = join(currentDir, ".."); // Register components from each directory const componentDirs = [ { path: join(srcDir, "tools"), name: "tools" }, { path: join(srcDir, "resources"), name: "resources" }, { path: join(srcDir, "prompts"), name: "prompts" } ]; for (const { path, name } of componentDirs) { try { console.log(`Loading ${name} from ${path}...`); const modules = await this.moduleLoader.loadModulesFromDirectory(path); for (const module of modules) { await this.moduleLoader.registerModule(module, this.server); } console.log(`✓ Registered ${modules.length} ${name}`); } catch (error) { console.error(`✗ Failed to register ${name}:`, error); // Continue with other components even if one fails } } } /** * Get server status information */ getStatus(): { initialized: boolean; connected: boolean; config: MCPServerConfig; loadedModules: Array<{ name: string; metadata?: any }>; } { return { initialized: this.isInitialized, connected: this.isConnected, config: this.config, loadedModules: this.moduleLoader.getLoadedModulesInfo() }; } /** * Get the underlying server instance (for advanced usage) * Note: This should be used sparingly to maintain encapsulation */ getServerInstance(): McpServer | null { return this.server; } }

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/kylekanouse/Test-MCP---DEMO-MCP-Dev-1'

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