fix(mcp): default Savings Plans search params + region post-filter (avoid required-param cascade) #1506
Description
Problem
The cudly_search_recommendations MCP tool advertises payment_option, term_years, and lookback_period as optional filters ("omit to search all terms"). That is true for AWS EC2/RDS (GetReservationPurchaseRecommendation defaults them), but false for Savings Plans: AWS's GetSavingsPlansPurchaseRecommendation requires term, payment option, and lookback period.
Result observed in a live session: searching Savings Plans triggered a "20-questions" cascade — the tool failed forward one required param at a time (payment_option → term_years → lookback_period), and the client then brute-forced 1yr/3yr x no-upfront/all-upfront combinations. ~15 Cost Explorer calls (each ~$0.01) just to run one SP search, all returning 0 recs. EC2/RDS by contrast each worked in a single call.
Root cause: the schema presents a uniform "these are optional" contract that does not hold for the SP service, and the missing-param errors surface piecemeal from the downstream AWS API rather than all-at-once.
Fix
- Default the SP-required params when omitted, mirroring the CUDly CLI's own defaults:
payment_option=no-upfront,term=1yr,lookback_period=30d. A bare "search savings plans" then works in one call like EC2/RDS. Defaulting is appropriate here because search is read-only (no money) — the no-silent-fallback rule stays strict on the purchase tools, not read-only search. - Validate all SP-required params together and, if any are still missing after defaulting (shouldn't happen once defaulted, but as a safety net for other services), return a single error listing every missing field rather than one-per-call.
- Fix the misleading schema text: the
omit to search alldescriptions should note that term/payment/lookback are required for Savings Plans searches and default to 1yr/no-upfront/30d there.
Secondary (same PR)
- Region post-filter:
GetReservationPurchaseRecommendationis account-level and does not hard-filter by region, so aregion/include_regions/exclude_regionssupplied to the search is not actually honored (observed: aregion=us-east-1search surfaced an eu-west-1 rec). Post-filter the returned recommendations by the requested region set client-side so the param means what it says. (Investigate first; only add the filter if the region param is genuinely not honored today.)
Guardrails
- Read-only tool: defaults are fine and desirable here.
- Do NOT change the purchase tools' fail-loud behavior on money-affecting params.
- Keep enum/type validation; document the new defaults in the tool schema + mcp/README.md.
Related
- Surfaced while manually testing the MCP server (PR feat(mcp): CUDly MCP server for RI/SP/CUD purchases across AWS, Azure, GCP #1495) against a personal AWS account.
Activity
cristim commentedon Sep 2, 2026
Verified resolved at 3c0f8ac: cudly_search_recommendations now defaults payment_option/term_years/lookback_period to no-upfront/1yr/30d for AWS Savings Plans searches (caller-supplied values win), reports any still-missing required field in one error, documents the defaults in the tool schema and mcp/README.md, and post-filters results by region/include_regions/exclude_regions so the region argument is honoured. Evidence: mcp/tools/search_recommendations.go:363 and providers/aws/service_client.go:98 (PR #1495, commit 887d51f; PR #1507 was superseded and closed). Residual axes checked: purchase tools keep their fail-loud required-parameter behaviour; reservation searches still leave term/payment unset to return one result per option. Closing as completed; reopen if the behaviour recurs.