diff --git a/.changeset/fix-compact-version-envelope.md b/.changeset/fix-compact-version-envelope.md new file mode 100644 index 0000000000..4c545a14ef --- /dev/null +++ b/.changeset/fix-compact-version-envelope.md @@ -0,0 +1,18 @@ +--- +"adcontextprotocol": patch +--- + +Restore `adcp_major_version` in compact MCP request schemas. + +The 3.2.0-beta.0 frozen snapshots for `buy-products`, `accept-proposal`, +and `control-media-buy` request schemas were published before the source +schemas gained the deprecated `adcp_major_version` field. Combined with +`additionalProperties: false`, this caused conforming SDK buyers to fail +MCP input validation when emitting both version fields (as the spec +requires through 3.x). + +Patches the 18 affected dist schema files across all beta.0 output +paths (bundled, MCP, profiles, model-context) and adds lint coverage to +prevent the same drift in future version snapshots. + +Refs #6649 diff --git a/dist/schemas/3.2.0-beta.0/bundled/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/bundled/media-buy/accept-proposal-request.json index bc92814936..69dd3b4be4 100644 --- a/dist/schemas/3.2.0-beta.0/bundled/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/bundled/media-buy/accept-proposal-request.json @@ -39,6 +39,13 @@ "3.1-rc.1" ] }, + "adcp_major_version": { + "type": "integer", + "deprecated": true, + "description": "DEPRECATED in favor of adcp_version (release-precision string). Servers MUST continue to honor this field through 3.x. Removed in 4.0. Original semantics: the AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, "idempotency_key": { "type": "string", "minLength": 16, @@ -669,4 +676,4 @@ "generatedAt": "2026-08-17T20:29:51.925Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } -} \ No newline at end of file +} diff --git a/dist/schemas/3.2.0-beta.0/bundled/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/bundled/media-buy/buy-products-request.json index a260999c0e..9ab52a0abf 100644 --- a/dist/schemas/3.2.0-beta.0/bundled/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/bundled/media-buy/buy-products-request.json @@ -27,6 +27,13 @@ "3.1-rc.1" ] }, + "adcp_major_version": { + "type": "integer", + "deprecated": true, + "description": "DEPRECATED in favor of adcp_version (release-precision string). Servers MUST continue to honor this field through 3.x. Removed in 4.0. Original semantics: the AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, "idempotency_key": { "type": "string", "minLength": 16, @@ -6899,4 +6906,4 @@ "generatedAt": "2026-08-17T20:29:52.149Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } -} \ No newline at end of file +} diff --git a/dist/schemas/3.2.0-beta.0/bundled/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/bundled/media-buy/control-media-buy-request.json index 4e368b983d..ae07cd01b3 100644 --- a/dist/schemas/3.2.0-beta.0/bundled/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/bundled/media-buy/control-media-buy-request.json @@ -38,6 +38,13 @@ "3.1-rc.1" ] }, + "adcp_major_version": { + "type": "integer", + "deprecated": true, + "description": "DEPRECATED in favor of adcp_version (release-precision string). Servers MUST continue to honor this field through 3.x. Removed in 4.0. Original semantics: the AdCP major version the buyer's payloads conform to. Sellers validate against their supported major_versions and return VERSION_UNSUPPORTED if unsupported. When omitted, the seller assumes its highest supported version.", + "minimum": 1, + "maximum": 99 + }, "idempotency_key": { "type": "string", "minLength": 16, @@ -5708,4 +5715,4 @@ "generatedAt": "2026-08-17T20:29:52.168Z", "note": "This is a bundled schema with all $ref resolved inline. For the modular version with references, use the parent directory." } -} \ No newline at end of file +} diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/accept-proposal-request.json index 9bcd0b4faa..4e6cd7f759 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/accept-proposal-request.json @@ -31,6 +31,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/buy-products-request.json index 8afde7da2a..8320eff563 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/buy-products-request.json @@ -19,6 +19,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/control-media-buy-request.json index 938dd40fd5..fbb667d52a 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/media-buy/control-media-buy-request.json @@ -30,6 +30,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json index afcc2e5264..f8d90b914b 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json @@ -28,6 +28,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json index 83de3d009c..a7ffd9261a 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json @@ -16,6 +16,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json index 9ecffe5328..6eac9df1b9 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json @@ -27,6 +27,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json index 61a34ff7fe..730b61cad5 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json @@ -4,6 +4,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string" }, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json index 0ba94b43ed..e56719c5ef 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json @@ -4,6 +4,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string" }, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json index 87cf9d22ed..a1aff60fdf 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json @@ -4,6 +4,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string" }, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/accept-proposal-request.json index b847c1a944..d09f7a14a9 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/accept-proposal-request.json @@ -28,6 +28,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/buy-products-request.json index ac42673b2f..74a50be684 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/buy-products-request.json @@ -16,6 +16,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/control-media-buy-request.json index 3268163f02..d8fce03881 100644 --- a/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/mcp/2026-07-28/profiles/production/media-buy/control-media-buy-request.json @@ -27,6 +27,9 @@ "adcp_version": { "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "#/$defs/external:core~1version-envelope.json/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/media-buy/accept-proposal-request.json b/dist/schemas/3.2.0-beta.0/media-buy/accept-proposal-request.json index 3a2a367931..227d6d8746 100644 --- a/dist/schemas/3.2.0-beta.0/media-buy/accept-proposal-request.json +++ b/dist/schemas/3.2.0-beta.0/media-buy/accept-proposal-request.json @@ -31,6 +31,9 @@ "adcp_version": { "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/media-buy/buy-products-request.json b/dist/schemas/3.2.0-beta.0/media-buy/buy-products-request.json index f6c782455f..79a284980f 100644 --- a/dist/schemas/3.2.0-beta.0/media-buy/buy-products-request.json +++ b/dist/schemas/3.2.0-beta.0/media-buy/buy-products-request.json @@ -19,6 +19,9 @@ "adcp_version": { "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/dist/schemas/3.2.0-beta.0/media-buy/control-media-buy-request.json b/dist/schemas/3.2.0-beta.0/media-buy/control-media-buy-request.json index 0b7e4e1d6f..797896112c 100644 --- a/dist/schemas/3.2.0-beta.0/media-buy/control-media-buy-request.json +++ b/dist/schemas/3.2.0-beta.0/media-buy/control-media-buy-request.json @@ -30,6 +30,9 @@ "adcp_version": { "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_version" }, + "adcp_major_version": { + "$ref": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/version-envelope.json#/properties/adcp_major_version" + }, "idempotency_key": { "type": "string", "minLength": 16, diff --git a/tests/compact-version-envelope.test.cjs b/tests/compact-version-envelope.test.cjs index 7fbee552bd..955f3bdd4a 100644 --- a/tests/compact-version-envelope.test.cjs +++ b/tests/compact-version-envelope.test.cjs @@ -10,11 +10,6 @@ const { ProtocolClient } = require('@adcp/sdk'); const SOURCE_DIR = path.resolve(__dirname, '..', 'static', 'schemas', 'source'); const ADCP_VERSION = '3.2.0-beta.0'; -const COMPACT_SCHEMAS_WITHOUT_MAJOR = new Set([ - 'buy_products', - 'accept_proposal', - 'control_media_buy', -]); function readSchema(uri) { if (!uri.startsWith('/schemas/')) { @@ -108,7 +103,7 @@ test('SDK auto version envelope passes every strict compact lifecycle request sc for (const [tool, request] of Object.entries(compactRequests)) { await ProtocolClient.callTool(agent, tool, request, { adcpVersion: ADCP_VERSION }); const expectedEnvelope = { - adcp_major_version: COMPACT_SCHEMAS_WITHOUT_MAJOR.has(tool) ? undefined : 3, + adcp_major_version: 3, adcp_version: '3.2-beta.0', }; assert.deepEqual({ diff --git a/tests/lint-version-envelope.test.cjs b/tests/lint-version-envelope.test.cjs index aa592bdf17..cf48a9b5f3 100644 --- a/tests/lint-version-envelope.test.cjs +++ b/tests/lint-version-envelope.test.cjs @@ -117,3 +117,51 @@ test('release-precision version grammar stays aligned across inlined negotiation ); assert.equal(versionPatternCheck?.pattern, canonicalPattern); }); + +test('every source request schema with adcp_version also has adcp_major_version', () => { + const violations = []; + for (const file of listJsonFiles(SOURCE_DIR)) { + if (!file.endsWith('-request.json')) continue; + let schema; + try { schema = JSON.parse(fs.readFileSync(file, 'utf8')); } catch { continue; } + if (!schema.properties) continue; + const hasVersion = 'adcp_version' in schema.properties; + const hasMajor = 'adcp_major_version' in schema.properties; + if (hasVersion && !hasMajor) { + violations.push(path.relative(path.resolve(__dirname, '..'), file)); + } + } + assert.deepEqual( + violations, + [], + 'Request schemas that declare adcp_version MUST also declare ' + + 'adcp_major_version (deprecated but required through 3.x). ' + + 'Missing in:\n' + violations.map((v) => ` ${v}`).join('\n'), + ); +}); + +const DIST_DIR = path.resolve(__dirname, '..', 'dist', 'schemas'); + +test('every versioned dist request schema with adcp_version also has adcp_major_version', () => { + if (!fs.existsSync(DIST_DIR)) return; + const violations = []; + for (const ver of fs.readdirSync(DIST_DIR).filter((d) => d.match(/^\d/))) { + const bundled = path.join(DIST_DIR, ver, 'bundled'); + if (!fs.existsSync(bundled)) continue; + for (const file of listJsonFiles(bundled)) { + if (!file.endsWith('-request.json')) continue; + let schema; + try { schema = JSON.parse(fs.readFileSync(file, 'utf8')); } catch { continue; } + if (!schema.properties) continue; + if ('adcp_version' in schema.properties && !('adcp_major_version' in schema.properties)) { + violations.push(path.relative(path.resolve(__dirname, '..'), file)); + } + } + } + assert.deepEqual( + violations, + [], + 'Versioned bundled dist schemas must preserve adcp_major_version alongside ' + + 'adcp_version. Missing in:\n' + violations.map((v) => ` ${v}`).join('\n'), + ); +});