Skip to content

Commit 4ad0567

Browse files
docs(billing-cost-management-mcp-server): document Not in the sp-recommendation filter (#4920)
GetSavingsPlansPurchaseRecommendation accepts a Not expression around the LINKED_ACCOUNT Dimensions filter, which is how a caller excludes accounts from a recommendation. The filter arg doc said only that AND and OR are not supported, so a caller could not tell that Not works. - filter arg doc: a LINKED_ACCOUNT Dimensions expression, optionally wrapped in a single Not to exclude those accounts, with a one-line example; MatchOptions, if given, must be EQUALS; And, Or and a Not inside another Not are rejected. The parameter type is unchanged. The internal helper filter_expr doc says the same in short. - Test: the served filter description carries the Not wording, a parseable example, the MatchOptions rule and the rejected forms. Co-authored-by: Junaid Girkar <60307291+junaidgirkar@users.noreply.github.com>
1 parent 442c5c8 commit 4ad0567

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

‎src/billing-cost-management-mcp-server/awslabs/billing_cost_management_mcp_server/tools/sp_recommendation_tools.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@ async def sp_recommendation(
114114
LIGHT/MEDIUM/HEAVY_UTILIZATION values, which are Reserved Instance utilization levels and do not apply to Savings Plans.
115115
lookback_period_in_days: SEVEN_DAYS, THIRTY_DAYS, or SIXTY_DAYS. Required for get_savings_plans_purchase_recommendation.
116116
account_scope: PAYER or LINKED.
117-
filter: Filter recommendations by Account ID. Includes Dimensions only,
118-
with Key as LINKED_ACCOUNT and Value one or more Account IDs. AND and OR operators are
119-
not supported. Applies to get_savings_plans_purchase_recommendation only.
117+
filter: Filter recommendations by Account ID: a Dimensions expression with Key
118+
LINKED_ACCOUNT and Values one or more Account IDs, optionally wrapped in a single Not to
119+
exclude those accounts, for example
120+
{"Not": {"Dimensions": {"Key": "LINKED_ACCOUNT", "Values": ["111122223333"]}}}.
121+
MatchOptions, if given, must be EQUALS. And, Or, and a Not inside another Not are not
122+
supported. Applies to get_savings_plans_purchase_recommendation only.
120123
recommendation_detail_id: Required for get_savings_plan_purchase_recommendation_details. Comes from the RecommendationDetailId field of a recommendation.
121124
generation_status: SUCCEEDED, PROCESSING, or FAILED. Filters list_savings_plans_purchase_recommendation_generation.
122125
recommendation_ids: Recommendation IDs to filter to.
@@ -221,7 +224,8 @@ async def get_savings_plans_purchase_recommendation(
221224
recommendations including the management account and member accounts if the value is
222225
set to PAYER. If the value is LINKED, recommendations are calculated for individual
223226
member accounts only.
224-
filter_expr: Filter by Account ID with the LINKED_ACCOUNT dimension.
227+
filter_expr: Filter by Account ID with the LINKED_ACCOUNT dimension, optionally wrapped in a
228+
single Not to exclude those accounts.
225229
max_items: Total number of recommendation details to return. None fetches every page.
226230
next_token: The token from a previous response.
227231

‎src/billing-cost-management-mcp-server/tests/tools/test_sp_recommendation_tools.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
lowercase nextToken on the Savings Plans service.
2121
"""
2222

23+
import json
2324
import pytest
2425
from awslabs.billing_cost_management_mcp_server.tools.sp_recommendation_tools import (
2526
get_savings_plan_purchase_recommendation_details,
@@ -709,6 +710,21 @@ async def test_client_creation_failure_is_reported(self, mock_create_client, moc
709710
assert result['status'] == 'error'
710711

711712

713+
@pytest.mark.asyncio
714+
async def test_filter_doc_states_not_is_supported():
715+
"""The filter arg doc says Not is accepted around the LINKED_ACCOUNT dimension, with an example."""
716+
tool = await sp_recommendation_server.get_tool('sp-recommendation')
717+
assert tool is not None
718+
filter_doc = ' '.join(tool.parameters['properties']['filter'].get('description', '').split())
719+
assert 'optionally wrapped in a single Not to exclude those accounts' in filter_doc
720+
example = json.JSONDecoder().raw_decode(filter_doc, filter_doc.index('{"Not"'))[0]
721+
assert example == {
722+
'Not': {'Dimensions': {'Key': 'LINKED_ACCOUNT', 'Values': ['111122223333']}}
723+
}
724+
assert 'MatchOptions, if given, must be EQUALS' in filter_doc
725+
assert 'And, Or, and a Not inside another Not are not supported' in filter_doc
726+
727+
712728
def test_sp_recommendation_server_initialization():
713729
"""The server is named and carries instructions."""
714730
assert sp_recommendation_server.name == 'sp-recommendation-tools'

0 commit comments

Comments
 (0)