Skip to main content
Glama
server.ts6.14 kB
/** * @fileoverview Main entry point for the MCP (Model Context Protocol) server. * This file orchestrates the server's lifecycle: * 1. Initializes the core `McpServer` instance (from `@modelcontextprotocol/sdk`) with its identity and capabilities. * 2. Registers available resources and tools, making them discoverable and usable by clients. * 3. Selects and starts the appropriate communication transport (stdio or Streamable HTTP) * based on configuration. * 4. Handles top-level error management during startup. * * MCP Specification References: * - Lifecycle: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/lifecycle.mdx * - Overview (Capabilities): https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/index.mdx * - Transports: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/basic/transports.mdx * @module src/mcp-server/server */ import { ServerType } from "@hono/node-server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { config, environment } from "../config/index.js"; import { ErrorHandler, logger, requestContextService } from "../utils/index.js"; import { BaseErrorCode } from "../types-global/errors.js"; import { registerPubchemSearchCompoundByIdentifierTool } from "./tools/searchCompoundByIdentifier/index.js"; import { registerPubchemFetchCompoundPropertiesTool } from "./tools/fetchCompoundProperties/index.js"; import { registerPubchemGetCompoundImageTool } from "./tools/getCompoundImageUrl/index.js"; import { registerPubchemSearchCompoundsByStructureTool } from "./tools/searchCompoundsByStructure/index.js"; import { registerPubchemSearchCompoundsBySimilarityTool } from "./tools/searchCompoundsBySimilarity/index.js"; import { registerPubchemSearchCompoundsByFormulaTool } from "./tools/searchCompoundsByFormula/index.js"; import { registerPubchemFetchSubstanceDetailsTool } from "./tools/fetchSubstanceDetails/index.js"; import { registerPubchemFetchAssaySummaryTool } from "./tools/fetchAssaySummary/index.js"; import { registerPubchemSearchAssaysByTargetTool } from "./tools/searchAssaysByTarget/index.js"; import { registerPubchemFetchCompoundXrefsTool } from "./tools/fetchCompoundXrefs/index.js"; import { startHttpTransport } from "./transports/httpTransport.js"; import { connectStdioTransport } from "./transports/stdioTransport.js"; /** * Creates and configures a new instance of the `McpServer`. * * @returns A promise resolving with the configured `McpServer` instance. * @throws {McpError} If any resource or tool registration fails. * @private */ async function createMcpServerInstance(): Promise<McpServer> { const context = requestContextService.createRequestContext({ operation: "createMcpServerInstance", }); logger.info("Initializing MCP server instance", context); requestContextService.configure({ appName: config.mcpServerName, appVersion: config.mcpServerVersion, environment, }); const server = new McpServer( { name: config.mcpServerName, version: config.mcpServerVersion }, { capabilities: { logging: {}, resources: { listChanged: true }, tools: { listChanged: true }, }, }, ); await ErrorHandler.tryCatch( async () => { logger.debug("Registering resources and tools...", context); await registerPubchemSearchCompoundByIdentifierTool(server); await registerPubchemFetchCompoundPropertiesTool(server); await registerPubchemGetCompoundImageTool(server); await registerPubchemSearchCompoundsByStructureTool(server); await registerPubchemSearchCompoundsBySimilarityTool(server); await registerPubchemSearchCompoundsByFormulaTool(server); await registerPubchemFetchSubstanceDetailsTool(server); await registerPubchemFetchAssaySummaryTool(server); await registerPubchemSearchAssaysByTargetTool(server); await registerPubchemFetchCompoundXrefsTool(server); logger.info("Resources and tools registered successfully", context); }, { operation: "registerAllCapabilities", context, errorCode: BaseErrorCode.INITIALIZATION_FAILED, critical: true, }, ); return server; } /** * Selects, sets up, and starts the appropriate MCP transport layer based on configuration. * * @returns Resolves with `McpServer` for 'stdio', `http.Server` for 'http', or `void`. * @throws {Error} If transport type is unsupported or setup fails. * @private */ async function startTransport(): Promise<McpServer | ServerType | void> { const transportType = config.mcpTransportType; const context = requestContextService.createRequestContext({ operation: "startTransport", transport: transportType, }); logger.info(`Starting transport: ${transportType}`, context); if (transportType === "http") { return startHttpTransport(createMcpServerInstance, context); } if (transportType === "stdio") { const server = await createMcpServerInstance(); await connectStdioTransport(server, context); return server; } throw new Error( `Unsupported transport type: ${transportType}. Must be 'stdio' or 'http'.`, ); } /** * Main application entry point. Initializes and starts the MCP server. */ export async function initializeAndStartServer(): Promise< void | McpServer | ServerType > { const context = requestContextService.createRequestContext({ operation: "initializeAndStartServer", }); logger.info("MCP Server initialization sequence started.", context); try { const result = await startTransport(); logger.info( "MCP Server initialization sequence completed successfully.", context, ); return result; } catch (err) { ErrorHandler.handleError(err, { operation: "initializeAndStartServer", context: context, critical: true, rethrow: false, }); logger.info( "Exiting process due to critical initialization error.", context, ); process.exit(1); } }

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/cyanheads/pubchem-mcp-server'

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