feat(billing-cost-management-mcp-server): add AWS Enterprise Support tool and operations - #4481
feat(billing-cost-management-mcp-server): add AWS Enterprise Support tool and operations#4481frankolas wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4481 +/- ##
========================================
Coverage 93.14% 93.15%
========================================
Files 1038 1040 +2
Lines 87536 87656 +120
Branches 14123 14140 +17
========================================
+ Hits 81535 81655 +120
Misses 3638 3638
Partials 2363 2363 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
b0c058f to
4bb9484
Compare
4bb9484 to
cc78456
Compare
| # Oldest billing month with Enterprise Support data. Requests earlier than this | ||
| # are rejected locally rather than spending a call that cannot return data. | ||
| EARLIEST_BILLING_MONTH = '2025-01' |
| try: | ||
| client = _create_billing_client() | ||
| request_params = _build_linked_account_charges_request( | ||
| str(billing_month), account_id, max_results, next_token |
There was a problem hiding this comment.
Do we need to cast to str if we run _validate_billing_month(billing_month)
| Both are routinely misread. ``AccessDeniedException`` is raised when the IAM | ||
| policy omits the action AND when the caller is not the payer account | ||
| authorized for the Support profile, so it must not be reported as an absence |
There was a problem hiding this comment.
AND? IAM Policy of caller's role could contain the correct actions, but client could still throw AccessDeniedError if caller is not the payer account authorized for Support profile.
| ) | ||
|
|
||
|
|
||
| def _validate_billing_month(billing_month: Optional[str]) -> Optional[Dict[str, Any]]: |
There was a problem hiding this comment.
We should validate billing_month passed is in YYYY-MM format because LLM can pass in a string without the zero padding for month, which might be dangerous for comparison operations in this python file. They assume YYYY-MM for comparison operation and these happen before any server side validation. We can do it in this file.. which will be easier and safer lift. (Another unsafe alternative could be to add client-side validation which can be overriden).
Notes
Adds an
enterprise_supporttool with three operations,get_charge_summary,get_contract_detailsandlist_linked_account_charges, covering a billing period's Enterprise Support charge and the Support-eligible spend it was calculated from, the contract terms that govern how the charge is allocated, and the per-linked-account breakdown.account_idonlist_linked_account_chargesis a linked-account filter rather than the caller, so it is never resolved from credentials and is omitted from the request when the caller omits it. Defaulting it would silently reduce an organization-wide breakdown to a single row.list_linked_account_chargesuses the sharedpaginate_aws_responsehelper rather than a local paginator, and large breakdowns offload to the session SQL tool throughconvert_response_if_needed.Response field names pass through as returned, with only timestamps normalized.
AccessDeniedException and ResourceNotFoundException are classified with their own guidance because both are routinely misread in opposite directions; every other error falls through to the shared handler.
Testing
uv sync --frozen --all-extras --dev: cleanruff check .andruff format --check .: passpyright: 0 errorspytest --cov --cov-branch --cov-report=term-missing: full suite passes, 52 new tests, 99% statement coverage on the new operations module and 100% on the new tool moduleKiro-cli Testing
Identifiers and monetary amounts are redacted below. Field names, response shapes and model behaviour are unmodified.
An account or period with no Enterprise Support data, showing the not-found classification rather than a denial:
Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.