Repository navigation
Description
Summary
Most card table write operations are registered at a path with no /buckets/{bucketId}/ segment, so the request goes to an endpoint that does not exist. cards move_card is the one I hit: it 404s outright, and there is no way to pass the bucket because it is not in the spec.
This is the same class of bug as #724 (todos update sent to /{account}/todos/{id} instead of /{account}/buckets/{project}/todos/{id}.json), which was fixed for todos but not for card tables.
Reads are unaffected, since BC3 answers card table GETs without the bucket. That is probably why this has gone unnoticed.
Steps to reproduce
Through basecamp mcp, with write access:
{"action": "move_card",
"params": {"cardId": 111111},
"body": {"column_id": 333333, "position": 1}}Result:
Resource not found: https://3.basecampapi.com/999999/card_tables/cards/111111/moves.json
Supplying the bucket explicitly is rejected, because the spec does not declare it:
unknown parameter "bucketId" for action "move_card"
get_card_table and list_cards against the same table both succeed, so the account, table, column and card ids are all valid.
Expected
POST https://3.basecampapi.com/999999/buckets/222222/card_tables/cards/111111/moves.json
Per the BC3 API docs, card table resources live under /buckets/{bucket}/.
Scope
In internal/mcpserver/model/openapi.json at v0.13.2, six card table write operations carry the bucket and thirteen do not.
Carry the bucket (correct):
SetCardColumnColor PUT /{accountId}/buckets/{bucketId}/card_tables/columns/{columnId}/color.json
EnableCardColumnOnHold POST /{accountId}/buckets/{bucketId}/card_tables/columns/{columnId}/on_hold.json
DisableCardColumnOnHold DELETE /{accountId}/buckets/{bucketId}/card_tables/columns/{columnId}/on_hold.json
CreateWormhole POST /{accountId}/buckets/{bucketId}/card_tables/{cardTableId}/wormholes.json
UpdateWormhole PUT /{accountId}/buckets/{bucketId}/card_tables/wormholes/{wormholeId}
DeleteWormhole DELETE /{accountId}/buckets/{bucketId}/card_tables/wormholes/{wormholeId}
Missing the bucket:
MoveCard POST /{accountId}/card_tables/cards/{cardId}/moves.json
MoveCardColumn POST /{accountId}/card_tables/{cardTableId}/moves.json
CreateCard POST /{accountId}/card_tables/lists/{columnId}/cards.json
CreateCardColumn POST /{accountId}/card_tables/{cardTableId}/columns.json
CreateCardStep POST /{accountId}/card_tables/cards/{cardId}/steps.json
RepositionCardStep POST /{accountId}/card_tables/cards/{cardId}/positions.json
SetCardStepCompletion PUT /{accountId}/card_tables/steps/{stepId}/completions.json
SubscribeToCardColumn POST /{accountId}/card_tables/lists/{columnId}/subscription.json
UnsubscribeFromCardColumn DELETE /{accountId}/card_tables/lists/{columnId}/subscription.json
UpdateCard PUT /{accountId}/card_tables/cards/{cardId}
UpdateCardColumn PUT /{accountId}/card_tables/columns/{columnId}
UpdateCardStep PUT /{accountId}/card_tables/steps/{stepId}
I only exercised MoveCard. The other twelve share the same shape, and the inconsistency inside one resource family is itself the tell.
Impact
There is currently no way to move a card between columns through the MCP. update_card cannot stand in, since its body is title / content / due_on / assignee_ids only. For an agent working a card table, moving a card is the main write.
One thing that is better here than in #724: this fails loudly with a 404 rather than returning 200 and silently discarding the body. But the fix looks like the same one.
Environment
- basecamp CLI 0.13.2, installed via
brew install --cask basecamp/tap/basecamp-cli - macOS (Darwin 27.0.0), arm64
- Driven through
basecamp mcp, BC3 account, authenticated via OAuth
(IDs anonymised: 999999 = account, 222222 = project, 333333 = column, 111111 = card.)
Activity