Tag the 16 untagged operations (one tag per op) to unblock MCP catalog generation - #878
Conversation
The reports/timeline family, the check-in question operations,
RepositionTodo, and the card-column subscribe/unsubscribe operations
carried no OpenAPI tag. basecamp/mcp's catalog.Load requires exactly one
tag per operation to generate an MCP tool catalog from the model
build-products, so these blocked catalog generation for basecamp-mcp-server.
Assign each its domain tag, reusing existing tags where a sibling family
exists and adding Reports, Timeline, and Checkins to mirror the service
groupings the SDK generators already emit for these operations:
Reports: GetProgressReport, GetUpcomingSchedule, GetAssignedTodos,
GetOverdueTodos, GetPersonProgress
Timeline: GetProjectTimeline
Checkins: GetQuestionReminders, ListQuestionAnswerers,
GetAnswersByPerson, UpdateQuestionNotificationSettings,
PauseQuestion, ResumeQuestion
Todos: RepositionTodo
People: ListAssignablePeople
Card Tables: SubscribeToCardColumn, UnsubscribeFromCardColumn
The generators route service grouping off tags[0]. The TypeScript, Kotlin,
Swift, and Rust configs already list the card-column subscribe operations
under the Card Tables -> CardColumns split; complete that staging in the
Ruby and Python configs so the two operations stay on the CardColumns
service across all six SDKs instead of drifting to CardTables. All seven
SDKs regenerate byte-identical; the only generated artifact that changes is
the TypeScript vendored openapi-stripped.json, which mirrors the new tags.
behavior-model.json is unchanged: tags live only in the OpenAPI projection,
not the behavior model.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
🟢 Approved
All 262 operations have exactly one tag, projections agree, and existing service assignments are preserved.
Pull request overview
Tags all 262 OpenAPI operations exactly once while preserving existing SDK service grouping.
Changes:
- Adds tags to 16 previously untagged operations.
- Preserves Ruby and Python card-column routing.
- Regenerates OpenAPI projections.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
File summaries
| File | Description |
|---|---|
spec/overlays/tags.smithy |
Assigns the missing operation tags. |
openapi.json |
Regenerates the canonical OpenAPI projection. |
typescript/src/generated/openapi-stripped.json |
Synchronizes TypeScript’s vendored projection. |
ruby/scripts/generate-services.rb |
Preserves card-column service placement. |
python/scripts/generate_services.py |
Preserves card-column service placement. |
Review details
- Files reviewed: 4/5 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bfe1634c06
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Review threads: 1 resolved (1 fixed).
CI is green on 26f8841, Copilot approved, and the PR is mergeable (CLEAN). No threads open for a decision. |
Why
basecamp-mcp-serverwants to generate its MCP tool catalog from this SDK's Smithy build-products (openapi.json+behavior-model.json), the wayhey-mcp-serverdoes fromhey-sdk. The sharedbasecamp/mcptoolkit'scatalog.Loadrequires exactly one OpenAPI tag per operation, and it fails today because 16 operations carry no tag and there is noCheckinstag. This is M1 of that migration (card 10299423668; mcp-server catalog spike basecamp-mcp-server#140).This PR tags the 16 previously-untagged operations so every operation ends with exactly one tag. Verified: 262 operations, 0 untagged, 0 multi-tag.
Operations retagged (op → tag)
Reused existing domain tags where a sibling family exists, and added
Reports,Timeline, andCheckins(new tags) for families with no existing home. The new tags mirror the service groupings the SDK generators already emit for these operations, so generated client code is unchanged.ReportsTimelineCheckinsTodosPeopleCard TablesTags are applied in
spec/overlays/tags.smithy(apply <Op> @tags([...])), the existing mechanism;openapi.jsonis the regenerated projection (make smithy-build).behavior-model.jsonis unchanged — tags live only in the OpenAPI projection, not the behavior model.Tags are not free metadata here — the generator coupling
In this repo the OpenAPI
tagsfield is overloaded: the seven language SDK generators route service grouping offtags[0], and these 16 operations were deliberately untagged and routed via each generator's hand-maintainedUntaggedsplit table. Adding tags reroutes them, so this is not a pure-metadata change.The tag choices above were made specifically to keep the generated service grouping byte-identical:
Reports/Timeline/Checkinsmirror the service names the generators already produce, andTodos/Peopleland on the same base service. One gap: the card-column subscribe/unsubscribe ops live on theCardColumnssub-service, and the TypeScript, Kotlin, Swift, and Rust configs already list them under theCard Tables → CardColumnssplit — but the Ruby and Python configs did not (they had them only in theUntaggedsplit). This PR completes that staging inruby/scripts/generate-services.rbandpython/scripts/generate_services.pyso all six split-table SDKs agree.Verification (what CI runs)
smithy validate: clean (1 pre-existing unrelated deprecation warning)smithy-check/behavior-model-check: exports up to datecheck-service-inventory-parity: 54 services agree across all renderings (no service added/removed)check-operation-assignment-parity: 262 ops each land on the same service in all 6 SDKsopenapi-stripped.json, which mirrors the new tags.Remaining prerequisite for catalog generation: binary-body operations (not in this PR)
Three operations use non-JSON request bodies that
catalog.Loadalso rejects:UpdateAccountLogo(multipart),CreateAttachmentandCreateCampfireUpload(octet-stream). This PR deliberately does not touch them — they are file-upload operations that don't map cleanly onto JSON-argument MCP tools.Recommendation: handle these on the loader/curation side — exclude them from the generated catalog in
basecamp-mcp-server/ themcptoolkit — rather than changing their request bodies in the SDK (which would misrepresent the real API). Final call left to the maintainers.Sequencing
After this merges and the SDK re-releases the model exports,
basecamp-mcp-serverre-syncs (its spike's prerequisite-gate test flips) and M2/M3 proceed.Notes / follow-ups (optional, not done here to keep blast radius low)
GetQuestionnaire,ListQuestions, …) remain taggedAutomation(they already had a home). They share theCheckinsservice, so consolidating the whole check-in family under theCheckinstag is an editorial call left to maintainers.Untaggedsplit table is now entirely dead (all ops are tagged). Left in place as a safety net; can be pruned later.Summary by cubic
Tags the 16 OpenAPI operations that had no tag so every operation now has exactly one, unblocking MCP catalog generation for
basecamp-mcp-server.Reports,Timeline, andCheckinstags for families with no existing tag home.Todos,People, andCard Tablesfor the remaining operations.CardColumnsservice split in the Ruby and Python generators.url-routes.jsonchange, gaining the new tags and tag-derived resource names.Written for commit 26f8841. Summary will update on new commits.