1
- import crypto from 'node:crypto' ;
2
1
import { ServerList } from '../src/server.ts' ;
3
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js ' ;
2
+ import { handleStreamable } from '../src/transport.ts ' ;
4
3
5
- // Store sessions in memory (for Vercel serverless functions)
6
- // Note: In production with multiple instances, use Redis or other storage
4
+ // Store sessions in memory (note: for production with multiple serverless instances, use external storage)
7
5
const streamableSessions = new Map ( ) ;
8
6
const serverList = new ServerList ( ) ;
9
7
10
- // Extract configuration from URL search parameters (copied from transport.ts)
11
- function extractConfigFromURL ( url ) {
12
- const config = { } ;
13
-
14
- if ( url . searchParams . has ( 'browserbaseApiKey' ) ) {
15
- config . browserbaseApiKey = url . searchParams . get ( 'browserbaseApiKey' ) || undefined ;
16
- }
17
-
18
- if ( url . searchParams . has ( 'browserbaseProjectId' ) ) {
19
- config . browserbaseProjectId = url . searchParams . get ( 'browserbaseProjectId' ) || undefined ;
20
- }
21
-
22
- if ( url . searchParams . has ( 'proxies' ) ) {
23
- config . proxies = url . searchParams . get ( 'proxies' ) === 'true' ;
24
- }
25
-
26
- if ( url . searchParams . has ( 'advancedStealth' ) ) {
27
- config . advancedStealth = url . searchParams . get ( 'advancedStealth' ) === 'true' ;
28
- }
29
-
30
- if ( url . searchParams . has ( 'contextId' ) ) {
31
- config . context = {
32
- contextId : url . searchParams . get ( 'contextId' ) || undefined ,
33
- persist : url . searchParams . has ( 'persist' ) ? url . searchParams . get ( 'persist' ) === 'true' : true
34
- } ;
35
- }
36
-
37
- const browserWidth = url . searchParams . get ( 'browserWidth' ) ;
38
- const browserHeight = url . searchParams . get ( 'browserHeight' ) ;
39
- if ( browserWidth || browserHeight ) {
40
- config . viewPort = { } ;
41
- if ( browserWidth ) config . viewPort . browserWidth = parseInt ( browserWidth , 10 ) ;
42
- if ( browserHeight ) config . viewPort . browserHeight = parseInt ( browserHeight , 10 ) ;
43
- }
44
-
45
- return config ;
46
- }
47
-
48
8
export default async function handler ( req , res ) {
49
9
const url = new URL ( req . url , `https://${ req . headers . host } ` ) ;
50
10
51
- // Handle session-based requests
52
- const sessionId = req . headers [ 'mcp-session-id' ] ;
53
- if ( sessionId ) {
54
- const transport = streamableSessions . get ( sessionId ) ;
55
- if ( ! transport ) {
56
- res . statusCode = 404 ;
57
- res . end ( 'Session not found' ) ;
58
- return ;
11
+ try {
12
+ // Reuse the existing handleStreamable function from transport.js
13
+ await handleStreamable ( req , res , url , serverList , streamableSessions ) ;
14
+ } catch ( error ) {
15
+ console . error ( 'Error handling request:' , error ) ;
16
+ if ( ! res . headersSent ) {
17
+ res . status ( 500 ) . send ( 'Internal Server Error' ) ;
59
18
}
60
- return await transport . handleRequest ( req , res ) ;
61
19
}
62
-
63
- // Handle GET requests specifically with the correct error format
64
- if ( req . method === 'GET' ) {
65
- res . setHeader ( 'Content-Type' , 'application/json' ) ;
66
- res . statusCode = 200 ;
67
- res . end ( JSON . stringify ( {
68
- jsonrpc : '2.0' ,
69
- error : {
70
- code : - 32000 ,
71
- message : 'Method not allowed.' ,
72
- } ,
73
- id : null ,
74
- } ) ) ;
75
- return ;
76
- }
77
-
78
- if ( req . method === 'POST' ) {
79
- // Extract configuration from URL parameters
80
- const config = extractConfigFromURL ( url ) ;
81
-
82
- const transport = new StreamableHTTPServerTransport ( {
83
- sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
84
- onsessioninitialized : sessionId => {
85
- streamableSessions . set ( sessionId , transport ) ;
86
- }
87
- } ) ;
88
-
89
- transport . onclose = ( ) => {
90
- if ( transport . sessionId )
91
- streamableSessions . delete ( transport . sessionId ) ;
92
- } ;
93
-
94
- const server = await serverList . create ( config ) ;
95
- await server . connect ( transport ) ;
96
- return await transport . handleRequest ( req , res ) ;
97
- }
98
-
99
- res . statusCode = 400 ;
100
- res . end ( 'Invalid request' ) ;
101
20
}
0 commit comments