@@ -149,8 +149,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
149149 return ;
150150 }
151151
152- // resp
153- resp .setStatus (HttpServletResponse .SC_OK );
154152 resp .setCharacterEncoding ("UTF-8" );
155153
156154 final McpServerTransport transport = new StreamableHttpServerTransport (resp .getOutputStream (), objectMapper );
@@ -168,14 +166,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
168166 try {
169167 messages = parseRequestBodyAsStream (req );
170168 }
171- catch (Exception e ) {
169+ catch (final Exception e ) {
172170 resp .sendError (HttpServletResponse .SC_BAD_REQUEST , "Invalid JSON input" );
173171 return ;
174172 }
175173
176174 boolean hasRequest = messages .stream ().anyMatch (m -> m instanceof McpSchema .JSONRPCRequest );
177175 if (!hasRequest ) {
178176 resp .setStatus (HttpServletResponse .SC_ACCEPTED );
177+ if ("stateless" .equals (session .getId ())) {
178+ transport .closeGracefully ().subscribe ();
179+ }
179180 return ;
180181 }
181182
@@ -190,24 +191,17 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
190191 Flux .fromIterable (messages )
191192 .flatMap (session ::handle )
192193 .doOnError (e -> sendError (resp , 500 , "Streaming failed: " + e .getMessage ()))
193- .then (transport . closeGracefully ( ))
194+ .then (closeIfStateless ( session , transport ))
194195 .subscribe ();
195196 }
196197 else if (accept .contains (APPLICATION_JSON )) {
197198 // TODO: Handle traditional JSON-RPC,
198199 resp .setContentType (APPLICATION_JSON );
199- Flux .fromIterable (messages ).flatMap (session ::handle ).collectList ().flatMap (responses -> {
200- try {
201- // todo: collect result if it's a response,
202- // hm handle should not be void ...
203- String json = objectMapper .writeValueAsString (responses .size () == 1 ? responses .get (0 ) : responses );
204- resp .getWriter ().write (json );
205- return transport .closeGracefully ();
206- }
207- catch (IOException e ) {
208- return Mono .error (e );
209- }
210- }).doOnError (e -> sendError (resp , 500 , "JSON response failed: " + e .getMessage ())).subscribe ();
200+ Flux .fromIterable (messages )
201+ .flatMap (session ::handle )
202+ .doOnError (e -> sendError (resp , 500 , "Streaming failed: " + e .getMessage ()))
203+ .then (closeIfStateless (session , transport ))
204+ .subscribe ();
211205
212206 }
213207 else {
@@ -266,7 +260,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws
266260 resp .setStatus (HttpServletResponse .SC_NO_CONTENT );
267261 }
268262
269- private List <McpSchema .JSONRPCMessage > parseRequestBodyAsStream (final HttpServletRequest req ) {
263+ private List <McpSchema .JSONRPCMessage > parseRequestBodyAsStream (final HttpServletRequest req ) throws IOException {
270264 try (final InputStream inputStream = req .getInputStream ()) {
271265 final JsonNode node = objectMapper .readTree (inputStream );
272266 if (node .isArray ()) {
@@ -288,10 +282,6 @@ else if (node.isObject()) {
288282
289283 }
290284 }
291- catch (Exception e ) {
292- throw new IllegalArgumentException ("Invalid JSON-RPC request: " + e .getMessage ());
293- }
294-
295285 }
296286
297287 private void sendEvent (PrintWriter writer , String eventType , String data ) throws IOException {
@@ -320,6 +310,12 @@ else if (sessionFactory != null) {
320310 }
321311 }
322312
313+ Mono <Void > closeIfStateless (final McpSession session , final McpServerTransport transport ) {
314+ return "stateless" .equals (session .getId ())
315+ ? transport .closeGracefully ()
316+ : Mono .empty ();
317+ }
318+
323319 private void sendError (final HttpServletResponse resp , final int code , final String msg ) {
324320 try {
325321 resp .sendError (code , msg );
0 commit comments