|
|
@@ -25,7 +25,7 @@ import java.util.Map;
|
|
|
public class McpServer extends NanoHTTPD {
|
|
|
|
|
|
private static final String TAG = "McpServer";
|
|
|
- private static final String PROTOCOL_VERSION = "2024-11-05";
|
|
|
+ private static final String PROTOCOL_VERSION = "2025-03-26";
|
|
|
private static final String SERVER_NAME = "ijs-mcp";
|
|
|
private static final String SERVER_VERSION = "1.0";
|
|
|
|
|
|
@@ -51,7 +51,7 @@ public class McpServer extends NanoHTTPD {
|
|
|
|
|
|
// CORS preflight
|
|
|
if ("OPTIONS".equals(method)) {
|
|
|
- Response r = newFixedLengthResponse(Response.Status.OK, "text/plain", "");
|
|
|
+ Response r = newFixedLengthResponse(Response.Status.OK, "application/json", "{}");
|
|
|
addCommonHeaders(r);
|
|
|
return r;
|
|
|
}
|
|
|
@@ -64,14 +64,6 @@ public class McpServer extends NanoHTTPD {
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- // MCP SSE endpoint (for server→client notifications)
|
|
|
- if ("GET".equals(method) && "/mcp".equals(uri)) {
|
|
|
- String accept = session.getHeaders().getOrDefault("accept", "").toLowerCase();
|
|
|
- if (accept.contains("text/event-stream")) {
|
|
|
- return handleSse();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// DELETE /mcp terminates session
|
|
|
if ("DELETE".equals(method) && ("/mcp".equals(uri))) {
|
|
|
sessionId = java.util.UUID.randomUUID().toString();
|
|
|
@@ -80,6 +72,14 @@ public class McpServer extends NanoHTTPD {
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
+ // GET /mcp — Streamable HTTP server check
|
|
|
+ if ("GET".equals(method) && ("/mcp".equals(uri) || "/".equals(uri))) {
|
|
|
+ Response r = newFixedLengthResponse(Response.Status.OK, "application/json",
|
|
|
+ "{\"status\":\"ok\"}");
|
|
|
+ addCommonHeaders(r);
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
// Health check
|
|
|
if ("GET".equals(method) && "/health".equals(uri)) {
|
|
|
Response r = newFixedLengthResponse(Response.Status.OK, "application/json",
|
|
|
@@ -88,7 +88,8 @@ public class McpServer extends NanoHTTPD {
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "Not Found");
|
|
|
+ return newFixedLengthResponse(Response.Status.NOT_FOUND, "application/json",
|
|
|
+ "{\"error\":\"not found\"}");
|
|
|
}
|
|
|
|
|
|
private void addCommonHeaders(Response r) {
|
|
|
@@ -98,13 +99,6 @@ public class McpServer extends NanoHTTPD {
|
|
|
r.addHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
|
}
|
|
|
|
|
|
- /** SSE 端点:发送 endpoint 事件并保持连接 */
|
|
|
- private Response handleSse() {
|
|
|
- return newFixedLengthResponse(Response.Status.OK, "text/event-stream",
|
|
|
- "event: endpoint\r\n" +
|
|
|
- "data: /mcp?sessionId=" + sessionId + "\r\n\r\n");
|
|
|
- }
|
|
|
-
|
|
|
// ── JSON-RPC dispatch ─────────────────────────────────────────
|
|
|
|
|
|
private Response handleJsonRpc(IHTTPSession session) {
|
|
|
@@ -143,7 +137,7 @@ public class McpServer extends NanoHTTPD {
|
|
|
// Notification (no id) — no response expected
|
|
|
if (id == null) {
|
|
|
handleNotification(method, request.optJSONObject("params"));
|
|
|
- return newFixedLengthResponse(Response.Status.NO_CONTENT, "text/plain", "");
|
|
|
+ return newFixedLengthResponse(Response.Status.NO_CONTENT, "application/json", "");
|
|
|
}
|
|
|
|
|
|
// Regular request
|