|
2 | 2 |
|
3 | 3 | <!-- version list --> |
4 | 4 |
|
| 5 | +## v0.11.0 (2025-11-11) |
| 6 | + |
| 7 | +### Build System |
| 8 | + |
| 9 | +- **deps**: Bump mdformat from 0.7.22 to 1.0.0 |
| 10 | + ([#97](https://github.com/dougborg/stocktrim-openapi-client/pull/97), |
| 11 | + [`470d704`](https://github.com/dougborg/stocktrim-openapi-client/commit/470d7044606273923b77961f4e36efe9e2de5e7f)) |
| 12 | + |
| 13 | +Bumps [mdformat](https://github.com/hukkin/mdformat) from 0.7.22 to 1.0.0. - |
| 14 | +[Commits](https://github.com/hukkin/mdformat/compare/0.7.22...1.0.0) |
| 15 | + |
| 16 | +--- updated-dependencies: - dependency-name: mdformat dependency-version: 1.0.0 |
| 17 | + |
| 18 | +dependency-type: direct:production |
| 19 | + |
| 20 | +update-type: version-update:semver-major |
| 21 | + |
| 22 | +... |
| 23 | + |
| 24 | +Signed-off-by: dependabot[bot] <support@github.com> |
| 25 | + |
| 26 | +Co-authored-by: Doug Borg <dougborg@dougborg.org> |
| 27 | + |
| 28 | +- **deps**: Bump openapi-python-client from 0.27.0 to 0.27.1 |
| 29 | + ([`4749d3f`](https://github.com/dougborg/stocktrim-openapi-client/commit/4749d3fa5550dee1fa8f36b7262579601c22d1dc)) |
| 30 | + |
| 31 | +Bumps |
| 32 | +[openapi-python-client](https://github.com/openapi-generators/openapi-python-client) |
| 33 | +from 0.27.0 to 0.27.1. - |
| 34 | +[Release notes](https://github.com/openapi-generators/openapi-python-client/releases) - |
| 35 | +[Changelog](https://github.com/openapi-generators/openapi-python-client/blob/main/CHANGELOG.md) |
| 36 | +\- |
| 37 | +[Commits](https://github.com/openapi-generators/openapi-python-client/compare/v0.27.0...v0.27.1) |
| 38 | + |
| 39 | +--- updated-dependencies: - dependency-name: openapi-python-client dependency-version: |
| 40 | +0.27.1 |
| 41 | + |
| 42 | +dependency-type: direct:production |
| 43 | + |
| 44 | +update-type: version-update:semver-patch |
| 45 | + |
| 46 | +... |
| 47 | + |
| 48 | +Signed-off-by: dependabot[bot] <support@github.com> |
| 49 | + |
| 50 | +- **deps**: Bump pre-commit from 4.3.0 to 4.4.0 |
| 51 | + ([`57c1849`](https://github.com/dougborg/stocktrim-openapi-client/commit/57c1849c09732a1a56a092b2f02f518ada1350c7)) |
| 52 | + |
| 53 | +Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 4.3.0 to 4.4.0. - |
| 54 | +[Release notes](https://github.com/pre-commit/pre-commit/releases) - |
| 55 | +[Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) - |
| 56 | +[Commits](https://github.com/pre-commit/pre-commit/compare/v4.3.0...v4.4.0) |
| 57 | + |
| 58 | +--- updated-dependencies: - dependency-name: pre-commit dependency-version: 4.4.0 |
| 59 | + |
| 60 | +dependency-type: direct:production |
| 61 | + |
| 62 | +update-type: version-update:semver-minor |
| 63 | + |
| 64 | +... |
| 65 | + |
| 66 | +Signed-off-by: dependabot[bot] <support@github.com> |
| 67 | + |
| 68 | +- **deps**: Bump pydantic from 2.12.3 to 2.12.4 |
| 69 | + ([`3c4f712`](https://github.com/dougborg/stocktrim-openapi-client/commit/3c4f712f03458d5d7a3ccf82dd382d0620251666)) |
| 70 | + |
| 71 | +Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.12.3 to 2.12.4. - |
| 72 | +[Release notes](https://github.com/pydantic/pydantic/releases) - |
| 73 | +[Changelog](https://github.com/pydantic/pydantic/blob/v2.12.4/HISTORY.md) - |
| 74 | +[Commits](https://github.com/pydantic/pydantic/compare/v2.12.3...v2.12.4) |
| 75 | + |
| 76 | +--- updated-dependencies: - dependency-name: pydantic dependency-version: 2.12.4 |
| 77 | + |
| 78 | +dependency-type: direct:production |
| 79 | + |
| 80 | +update-type: version-update:semver-patch |
| 81 | + |
| 82 | +... |
| 83 | + |
| 84 | +Signed-off-by: dependabot[bot] <support@github.com> |
| 85 | + |
| 86 | +- **deps**: Bump python-semantic-release from 10.4.1 to 10.5.0 |
| 87 | + ([`89a11ed`](https://github.com/dougborg/stocktrim-openapi-client/commit/89a11ed5011e7ff6cb371c94dca26fd6cd83e4f1)) |
| 88 | + |
| 89 | +## Bumps [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) from 10.4.1 to 10.5.0. - [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) - [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.rst) |
| 90 | + |
| 91 | +[Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v10.4.1...v10.5) |
| 92 | + |
| 93 | +--- updated-dependencies: - dependency-name: python-semantic-release dependency-version: |
| 94 | +10.5.0 |
| 95 | + |
| 96 | +dependency-type: direct:production |
| 97 | + |
| 98 | +update-type: version-update:semver-minor |
| 99 | + |
| 100 | +... |
| 101 | + |
| 102 | +Signed-off-by: dependabot[bot] <support@github.com> |
| 103 | + |
| 104 | +### Chores |
| 105 | + |
| 106 | +- **release**: Mcp v0.11.0 |
| 107 | + ([`e129cbb`](https://github.com/dougborg/stocktrim-openapi-client/commit/e129cbb0baba6fd7a17d47e52312fadc43b5af88)) |
| 108 | + |
| 109 | +### Documentation |
| 110 | + |
| 111 | +- Add ADRs and update documentation |
| 112 | + ([#90](https://github.com/dougborg/stocktrim-openapi-client/pull/90), |
| 113 | + [`ec871c2`](https://github.com/dougborg/stocktrim-openapi-client/commit/ec871c2d02db7e636ee6b233ba428d75e62e7a00)) |
| 114 | + |
| 115 | +* docs: add ADRs and update documentation |
| 116 | + |
| 117 | +- Add ADR 002: Tool Interface Pattern (Pydantic + FastMCP) - Add ADR 003: Automated Tool |
| 118 | + Documentation strategy - Update overview.md and README.md with current features - |
| 119 | + Organize tool documentation investigation into docs/ - Add session summary for |
| 120 | + 2025-11-07 |
| 121 | + |
| 122 | +Related: #84, #85, #86 |
| 123 | + |
| 124 | +🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| 125 | + |
| 126 | +Co-Authored-By: Claude <noreply@anthropic.com> |
| 127 | + |
| 128 | +### Features |
| 129 | + |
| 130 | +- Replace product search with keyword search using Order Plan API |
| 131 | + ([#99](https://github.com/dougborg/stocktrim-openapi-client/pull/99), |
| 132 | + [`102cae9`](https://github.com/dougborg/stocktrim-openapi-client/commit/102cae9d858581ae3c3cfbd7336ecbf64d53a851)) |
| 133 | + |
| 134 | +* feat: replace product search with keyword search using Order Plan API |
| 135 | + |
| 136 | +Replace nearly-useless prefix-based product search with comprehensive keyword search |
| 137 | +that works across product names, codes, and categories. |
| 138 | + |
| 139 | +Changes: - tools/foundation/products.py: - Rename SearchProductsRequest.prefix → |
| 140 | +search_query - Replace Products API call with Order Plan API searchString - Update |
| 141 | +docstring with keyword search examples - tests: Update mocks to use Order Plan API and |
| 142 | +SkuOptimizedResultsDto |
| 143 | + |
| 144 | +Benefits: - Search by product name: "blue widget" - Search by category: "electronics" - |
| 145 | +Search by partial code: "WIDG" matches "WIDGET-001" - Much more useful than prefix-only |
| 146 | +search |
| 147 | + |
| 148 | +Before: search_products(prefix="WIDG") - must know exact prefix |
| 149 | + |
| 150 | +After: search_products(search_query="widget") - natural search |
| 151 | + |
| 152 | +🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| 153 | + |
| 154 | +Co-Authored-By: Claude <noreply@anthropic.com> |
| 155 | + |
| 156 | +- fix: use OrderPlanFilterCriteria instead of DTO for 415 error |
| 157 | + |
| 158 | +The Order Plan API endpoint expects OrderPlanFilterCriteria, not |
| 159 | +OrderPlanFilterCriteriaDto. Using the DTO version caused 415 "Unsupported Media Type" |
| 160 | +errors. |
| 161 | + |
| 162 | +Changes: - Import OrderPlanFilterCriteria instead of OrderPlanFilterCriteriaDto - Update |
| 163 | +test to be more robust when checking call arguments |
| 164 | + |
| 165 | +Fixes the 415 errors seen in production logs. |
| 166 | + |
| 167 | +- feat: add unpack decorator for flattened MCP parameters |
| 168 | + |
| 169 | +Add @unpack_pydantic_params decorator to enable flattened parameter calls instead of |
| 170 | +nested request objects, matching the pattern from katana-mcp. |
| 171 | + |
| 172 | +Changes: - Add unpack.py module with Unpack marker and decorator - Apply decorator to |
| 173 | +search_products tool - Update tests to use flattened parameters |
| 174 | + |
| 175 | +Benefits: - Better DX: search_products(search_query="widget") instead of |
| 176 | +search_products(request={"search_query": "widget"}) - Maintains Pydantic validation |
| 177 | +while exposing flat params to MCP - Compatible with FastMCP's parameter introspection |
| 178 | + |
| 179 | +Pattern from: https://github.com/dougborg/katana-openapi-client |
| 180 | + |
| 181 | +- feat(mcp): implement parameter flattening for all tools |
| 182 | + |
| 183 | +Apply @unpack_pydantic_params decorator to all MCP tools to expose flattened parameters |
| 184 | +instead of nested objects. This improves compatibility with Claude Code and other MCP |
| 185 | +clients that have issues serializing nested parameter objects. |
| 186 | + |
| 187 | +Changes: - Add unpack.py module with @unpack_pydantic_params decorator (from Katana) - |
| 188 | +Apply decorator to all 27 tools across 11 tool files - Update all foundation tool tests |
| 189 | +to use flattened parameters - Add ADR 0001 documenting parameter flattening decision - |
| 190 | +Update README with parameter flattening pattern documentation |
| 191 | + |
| 192 | +Technical Details: The decorator transforms function signatures at import time: - Scans |
| 193 | +for Annotated[Model, Unpack()] parameters - Extracts Pydantic model fields as individual |
| 194 | +KEYWORD_ONLY params - Updates __signature__ and __annotations__ for FastMCP |
| 195 | +introspection - At runtime, reconstructs validated model instances from flat params |
| 196 | + |
| 197 | +This provides: - Flat parameters for MCP protocol compatibility - Pydantic validation |
| 198 | +for type safety - Clean tool code working with typed model objects - Automatic parameter |
| 199 | +documentation from Field descriptions |
| 200 | + |
| 201 | +All 276 tests passing. |
| 202 | + |
| 203 | +Related: Katana MCP implementation (ef59809, 862ce79, a025ca9) |
| 204 | + |
| 205 | +- fix: address PR review feedback |
| 206 | + |
| 207 | +Address review comments from PR #99: |
| 208 | + |
| 209 | +1. Revert nullable supplier code - The SupplierInfo.code field should remain required |
| 210 | + (str) as it's fundamental for identifying suppliers and the underlying |
| 211 | + SupplierResponseDto has it as non-nullable. |
| 212 | + |
| 213 | +1. Improve 404 handling documentation - Add detailed comment explaining why StockTrim |
| 214 | + API returns 404 for "no results" instead of the more conventional 200 with empty |
| 215 | + list, and why we treat it as expected behavior rather than an error. |
| 216 | + |
| 217 | +1. Fix empty product code handling - Instead of using empty string fallback which |
| 218 | + violates ProductInfo schema, filter out order plan items that have missing/empty |
| 219 | + product codes to prevent creating invalid product records. |
| 220 | + |
| 221 | +- **mcp**: Add Docker MCP Registry support |
| 222 | + ([#93](https://github.com/dougborg/stocktrim-openapi-client/pull/93), |
| 223 | + [`7428599`](https://github.com/dougborg/stocktrim-openapi-client/commit/74285990b3617fae10f96afac598978b1c45aeae)) |
| 224 | + |
| 225 | +* docs: add ADR 001 documenting user confirmation pattern |
| 226 | + |
| 227 | +Add Architecture Decision Record documenting the choice to use FastMCP Elicitation for |
| 228 | +user confirmation on destructive operations. |
| 229 | + |
| 230 | +Documents: - Context and problem statement - 4 options considered (pre-flight, |
| 231 | +parameter, prompt, elicitation) - Decision rationale (MCP-native, industry best |
| 232 | +practice) - Implementation pattern with code examples - Tool categorization by risk |
| 233 | +level - Testing requirements - Consequences and validation criteria |
| 234 | + |
| 235 | +Decision: Use FastMCP Elicitation (MCP native protocol) |
| 236 | + |
| 237 | +Rationale: Standard protocol, strong safety guarantees, rich context, |
| 238 | + |
| 239 | +excellent developer experience |
| 240 | + |
| 241 | +Part of Issue #80 implementation. |
| 242 | + |
| 243 | +🤖 Generated with [Claude Code](https://claude.com/claude-code) |
| 244 | + |
| 245 | +Co-Authored-By: Claude <noreply@anthropic.com> |
| 246 | + |
| 247 | +- test: update purchase order and sales order deletion tests for elicitation |
| 248 | + |
| 249 | +* Replace old deletion tests with elicitation pattern tests - Add imports for |
| 250 | + AcceptedElicitation, DeclinedElicitation, CancelledElicitation - Test all elicitation |
| 251 | + response paths (not found, accepted, declined, cancelled) - Align with product and |
| 252 | + supplier test patterns - All 276 tests passing |
| 253 | + |
| 254 | +- test: implement autospec for service mocks to enforce interface compliance |
| 255 | + |
| 256 | +Use create_autospec() for all service mocks in conftest.py to prevent tests from passing |
| 257 | +while mocking non-existent methods. This ensures that test mocks always match the actual |
| 258 | +service interfaces. |
| 259 | + |
| 260 | +Benefits: - Tests will fail immediately if they mock non-existent methods - Prevents |
| 261 | +bugs where tests pass but production code fails - Provides better refactoring safety - |
| 262 | +Catches method name typos and signature mismatches |
| 263 | + |
| 264 | +This change was implemented after discovering that tests were mocking |
| 265 | +services.suppliers.list_suppliers() instead of list_all(), which allowed the bug to slip |
| 266 | +through to the resource implementation. |
| 267 | + |
| 268 | +All 276 tests pass with autospec enforcement. |
| 269 | + |
| 270 | +Addresses: #82 |
| 271 | + |
| 272 | +- fix: add nullable enum support to client regeneration + fix resource bug |
| 273 | + |
| 274 | +1. Add nullable enum field support to regeneration script - Add |
| 275 | + `add_nullable_to_enum_fields()` function - Mark OrderPlanFilterCriteria.currentStatus |
| 276 | + as nullable - Fixes "None is not a valid CurrentStatusEnum" errors - Addresses: #83 |
| 277 | + |
| 278 | +1. Fix supplier directory resource method name - Change `list_suppliers()` to |
| 279 | + `list_all()` - This bug was caught by autospec implementation - Related: #82 |
| 280 | + |
| 281 | +The regeneration script now handles enum fields that can be null in API responses, using |
| 282 | +the allOf + nullable pattern for OpenAPI 3.0. |
| 283 | + |
| 284 | +- fix: regenerate client with nullable currentStatus enum field |
| 285 | + |
| 286 | +Regenerated Python client from StockTrim OpenAPI spec with the nullable enum field fix |
| 287 | +applied. The currentStatus field in OrderPlanFilterCriteria can now handle null values |
| 288 | +from the API. |
| 289 | + |
| 290 | +Changes: - OrderPlanFilterCriteria.currentStatus is now CurrentStatusEnum | None | Unset |
| 291 | +\- from_dict() properly handles None values without throwing validation errors |
| 292 | + |
| 293 | +This fixes the "None is not a valid CurrentStatusEnum" error when querying order plan |
| 294 | +data. |
| 295 | + |
| 296 | +Fixes: #83 |
| 297 | + |
| 298 | +- fix: remove limit parameter from ProductService.list_all() calls |
| 299 | + |
| 300 | +The ProductService.list_all() method doesn't accept a limit parameter, but foundation.py |
| 301 | +was calling it with limit=50. This was caught when testing resources with MCP Inspector |
| 302 | +at runtime. |
| 303 | + |
| 304 | +Root cause: test_foundation.py was using mock_foundation_context which overrode the |
| 305 | +autospec'd services from conftest.py with plain AsyncMock, so tests couldn't catch the |
| 306 | +interface mismatch. |
| 307 | + |
| 308 | +Changes: - foundation.py: Remove limit=50 from list_all() call, use slicing instead - |
| 309 | +test_foundation.py: Remove mock_foundation_context fixture that was overriding |
| 310 | +autospec'd services with plain AsyncMock - test_foundation.py: Update all tests to use |
| 311 | +mock_context directly - test_foundation.py: Fix catalog limit test to verify slicing |
| 312 | +behavior |
| 313 | + |
| 314 | +This ensures autospec catches interface mismatches in resource tests. |
| 315 | + |
| 316 | +- fix: use bulk endpoint for listing all suppliers |
| 317 | + |
| 318 | +The Suppliers.get_all() method was incorrectly using /api/Suppliers endpoint without a |
| 319 | +code parameter, which returns 404. The StockTrim API has separate endpoints for |
| 320 | +different supplier operations: - /api/Suppliers?code=X - returns single supplier |
| 321 | +(requires code) - /api/SuppliersBulk |
| 322 | + |
| 323 | +- returns all suppliers (no parameters) |
| 324 | + |
| 325 | +This is different from other endpoints like Customers and Products which return arrays |
| 326 | +from their main endpoint. |
| 327 | + |
| 328 | +Changes: - Import get_api_suppliers_bulk from generated API - Use bulk endpoint when |
| 329 | +code is UNSET (listing all) - Use single endpoint when code is provided (get specific |
| 330 | +supplier) - Update docstring to clarify the conditional behavior |
| 331 | + |
| 332 | +This fixes the 404 error in the supplier directory MCP resource. |
| 333 | + |
| 334 | +- feat(mcp): add Dockerfile for Docker MCP Registry |
| 335 | + |
| 336 | +Add Dockerfile to support publishing MCP server to Docker Hub via Docker MCP Registry. |
| 337 | +Image installs stocktrim-openapi-client from PyPI and runs the MCP server. |
| 338 | + |
| 339 | +Related to #2 |
| 340 | + |
| 341 | +- feat(mcp): add tools.json generation script |
| 342 | + |
| 343 | +Add script to auto-generate tools.json from registered MCP tools to keep Docker MCP |
| 344 | +Registry submission in sync with actual tool implementations. |
| 345 | + |
| 346 | +Script introspects FastMCP tool manager and extracts tool names and descriptions from |
| 347 | +registered tools. |
| 348 | + |
| 349 | +______________________________________________________________________ |
| 350 | + |
| 351 | +Co-authored-by: Doug Borg <dougborg@apple.com> |
| 352 | + |
| 353 | +Co-authored-by: Claude <noreply@anthropic.com> |
| 354 | + |
5 | 355 | ## v0.10.0 (2025-11-09) |
6 | 356 |
|
7 | 357 | ### Chores |
|
0 commit comments