MCP: option-level `ranking` must be independent of `property_rankings`

Seen in 1 project by 1 person

About

Bug

Test 1 (option 01118eef-fc2d-4573-94b8-7c4d820f04ad, definition task) returns ranking: 0 and property_rankings: {} via the MCP. Verified 2026-05-25 against MCP server 1.12.0.

The property_rankings: {} is correct per the 2026-05-24 changelog entry — task and general have no rankable properties, so the per-property map is empty by design.

But ranking: 0 is wrong as a default. The option-level ranking is a first-class user-facing column (numeric, settable directly via update_option.ranking per the schema, completely independent of any per-property reaction aggregate). It should reflect the actual stored value on the option (which may be null if never set, or any number if set) regardless of whether the definition has rankable properties.

What the user expects

  • ranking = the option's overall ranking, sourced from the option row itself. Independent of property reactions.
  • property_rankings = the aggregate of weighted reactions per rankable property. Returns {} for definitions like task / general that have no rankable properties — that part is already correct.

These two values are independent. Today, for task options, the MCP appears to be conflating them: ranking reads as 0 rather than reflecting either (a) a real user-set value or (b) null for never-set.

Repro

get_option({ optionId: '01118eef-fc2d-4573-94b8-7c4d820f04ad' })
→ ranking: 0, property_rankings: {}

Compare against an option of a rankable definition (e.g. flight, lodging) where ranking correctly reflects either the stored option-level value or aggregated property reactions.

Confirming evidence (2026-05-25)

While creating this very bug-report task via create_option, the response payload came back with "ranking": null — the exact correct shape the existing Test 1 option should return instead of 0. This means the conflation is happening on the read path, not on the write pathcreate_option correctly stores null for a never-set ranking, but get_option / list_options later surface it as 0. Useful clue for narrowing the fix: focus on the SELECT / response-shaping logic in the read tools.

Likely root cause

The MCP read tools (get_option, list_options) probably compute ranking from property_rankings for definitions with rankable properties, and fall back to 0 (instead of the option row's actual stored ranking column, or null) for non-rankable definitions like task. Should always read the option's own ranking column first, and only fall back to a property-aggregate computation if the column is null and the definition is rankable.

Acceptance

  • get_option and list_options return ranking as either the actual stored value on the option, or null if never set — never 0 as a synthesized default.
  • property_rankings continues to return {} for task / general (unchanged from the 2026-05-24 behaviour).
  • The two fields are documented as independent in the tool descriptions.
  • Test: setting update_option({ optionId, ranking: 5 }) on a task option, then get_option, should return ranking: 5 (not 0).
  • Test: never-set ranking on a task option should return null (not 0).
  • Test: create_option already returns the correct null shape — verify the same option then read back via get_option returns matching null (not 0).

Links

No links shared yet.

Listed in

Bookmarked in

Not in any public bookmark categories yet.