55import { ClientScenario , ConformanceCheck , SpecVersion } from '../../types' ;
66import { connectToServer } from './client-helper' ;
77
8+ const VISIBLE_ASCII_REGEX = / ^ [ \x21 - \x7E ] + $ / ;
9+
10+ const SESSION_SPEC_REFERENCES = [
11+ {
12+ id : 'MCP-Session-Management' ,
13+ url : 'https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management'
14+ }
15+ ] ;
16+
817export class ServerInitializeScenario implements ClientScenario {
918 name = 'server-initialize' ;
1019 specVersions : SpecVersion [ ] = [ '2025-06-18' , '2025-11-25' ] ;
@@ -18,8 +27,10 @@ export class ServerInitializeScenario implements ClientScenario {
1827- Accept \`initialize\` request with client info and capabilities
1928- Return valid initialize response with server info, protocol version, and capabilities
2029- Accept \`initialized\` notification from client after handshake
30+ - If a session ID is assigned, it MUST only contain visible ASCII characters (0x21 to 0x7E)
2131
22- This test verifies the server can complete the two-phase initialization handshake successfully.` ;
32+ This test verifies the server can complete the two-phase initialization handshake successfully,
33+ and validates session ID format if one is assigned.` ;
2334
2435 async run ( serverUrl : string ) : Promise < ConformanceCheck [ ] > {
2536 const checks : ConformanceCheck [ ] = [ ] ;
@@ -65,6 +76,91 @@ This test verifies the server can complete the two-phase initialization handshak
6576 }
6677 ]
6778 } ) ;
79+ return checks ;
80+ }
81+
82+ // Check: Session ID visible ASCII validation
83+ // Use a raw fetch to inspect the MCP-Session-Id response header,
84+ // since the SDK client transport does not expose it.
85+ try {
86+ const response = await fetch ( serverUrl , {
87+ method : 'POST' ,
88+ headers : {
89+ 'Content-Type' : 'application/json' ,
90+ Accept : 'application/json, text/event-stream' ,
91+ 'mcp-protocol-version' : '2025-11-25'
92+ } ,
93+ body : JSON . stringify ( {
94+ jsonrpc : '2.0' ,
95+ id : 1 ,
96+ method : 'initialize' ,
97+ params : {
98+ protocolVersion : '2025-11-25' ,
99+ capabilities : { } ,
100+ clientInfo : {
101+ name : 'conformance-session-id-test' ,
102+ version : '1.0.0'
103+ }
104+ }
105+ } )
106+ } ) ;
107+
108+ const sessionId = response . headers . get ( 'mcp-session-id' ) ;
109+
110+ if ( ! sessionId ) {
111+ checks . push ( {
112+ id : 'server-session-id-visible-ascii' ,
113+ name : 'ServerSessionIdVisibleAscii' ,
114+ description :
115+ 'Server-provided session ID uses only visible ASCII characters' ,
116+ status : 'INFO' ,
117+ timestamp : new Date ( ) . toISOString ( ) ,
118+ specReferences : SESSION_SPEC_REFERENCES ,
119+ details : {
120+ message :
121+ 'Server did not provide an MCP-Session-Id header (session ID is optional)'
122+ }
123+ } ) ;
124+ } else if ( VISIBLE_ASCII_REGEX . test ( sessionId ) ) {
125+ checks . push ( {
126+ id : 'server-session-id-visible-ascii' ,
127+ name : 'ServerSessionIdVisibleAscii' ,
128+ description :
129+ 'Server-provided session ID uses only visible ASCII characters' ,
130+ status : 'SUCCESS' ,
131+ timestamp : new Date ( ) . toISOString ( ) ,
132+ specReferences : SESSION_SPEC_REFERENCES ,
133+ details : {
134+ sessionId
135+ }
136+ } ) ;
137+ } else {
138+ checks . push ( {
139+ id : 'server-session-id-visible-ascii' ,
140+ name : 'ServerSessionIdVisibleAscii' ,
141+ description :
142+ 'Server-provided session ID uses only visible ASCII characters' ,
143+ status : 'FAILURE' ,
144+ timestamp : new Date ( ) . toISOString ( ) ,
145+ errorMessage :
146+ 'Session ID contains characters outside visible ASCII range (0x21-0x7E)' ,
147+ specReferences : SESSION_SPEC_REFERENCES ,
148+ details : {
149+ sessionId
150+ }
151+ } ) ;
152+ }
153+ } catch ( error ) {
154+ checks . push ( {
155+ id : 'server-session-id-visible-ascii' ,
156+ name : 'ServerSessionIdVisibleAscii' ,
157+ description :
158+ 'Server-provided session ID uses only visible ASCII characters' ,
159+ status : 'FAILURE' ,
160+ timestamp : new Date ( ) . toISOString ( ) ,
161+ errorMessage : `Failed to send initialize request for session ID check: ${ error instanceof Error ? error . message : String ( error ) } ` ,
162+ specReferences : SESSION_SPEC_REFERENCES
163+ } ) ;
68164 }
69165
70166 return checks ;
0 commit comments