diff --git a/scripts/notion-openapi.json b/scripts/notion-openapi.json index 8fa15770..0aa56cbd 100644 --- a/scripts/notion-openapi.json +++ b/scripts/notion-openapi.json @@ -1513,6 +1513,11 @@ "summary": "Create comment", "description": "Creates a comment in a page or existing discussion thread.", "operationId": "create-a-comment", + "parameters": [ + { + "$ref": "#/components/parameters/notionVersion" + } + ], "requestBody": { "content": { "application/json": { diff --git a/src/openapi-mcp-server/openapi/__tests__/notion-version-coverage.test.ts b/src/openapi-mcp-server/openapi/__tests__/notion-version-coverage.test.ts new file mode 100644 index 00000000..ab26f21b --- /dev/null +++ b/src/openapi-mcp-server/openapi/__tests__/notion-version-coverage.test.ts @@ -0,0 +1,43 @@ +import fs from 'node:fs' +import path from 'node:path' +import { describe, expect, it } from 'vitest' +import type { OpenAPIV3 } from 'openapi-types' + +/** + * Every Notion API operation must declare the shared Notion-Version header + * parameter so HttpClient.buildDefaultHeaders() can attach the version. + */ +describe('Notion OpenAPI spec Notion-Version coverage', () => { + const spec = JSON.parse( + fs.readFileSync(path.resolve(process.cwd(), 'scripts/notion-openapi.json'), 'utf-8'), + ) as OpenAPIV3.Document + + const notionVersionRef = '#/components/parameters/notionVersion' + + function hasNotionVersionParameter(operation: OpenAPIV3.OperationObject): boolean { + return (operation.parameters ?? []).some((param) => { + if ('$ref' in param) { + return param.$ref === notionVersionRef + } + return param.in === 'header' && param.name === 'Notion-Version' + }) + } + + it('declares Notion-Version on every operation', () => { + const missing: string[] = [] + + for (const [pathKey, pathItem] of Object.entries(spec.paths ?? {})) { + for (const method of ['get', 'post', 'put', 'patch', 'delete'] as const) { + const operation = pathItem?.[method] + if (!operation?.operationId) { + continue + } + if (!hasNotionVersionParameter(operation)) { + missing.push(`${method.toUpperCase()} ${pathKey} (${operation.operationId})`) + } + } + } + + expect(missing).toEqual([]) + }) +})