feat(codegen): derive tool name from path when operationId is absent - #53
Conversation
The codegen assumed every operation has an operationId (parser.ts: `operationId!`), true for Taskade API v1 but NOT v2 (45 ops, zero operationIds) — every v2 tool name would be `undefined`. Add deriveToolName(method, path): strip path params, camelCase the segments (POST /promptAgent -> promptAgent), fall back to summary for description. Backward-compatible: v1 keeps using operationId. Unit-tested (5 cases).
🦋 Changeset detectedLatest commit: 123e6d7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Review follow-upRan Verdict: no blocking issues. Zero v1 regression — every v1 operation carries an Validated:
Two test-coverage gaps the analyzer flagged here are now closed in #55: the Non-blocking, for later: the derived name excludes the HTTP method, so a REST-style spec with |
Why
The codegen assumed every OpenAPI operation has an
operationId(parser.ts:operation.operationId!). True for Taskade API v1 — but v2 has 45 operations and zero operationIds (verified against/api/documentation/v2/json), so every v2 tool name would beundefinedand nothing would register. This is the prerequisite that unblocks porting v2 into the MCP server.What
deriveToolName(method, path): strips path params ({id}), camelCases remaining segments (POST /promptAgent→promptAgent;GET /media/{mediaId}/content→mediaContent), falls back to the HTTP method for a root path.parser.ts:name: operation.operationId ?? deriveToolName(method, path)anddescription: operation.description ?? operation.summary ?? ''.parser.test.ts(5 cases).Zero-regression
??fallback never fires. Verified: the v1 test assertsoperationIdstill wins.yarn lintclean; all tests pass (existingnormalizeAllOf/runtime+ newparser).@taskade/mcp-openapi-codegen; no change to the generated v1 tool set.Next in the chain
$refinField.data.fillerConfig.sourceRefthat makesdereference()throw — PR-3 will bundle-not-dereference or prune; tracking separately.)