fix(claude-code): harden MCP elicitation schema handling
This commit is contained in:
parent
1495e711e1
commit
bf4bcfadde
3 changed files with 46 additions and 9 deletions
|
|
@ -547,9 +547,6 @@ export async function createMcpServer(sessionManager: SessionManager): Promise<{
|
|||
type: 'string',
|
||||
title: item.key,
|
||||
description: descParts.join('\n'),
|
||||
format: 'password',
|
||||
writeOnly: true,
|
||||
'x-sensitive': true,
|
||||
};
|
||||
// Don't mark as required — empty string = skip
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,8 +313,15 @@ export function parseTextInputElicitation(
|
|||
request: Pick<SdkElicitationRequest, "message" | "mode" | "requestedSchema">,
|
||||
): ParsedTextInputField[] | null {
|
||||
if (request.mode && request.mode !== "form") return null;
|
||||
const properties = request.requestedSchema?.properties;
|
||||
if (!properties || typeof properties !== "object") return null;
|
||||
const schema = request.requestedSchema as
|
||||
| ({ properties?: Record<string, SdkElicitationFieldSchema>; keys?: Record<string, SdkElicitationFieldSchema> } & Record<string, unknown>)
|
||||
| undefined;
|
||||
const fieldsSource = schema?.properties && typeof schema.properties === "object"
|
||||
? schema.properties
|
||||
: schema?.keys && typeof schema.keys === "object"
|
||||
? schema.keys
|
||||
: undefined;
|
||||
if (!fieldsSource) return null;
|
||||
|
||||
const requiredSet = new Set(
|
||||
Array.isArray(request.requestedSchema?.required)
|
||||
|
|
@ -323,10 +330,10 @@ export function parseTextInputElicitation(
|
|||
);
|
||||
|
||||
const fields: ParsedTextInputField[] = [];
|
||||
for (const [fieldId, field] of Object.entries(properties)) {
|
||||
if (!field || typeof field !== "object") return null;
|
||||
if (field.type !== "string") return null;
|
||||
if (Array.isArray(field.oneOf) && field.oneOf.length > 0) return null;
|
||||
for (const [fieldId, field] of Object.entries(fieldsSource)) {
|
||||
if (!field || typeof field !== "object") continue;
|
||||
if (field.type !== "string") continue;
|
||||
if (Array.isArray(field.oneOf) && field.oneOf.length > 0) continue;
|
||||
|
||||
fields.push({
|
||||
id: fieldId,
|
||||
|
|
|
|||
|
|
@ -557,6 +557,39 @@ describe("stream-adapter — MCP elicitation bridge", () => {
|
|||
]);
|
||||
});
|
||||
|
||||
test("parseTextInputElicitation accepts legacy keys schema and skips unsupported fields", () => {
|
||||
const request = {
|
||||
serverName: "gsd-workflow",
|
||||
message: "Enter secure values",
|
||||
mode: "form" as const,
|
||||
requestedSchema: {
|
||||
type: "object" as const,
|
||||
keys: {
|
||||
API_TOKEN: {
|
||||
type: "string",
|
||||
title: "API_TOKEN",
|
||||
description: "Leave empty to skip.",
|
||||
},
|
||||
META: {
|
||||
type: "object",
|
||||
title: "metadata",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const parsed = parseTextInputElicitation(request as any);
|
||||
assert.deepEqual(parsed, [
|
||||
{
|
||||
id: "API_TOKEN",
|
||||
title: "API_TOKEN",
|
||||
description: "Leave empty to skip.",
|
||||
required: false,
|
||||
secure: true,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("createClaudeCodeElicitationHandler collects secure_env_collect fields through input dialogs", async () => {
|
||||
const secureRequest = {
|
||||
serverName: "gsd-workflow",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue