Skip to content

Tag the 16 untagged operations (one tag per op) to unblock MCP catalog generation - #878

Merged
jeremy merged 2 commits into
mainfrom
catalog-tag-untagged-ops
Sep 16, 2026
Merged

jeremy merged 2 commits into
mainfrom
catalog-tag-untagged-ops

Conversation

@jeremy

@jeremy jeremy commented Sep 14, 2026

Copy link
Copy Markdown
Member

Why

basecamp-mcp-server wants to generate its MCP tool catalog from this SDK's Smithy build-products (openapi.json + behavior-model.json), the way hey-mcp-server does from hey-sdk. The shared basecamp/mcp toolkit's catalog.Load requires exactly one OpenAPI tag per operation, and it fails today because 16 operations carry no tag and there is no Checkins tag. 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, and Checkins (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.

Tag Operations New tag?
Reports GetProgressReport, GetUpcomingSchedule, GetAssignedTodos, GetOverdueTodos, GetPersonProgress new
Timeline GetProjectTimeline new
Checkins GetQuestionReminders, ListQuestionAnswerers, GetAnswersByPerson, UpdateQuestionNotificationSettings, PauseQuestion, ResumeQuestion new
Todos RepositionTodo existing
People ListAssignablePeople existing
Card Tables SubscribeToCardColumn, UnsubscribeFromCardColumn existing

Tags are applied in spec/overlays/tags.smithy (apply <Op> @tags([...])), the existing mechanism; openapi.json is the regenerated projection (make smithy-build). behavior-model.json is 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 tags field is overloaded: the seven language SDK generators route service grouping off tags[0], and these 16 operations were deliberately untagged and routed via each generator's hand-maintained Untagged split 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/Checkins mirror the service names the generators already produce, and Todos/People land on the same base service. One gap: the card-column subscribe/unsubscribe ops live on the CardColumns sub-service, and the TypeScript, Kotlin, Swift, and Rust configs already list them under the Card Tables → CardColumns split — but the Ruby and Python configs did not (they had them only in the Untagged split). This PR completes that staging in ruby/scripts/generate-services.rb and python/scripts/generate_services.py so 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 date
  • check-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 SDKs
  • Generated-drift checks — all seven SDKs report no drift: Go, TypeScript, Ruby, Python, Kotlin, Swift, Rust. The only regenerated artifact is TypeScript's vendored openapi-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.Load also rejects: UpdateAccountLogo (multipart), CreateAttachment and CreateCampfireUpload (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 / the mcp toolkit — 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-server re-syncs (its spike's prerequisite-gate test flips) and M2/M3 proceed.

Notes / follow-ups (optional, not done here to keep blast radius low)

  • The existing questionnaire/question/answer CRUD ops (GetQuestionnaire, ListQuestions, …) remain tagged Automation (they already had a home). They share the Checkins service, so consolidating the whole check-in family under the Checkins tag is an editorial call left to maintainers.
  • Each generator's Untagged split 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.

  • Adds new Reports, Timeline, and Checkins tags for families with no existing tag home.
  • Reuses Todos, People, and Card Tables for the remaining operations.
  • Moves the card-column subscribe/unsubscribe operations into the CardColumns service split in the Ruby and Python generators.
  • Generated SDK code is unchanged across all seven SDKs; only the OpenAPI projection, TypeScript's vendored OpenAPI file, and Go's url-routes.json change, gaining the new tags and tag-derived resource names.

Written for commit 26f8841. Summary will update on new commits.

Review in cubic

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.
Copilot AI balanced review requested due to automatic review settings September 14, 2026 10:37
@github-actions github-actions Bot added typescript Pull requests that update TypeScript code ruby Pull requests that update the Ruby SDK spec Changes to the Smithy spec or OpenAPI python Pull requests that update the Python SDK labels Sep 14, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T12:09:59.024264Z 26f8841 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

🟢 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 run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 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".

Comment thread spec/overlays/tags.smithy
@github-actions github-actions Bot added the go label Sep 14, 2026
@jeremy

jeremy commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

Review threads: 1 resolved (1 fixed).

  • Codex P1 "Regenerate the embedded URL route table" (r4004346152) — go/pkg/basecamp/url-routes.json regenerated in 26f8841; the 14 stale records (16 newly-tagged operations) now carry their derived resource, and url-routes-check / Go Tests pass on the current head. Codex reviewed the pre-fix commit bfe1634.

CI is green on 26f8841, Copilot approved, and the PR is mergeable (CLEAN). No threads open for a decision.

@jeremy
jeremy merged commit 5c1d07f into main Sep 16, 2026
53 checks passed
@jeremy
jeremy deleted the catalog-tag-untagged-ops branch September 16, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go python Pull requests that update the Python SDK ruby Pull requests that update the Ruby SDK spec Changes to the Smithy spec or OpenAPI typescript Pull requests that update TypeScript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants