Skip to content

feat(codegen): derive tool name from path when operationId is absent - #53

Merged
johnxie merged 1 commit into
mainfrom
feat/codegen-operationid-fallback
Jun 27, 2026
Merged

feat(codegen): derive tool name from path when operationId is absent#53
johnxie merged 1 commit into
mainfrom
feat/codegen-operationid-fallback

Conversation

@johnxie

@johnxie johnxie commented Jun 27, 2026

Copy link
Copy Markdown
Member

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 be undefined and 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 /promptAgentpromptAgent; GET /media/{mediaId}/contentmediaContent), falls back to the HTTP method for a root path.
  • parser.ts: name: operation.operationId ?? deriveToolName(method, path) and description: operation.description ?? operation.summary ?? ''.
  • New parser.test.ts (5 cases).

Zero-regression

  • v1 is unaffected — it has operationIds, so the ?? fallback never fires. Verified: the v1 test asserts operationId still wins.
  • yarn lint clean; all tests pass (existing normalizeAllOf/runtime + new parser).
  • Pure addition to @taskade/mcp-openapi-codegen; no change to the generated v1 tool set.

Next in the chain

  • PR-2: fix the dead v1 spec fetch URL.
  • PR-3: add the v2 tool layer (agent chat + webhooks) using this fallback. (Heads-up surfaced during testing: the live v2 spec has a broken $ref in Field.data.fillerConfig.sourceRef that makes dereference() throw — PR-3 will bundle-not-dereference or prune; tracking separately.)

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).
@johnxie
johnxie requested a review from Copilot June 27, 2026 08:26
@changeset-bot

changeset-bot Bot commented Jun 27, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 123e6d7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@taskade/mcp-openapi-codegen Patch

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@johnxie
johnxie merged commit 93017a7 into main Jun 27, 2026
1 of 2 checks passed
@johnxie
johnxie deleted the feat/codegen-operationid-fallback branch June 27, 2026 08:54
@github-actions github-actions Bot mentioned this pull request Jun 27, 2026
@johnxie

johnxie commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

Review follow-up

Ran /pr-review-toolkit:review-pr (code-reviewer + pr-test-analyzer) and the /code-review scored pass on this change. Posting the result for visibility — cc @deanzaka @lxcid.

Verdict: no blocking issues. Zero v1 regression — every v1 operation carries an operationId, so ?? short-circuits and deriveToolName never fires for v1; tools.generated.ts is byte-identical.

Validated:

  • deriveToolName run over all 45 live v2 operations → 0 operationIds, 45 unique names, 0 empty/malformed (e.g. POST /promptAgentpromptAgent, /media/{mediaId}/contentmediaContent).
  • Edge cases: /get, /api_keys & /api-keysapiKeys, path params dropped.

Two test-coverage gaps the analyzer flagged here are now closed in #55: the /[-_]/ kebab/snake segment split and the ?? '' empty-description tail now have explicit assertions in parser.test.ts.

Non-blocking, for later: the derived name excludes the HTTP method, so a REST-style spec with GET /x + POST /x would collide. Not reachable on v2 (flat, distinct RPC paths), but worth a duplicate-name guard in parseOpenApi if we ever feed REST specs through this path.

parser.ts deriveToolName

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants