@@ -11,6 +11,7 @@ import { z } from 'zod'
1111export class McpServer {
1212 private server : OfficialMcpServer
1313 private config : ServerConfig
14+ private expressApp ?: any
1415
1516 constructor ( config : ServerConfig ) {
1617 this . config = config
@@ -56,7 +57,7 @@ export class McpServer {
5657 toolName ,
5758 definition . description || 'Resource Template' ,
5859 this . createInputSchema ( definition . uriTemplate ) ,
59- async ( params ) => {
60+ async ( params : any ) => {
6061 const content = await definition . fn ( params as Record < string , string > )
6162 return {
6263 content : [
@@ -81,7 +82,7 @@ export class McpServer {
8182 definition . name ,
8283 definition . description || definition . name ,
8384 inputSchema ,
84- async ( params ) => {
85+ async ( params : any ) => {
8586 const result = await definition . fn ( params )
8687 return {
8788 content : [
@@ -106,7 +107,7 @@ export class McpServer {
106107 definition . name ,
107108 definition . description || definition . name ,
108109 argsSchema ,
109- async ( params ) => {
110+ async ( params : any ) => {
110111 const result = await definition . fn ( params )
111112 return {
112113 messages : [
@@ -125,14 +126,83 @@ export class McpServer {
125126 }
126127
127128 /**
128- * Start the MCP server
129+ * Set the Express app for SSE transport
129130 */
130- async serve ( ) : Promise < void > {
131- // The MCP server needs to be connected to a transport
132- // For now, we'll use stdio transport by default
133- const { StdioServerTransport } = await import ( '@modelcontextprotocol/sdk/server/stdio.js' )
134- const transport = new StdioServerTransport ( )
135- await this . server . connect ( transport )
131+ setExpressApp ( app : any ) : this {
132+ this . expressApp = app
133+ return this
134+ }
135+
136+ /**
137+ * Start the MCP server with configurable transport
138+ * @param options - Transport options (defaults to HTTP)
139+ */
140+ async serve ( options ?: { transport ?: 'http' | 'stdio' , port ?: number , endpoint ?: string } ) : Promise < void > {
141+ const transport = options ?. transport || ( process . env . MCP_TRANSPORT as 'http' | 'stdio' ) || 'http'
142+
143+ if ( transport === 'stdio' ) {
144+ // Use stdio transport (for traditional MCP clients)
145+ const { StdioServerTransport } = await import ( '@modelcontextprotocol/sdk/server/stdio.js' )
146+ const stdioTransport = new StdioServerTransport ( )
147+ await this . server . connect ( stdioTransport )
148+ console . log ( '📡 MCP server connected via stdio transport' )
149+ } else {
150+ // Default to StreamableHTTPServerTransport (for HTTP/web access)
151+ const { StreamableHTTPServerTransport } = await import ( '@modelcontextprotocol/sdk/server/streamableHttp.js' )
152+ const endpoint = options ?. endpoint || '/mcp'
153+
154+ if ( ! this . expressApp ) {
155+ // Create a standalone Express server if no app provided
156+ const express = await import ( 'express' )
157+ this . expressApp = express . default ( )
158+
159+ // Enable CORS
160+ this . expressApp . use ( ( req : any , res : any , next : any ) => {
161+ res . header ( 'Access-Control-Allow-Origin' , '*' )
162+ res . header ( 'Access-Control-Allow-Methods' , 'GET, POST, DELETE, OPTIONS' )
163+ res . header ( 'Access-Control-Allow-Headers' , 'Content-Type' )
164+ next ( )
165+ } )
166+
167+ const port = options ?. port || 3001
168+ this . expressApp . listen ( port , ( ) => {
169+ console . log ( `📡 MCP HTTP server listening on http://localhost:${ port } ${ endpoint } ` )
170+ } )
171+ }
172+
173+ console . log ( `📡 Registering HTTP endpoints on Express app...` )
174+
175+ // Create StreamableHTTPServerTransport in stateless mode
176+ const httpTransport = new StreamableHTTPServerTransport ( {
177+ sessionIdGenerator : undefined // Stateless mode
178+ } )
179+
180+ // Connect the MCP server to the transport
181+ await this . server . connect ( httpTransport )
182+
183+ // Add HTTP endpoints for StreamableHTTPServerTransport
184+ const express = await import ( 'express' )
185+
186+ // GET endpoint for SSE streaming
187+ this . expressApp . get ( endpoint , async ( req : any , res : any ) => {
188+ console . log ( `📡 HTTP GET request received at ${ endpoint } ` )
189+ await httpTransport . handleRequest ( req , res )
190+ } )
191+
192+ // POST endpoint for messages
193+ this . expressApp . post ( endpoint , express . json ( ) , async ( req : any , res : any ) => {
194+ console . log ( `📡 HTTP POST request received at ${ endpoint } ` )
195+ await httpTransport . handleRequest ( req , res , req . body )
196+ } )
197+
198+ // DELETE endpoint for session cleanup (if using stateful mode)
199+ this . expressApp . delete ( endpoint , async ( req : any , res : any ) => {
200+ console . log ( `📡 HTTP DELETE request received at ${ endpoint } ` )
201+ await httpTransport . handleRequest ( req , res )
202+ } )
203+
204+ console . log ( `📡 MCP server HTTP endpoints registered at ${ endpoint } ` )
205+ }
136206 }
137207
138208 /**
0 commit comments