feat(mcp): add smart JSON parser for flexible input formats

Support multiple MCP configuration input formats:
- Pure config object: { "command": "npx", ... }
- Key-value pair fragment: "server-name": { "command": "npx", ... }
- Wrapped object: { "server-name": { "command": "npx", ... } }

The parser automatically:
- Detects and wraps JSON fragments into complete objects
- Extracts server name from single-key objects
- Auto-fills ID and Name fields when applicable
- Formats the config for display

This improves UX by allowing users to paste configs directly from
.claude.json or .codex/config.toml without manual editing.
This commit is contained in:
Jason
2025-11-16 20:08:04 +08:00
parent f79efb86cd
commit 98a1305684
2 changed files with 85 additions and 8 deletions

View File

@@ -13,6 +13,57 @@ export function formatJSON(value: string): string {
return JSON.stringify(parsed, null, 2);
}
/**
* 智能解析 MCP JSON 配置
* 支持两种格式:
* 1. 纯配置对象:{ "command": "npx", "args": [...], ... }
* 2. 带键名包装: "server-name": { "command": "npx", ... } 或 { "server-name": {...} }
*
* @param jsonText - JSON 字符串
* @returns { id?: string, config: object, formattedConfig: string }
* @throws 如果 JSON 格式无效
*/
export function parseSmartMcpJson(jsonText: string): {
id?: string;
config: any;
formattedConfig: string;
} {
let trimmed = jsonText.trim();
if (!trimmed) {
return { config: {}, formattedConfig: "" };
}
// 如果是键值对片段("key": {...}),包装成完整对象
if (trimmed.startsWith('"') && !trimmed.startsWith('{')) {
trimmed = `{${trimmed}}`;
}
const parsed = JSON.parse(trimmed);
// 如果是单键对象且值是对象,提取键名和配置
const keys = Object.keys(parsed);
if (
keys.length === 1 &&
parsed[keys[0]] &&
typeof parsed[keys[0]] === "object" &&
!Array.isArray(parsed[keys[0]])
) {
const id = keys[0];
const config = parsed[id];
return {
id,
config,
formattedConfig: JSON.stringify(config, null, 2),
};
}
// 否则直接使用
return {
config: parsed,
formattedConfig: JSON.stringify(parsed, null, 2),
};
}
/**
* TOML 格式化功能已禁用
*