Skip to content

Commit 5c5a61d

Browse files
committed
fix: inline registration schema definitions
1 parent 8c91fa4 commit 5c5a61d

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

src/core/__tests__/structured-output-schema.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ function expectStandaloneCompile(schema: JsonObject): void {
2525
expect(() => ajv.compile(schema)).not.toThrow();
2626
}
2727

28+
function stripRegistrationResourceEnvelope(schema: JsonObject): JsonObject {
29+
const stripped = JSON.parse(JSON.stringify(schema)) as JsonObject;
30+
delete stripped.$schema;
31+
delete stripped.$id;
32+
delete stripped.$defs;
33+
return stripped;
34+
}
35+
2836
describe('structured output schema bundling', () => {
2937
beforeEach(() => {
3038
__resetMcpOutputSchemaCacheForTests();
@@ -119,10 +127,20 @@ describe('structured output schema bundling', () => {
119127
$id: 'https://xcodebuildmcp.com/schemas/structured-output/xcodebuildmcp.output.simulator-list/1.registration.schema.json',
120128
type: 'object',
121129
oneOf: [
122-
getMcpOutputSchema(ref),
123-
getMcpOutputSchema({ schema: 'xcodebuildmcp.output.error', version: '1' }),
130+
stripRegistrationResourceEnvelope(getMcpOutputSchema(ref)),
131+
stripRegistrationResourceEnvelope(
132+
getMcpOutputSchema({ schema: 'xcodebuildmcp.output.error', version: '1' }),
133+
),
124134
],
135+
$defs: {
136+
...((getMcpOutputSchema(ref).$defs as JsonObject) ?? {}),
137+
...((getMcpOutputSchema({ schema: 'xcodebuildmcp.output.error', version: '1' })
138+
.$defs as JsonObject) ?? {}),
139+
},
125140
});
141+
expect((jsonSchema.oneOf as JsonObject[])[0].$defs).toBeUndefined();
142+
expect((jsonSchema.oneOf as JsonObject[])[0].$id).toBeUndefined();
143+
expect((jsonSchema.$defs as JsonObject).errorConsistency).toBeDefined();
126144
expectNoExternalCommonRefs(jsonSchema);
127145
expectStandaloneCompile(jsonSchema);
128146
});

src/core/structured-output-schema.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,26 @@ function bundleSchema(rootSchema: JsonObject, commonSchema: JsonObject): JsonObj
203203
return bundled;
204204
}
205205

206+
function inlineRegistrationSchemaResource(schema: JsonObject): {
207+
schema: JsonObject;
208+
defs: JsonObject;
209+
} {
210+
const inlinedSchema = cloneJson(schema);
211+
const defsCandidate = inlinedSchema.$defs === undefined ? {} : cloneJson(inlinedSchema.$defs);
212+
if (!isRecord(defsCandidate)) {
213+
throw new Error('Structured output registration $defs must be an object when present.');
214+
}
215+
216+
delete inlinedSchema.$schema;
217+
delete inlinedSchema.$id;
218+
delete inlinedSchema.$defs;
219+
220+
return {
221+
schema: inlinedSchema,
222+
defs: defsCandidate,
223+
};
224+
}
225+
206226
export function getMcpOutputSchema(ref: StructuredOutputSchemaRef): JsonObject {
207227
assertSchemaRef(ref);
208228
const cacheKey = `${ref.schema}@${ref.version}`;
@@ -226,13 +246,30 @@ function getMcpOutputSchemaForRegistrationJson(ref: StructuredOutputSchemaRef):
226246
if (ref.schema === STRUCTURED_ERROR_SCHEMA_REF.schema) {
227247
return toolSchema;
228248
}
249+
const errorSchema = getMcpOutputSchema(STRUCTURED_ERROR_SCHEMA_REF);
250+
const toolResource = inlineRegistrationSchemaResource(toolSchema);
251+
const errorResource = inlineRegistrationSchemaResource(errorSchema);
252+
const defs: JsonObject = {};
229253

230-
return {
254+
for (const [name, definition] of Object.entries(toolResource.defs)) {
255+
mergeDefinition(defs, name, definition);
256+
}
257+
for (const [name, definition] of Object.entries(errorResource.defs)) {
258+
mergeDefinition(defs, name, definition);
259+
}
260+
261+
const registrationSchema: JsonObject = {
231262
$schema: 'https://json-schema.org/draft/2020-12/schema',
232263
$id: `https://xcodebuildmcp.com/schemas/structured-output/${ref.schema}/${ref.version}.registration.schema.json`,
233264
type: 'object',
234-
oneOf: [toolSchema, getMcpOutputSchema(STRUCTURED_ERROR_SCHEMA_REF)],
265+
oneOf: [toolResource.schema, errorResource.schema],
235266
};
267+
268+
if (Object.keys(defs).length > 0) {
269+
registrationSchema.$defs = defs;
270+
}
271+
272+
return registrationSchema;
236273
}
237274

238275
export function getMcpOutputSchemaForRegistration(ref: StructuredOutputSchemaRef): McpOutputSchema {

0 commit comments

Comments
 (0)