|
106 | 106 | } |
107 | 107 |
|
108 | 108 | # Classes the spec defines as open key-value bags: `_meta` content, the |
109 | | -# JSON-Schema-document fields on `Tool`, and the schemas with explicit |
110 | | -# `additionalProperties: {}`. These keep `extra="allow"` so the sieve preserves |
111 | | -# arbitrary keys; every other class ignores extras. Per-version because codegen |
112 | | -# reuses class names across versions for unrelated schemas (e.g. `Data`). |
| 109 | +# JSON-Schema-document fields on `Tool`, the capability objects (documented as |
| 110 | +# "not a closed set"), and the schemas with explicit `additionalProperties: {}`. |
| 111 | +# These keep `extra="allow"` so the sieve preserves arbitrary keys; every other |
| 112 | +# class ignores extras. Per-version because codegen reuses class names across |
| 113 | +# versions for unrelated schemas (e.g. `Data`). |
113 | 114 | OPEN_CLASSES: dict[str, frozenset[str]] = { |
114 | | - "2025-11-25": frozenset({"Meta", "InputSchema", "OutputSchema", "Result", "GetTaskPayloadResult", "Data"}), |
| 115 | + "2025-11-25": frozenset( |
| 116 | + { |
| 117 | + "Meta", |
| 118 | + "InputSchema", |
| 119 | + "OutputSchema", |
| 120 | + "Result", |
| 121 | + "GetTaskPayloadResult", |
| 122 | + "Data", |
| 123 | + "ClientCapabilities", |
| 124 | + "ServerCapabilities", |
| 125 | + } |
| 126 | + ), |
115 | 127 | "2026-07-28": frozenset( |
116 | 128 | { |
117 | 129 | "MetaObject", |
|
122 | 134 | "InputSchema", |
123 | 135 | "OutputSchema", |
124 | 136 | "Result", |
| 137 | + "ClientCapabilities", |
| 138 | + "ServerCapabilities", |
125 | 139 | } |
126 | 140 | ), |
127 | 141 | } |
@@ -236,7 +250,7 @@ def patch(match: re.Match[str]) -> str: |
236 | 250 | return match.group(0).replace('extra="ignore"', 'extra="allow"') |
237 | 251 |
|
238 | 252 | source = re.sub( |
239 | | - r'^class (\w+)\(WireModel\):\n(?: {4}.*\n|\n)*? {4}model_config = ConfigDict\(\n {8}extra="ignore",\n {4}\)\n', |
| 253 | + r'^class (\w+)\(WireModel\):\n(?: {4}.*\n|\n)*? {4}model_config = ConfigDict\(extra="ignore"\)\n', |
240 | 254 | patch, |
241 | 255 | source, |
242 | 256 | flags=re.MULTILINE, |
@@ -296,6 +310,9 @@ def build(entry: dict[str, str]) -> str: |
296 | 310 | # them to full URLs so they resolve from the rendered API docs and pass the |
297 | 311 | # strict mkdocs link validation. |
298 | 312 | source = source.replace("](/", "](https://modelcontextprotocol.io/") |
| 313 | + source = re.sub( |
| 314 | + r'model_config = ConfigDict\(\n\s+(extra="ignore"),\n\s+\)', r"model_config = ConfigDict(\1)", source |
| 315 | + ) |
299 | 316 | source = allow_open_class_extras(source, OPEN_CLASSES[version]) |
300 | 317 | if epilogue := EPILOGUES.get(version, ""): |
301 | 318 | # Resolve aliases before rebuilding models with forward references. |
|
0 commit comments