feat(mcp): add SSE (Server-Sent Events) transport type support

Add comprehensive support for SSE transport type to MCP server configuration,
enabling real-time streaming connections alongside existing stdio and http types.

Backend Changes:
- Add SSE type validation in mcp.rs validate_server_spec()
- Extend Codex TOML import/export to handle SSE servers
- Update claude_mcp.rs legacy API for backward compatibility
- Unify http/sse handling in json_server_to_toml_table()

Frontend Changes:
- Extend McpServerSpec type definition to include "sse"
- Add SSE radio button to configuration wizard UI
- Update wizard form logic to handle SSE url and headers
- Add SSE validation in McpFormModal submission

Validation & Error Handling:
- Add SSE support in useMcpValidation hook (TOML/JSON)
- Extend tomlUtils normalizeServerConfig for SSE parsing
- Update Zod schemas (common.ts, mcp.ts) with SSE enum
- Add SSE error message mapping in errorUtils

Internationalization:
- Add "typeSse" translations (zh: "sse", en: "sse")

Tests:
- Add SSE validation test cases in useMcpValidation.test.tsx

SSE Configuration Format:
{
  "type": "sse",
  "url": "https://api.example.com/sse",
  "headers": { "Authorization": "Bearer token" }
}
This commit is contained in:
Jason
2025-11-16 16:15:17 +08:00
parent 4fc7413ffa
commit bfc27349b3
13 changed files with 92 additions and 36 deletions
+6 -3
View File
@@ -58,7 +58,7 @@ export const jsonConfigSchema = z
* 通用的 TOML 配置文本校验:
* - 允许为空(由上层业务决定是否必填)
* - 语法与结构有效
* - 针对 stdio/http 的必填字段(command/url)进行提示
* - 针对 stdio/http/sse 的必填字段(command/url)进行提示
*/
export const tomlConfigSchema = z.string().superRefine((value, ctx) => {
const err = validateToml(value);
@@ -80,10 +80,13 @@ export const tomlConfigSchema = z.string().superRefine((value, ctx) => {
message: "stdio 类型需填写 command",
});
}
if (server.type === "http" && !server.url?.trim()) {
if (
(server.type === "http" || server.type === "sse") &&
!server.url?.trim()
) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "http 类型需填写 url",
message: `${server.type} 类型需填写 url`,
});
}
} catch (e: any) {
+3 -3
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
const mcpServerSpecSchema = z
.object({
type: z.enum(["stdio", "http"]).optional(),
type: z.enum(["stdio", "http", "sse"]).optional(),
command: z.string().trim().optional(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
@@ -19,10 +19,10 @@ const mcpServerSpecSchema = z
path: ["command"],
});
}
if (type === "http" && !server.url?.trim()) {
if ((type === "http" || type === "sse") && !server.url?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "http 类型需填写 url",
message: `${type} 类型需填写 url`,
path: ["url"],
});
}