diff --git a/packages/core/src/types/schemas.ts b/packages/core/src/types/schemas.ts index 86acf11d7..a8a6a66f3 100644 --- a/packages/core/src/types/schemas.ts +++ b/packages/core/src/types/schemas.ts @@ -1717,77 +1717,89 @@ export const CreateMessageResultWithToolsSchema = ResultSchema.extend({ /** * Primitive schema definition for boolean fields. */ -export const BooleanSchemaSchema = z.object({ - type: z.literal('boolean'), - title: z.string().optional(), - description: z.string().optional(), - default: z.boolean().optional() -}); +export const BooleanSchemaSchema = z + .object({ + type: z.literal('boolean'), + title: z.string().optional(), + description: z.string().optional(), + default: z.boolean().optional() + }) + .passthrough(); /** * Primitive schema definition for string fields. */ -export const StringSchemaSchema = z.object({ - type: z.literal('string'), - title: z.string().optional(), - description: z.string().optional(), - minLength: z.number().optional(), - maxLength: z.number().optional(), - format: z.enum(['email', 'uri', 'date', 'date-time']).optional(), - default: z.string().optional() -}); +export const StringSchemaSchema = z + .object({ + type: z.literal('string'), + title: z.string().optional(), + description: z.string().optional(), + minLength: z.number().optional(), + maxLength: z.number().optional(), + format: z.enum(['email', 'uri', 'date', 'date-time']).optional(), + default: z.string().optional() + }) + .passthrough(); /** * Primitive schema definition for number fields. */ -export const NumberSchemaSchema = z.object({ - type: z.enum(['number', 'integer']), - title: z.string().optional(), - description: z.string().optional(), - minimum: z.number().optional(), - maximum: z.number().optional(), - default: z.number().optional() -}); +export const NumberSchemaSchema = z + .object({ + type: z.enum(['number', 'integer']), + title: z.string().optional(), + description: z.string().optional(), + minimum: z.number().optional(), + maximum: z.number().optional(), + default: z.number().optional() + }) + .passthrough(); /** * Schema for single-selection enumeration without display titles for options. */ -export const UntitledSingleSelectEnumSchemaSchema = z.object({ - type: z.literal('string'), - title: z.string().optional(), - description: z.string().optional(), - enum: z.array(z.string()), - default: z.string().optional() -}); +export const UntitledSingleSelectEnumSchemaSchema = z + .object({ + type: z.literal('string'), + title: z.string().optional(), + description: z.string().optional(), + enum: z.array(z.string()), + default: z.string().optional() + }) + .passthrough(); /** * Schema for single-selection enumeration with display titles for each option. */ -export const TitledSingleSelectEnumSchemaSchema = z.object({ - type: z.literal('string'), - title: z.string().optional(), - description: z.string().optional(), - oneOf: z.array( - z.object({ - const: z.string(), - title: z.string() - }) - ), - default: z.string().optional() -}); +export const TitledSingleSelectEnumSchemaSchema = z + .object({ + type: z.literal('string'), + title: z.string().optional(), + description: z.string().optional(), + oneOf: z.array( + z.object({ + const: z.string(), + title: z.string() + }) + ), + default: z.string().optional() + }) + .passthrough(); /** * Use {@linkcode TitledSingleSelectEnumSchema} instead. * This interface will be removed in a future version. */ -export const LegacyTitledEnumSchemaSchema = z.object({ - type: z.literal('string'), - title: z.string().optional(), - description: z.string().optional(), - enum: z.array(z.string()), - enumNames: z.array(z.string()).optional(), - default: z.string().optional() -}); +export const LegacyTitledEnumSchemaSchema = z + .object({ + type: z.literal('string'), + title: z.string().optional(), + description: z.string().optional(), + enum: z.array(z.string()), + enumNames: z.array(z.string()).optional(), + default: z.string().optional() + }) + .passthrough(); // Combined single selection enumeration export const SingleSelectEnumSchemaSchema = z.union([UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema]); @@ -1795,38 +1807,46 @@ export const SingleSelectEnumSchemaSchema = z.union([UntitledSingleSelectEnumSch /** * Schema for multiple-selection enumeration without display titles for options. */ -export const UntitledMultiSelectEnumSchemaSchema = z.object({ - type: z.literal('array'), - title: z.string().optional(), - description: z.string().optional(), - minItems: z.number().optional(), - maxItems: z.number().optional(), - items: z.object({ - type: z.literal('string'), - enum: z.array(z.string()) - }), - default: z.array(z.string()).optional() -}); +export const UntitledMultiSelectEnumSchemaSchema = z + .object({ + type: z.literal('array'), + title: z.string().optional(), + description: z.string().optional(), + minItems: z.number().optional(), + maxItems: z.number().optional(), + items: z + .object({ + type: z.literal('string'), + enum: z.array(z.string()) + }) + .passthrough(), + default: z.array(z.string()).optional() + }) + .passthrough(); /** * Schema for multiple-selection enumeration with display titles for each option. */ -export const TitledMultiSelectEnumSchemaSchema = z.object({ - type: z.literal('array'), - title: z.string().optional(), - description: z.string().optional(), - minItems: z.number().optional(), - maxItems: z.number().optional(), - items: z.object({ - anyOf: z.array( - z.object({ - const: z.string(), - title: z.string() +export const TitledMultiSelectEnumSchemaSchema = z + .object({ + type: z.literal('array'), + title: z.string().optional(), + description: z.string().optional(), + minItems: z.number().optional(), + maxItems: z.number().optional(), + items: z + .object({ + anyOf: z.array( + z.object({ + const: z.string(), + title: z.string() + }) + ) }) - ) - }), - default: z.array(z.string()).optional() -}); + .passthrough(), + default: z.array(z.string()).optional() + }) + .passthrough(); /** * Combined schema for multiple-selection enumeration diff --git a/packages/core/src/types/spec.types.ts b/packages/core/src/types/spec.types.ts index ba849c546..3d499a70a 100644 --- a/packages/core/src/types/spec.types.ts +++ b/packages/core/src/types/spec.types.ts @@ -2879,6 +2879,7 @@ export interface StringSchema { maxLength?: number; format?: 'email' | 'uri' | 'date' | 'date-time'; default?: string; + [key: string]: unknown; } /** @@ -2894,6 +2895,7 @@ export interface NumberSchema { minimum?: number; maximum?: number; default?: number; + [key: string]: unknown; } /** @@ -2907,6 +2909,7 @@ export interface BooleanSchema { title?: string; description?: string; default?: boolean; + [key: string]: unknown; } /** @@ -2935,6 +2938,7 @@ export interface UntitledSingleSelectEnumSchema { * Optional default value. */ default?: string; + [key: string]: unknown; } /** @@ -2972,6 +2976,7 @@ export interface TitledSingleSelectEnumSchema { * Optional default value. */ default?: string; + [key: string]: unknown; } /** @@ -3020,6 +3025,7 @@ export interface UntitledMultiSelectEnumSchema { * Optional default value. */ default?: string[]; + [key: string]: unknown; } /** @@ -3070,6 +3076,7 @@ export interface TitledMultiSelectEnumSchema { * Optional default value. */ default?: string[]; + [key: string]: unknown; } /** @@ -3095,6 +3102,7 @@ export interface LegacyTitledEnumSchema { */ enumNames?: string[]; default?: string; + [key: string]: unknown; } /** diff --git a/test/integration/test/server/elicitation.test.ts b/test/integration/test/server/elicitation.test.ts index 55c989da0..47deb1678 100644 --- a/test/integration/test/server/elicitation.test.ts +++ b/test/integration/test/server/elicitation.test.ts @@ -161,7 +161,6 @@ function testElicitationFlow(validatorProvider: typeof ajvProvider | typeof cfWo age: { type: 'integer', minimum: 0, maximum: 150 }, street: { type: 'string' }, city: { type: 'string' }, - // @ts-expect-error - pattern is not a valid property by MCP spec, however it is making use of the Ajv validator zipCode: { type: 'string', pattern: '^[0-9]{5}$' }, newsletter: { type: 'boolean' }, notifications: { type: 'boolean' } @@ -280,7 +279,6 @@ function testElicitationFlow(validatorProvider: typeof ajvProvider | typeof cfWo requestedSchema: { type: 'object', properties: { - // @ts-expect-error - pattern is not a valid property by MCP spec, however it is making use of the Ajv validator zipCode: { type: 'string', pattern: '^[0-9]{5}$' } }, required: ['zipCode']