aws-cost-mcp
README.md
# aws-cost-mcp
> An MCP server that lets AI agents (Claude, Cursor, Copilot, any MCP client) answer questions about your AWS bill — with guardrails, caching and zero write access.
  
```
You: "Why did our AWS bill jump 40% last week?"
Agent → aws-cost-mcp.get_cost_breakdown(groupBy: SERVICE, granularity: DAILY)
Agent → aws-cost-mcp.get_anomalies(last: 14d)
Agent: "Most of the increase comes from NAT Gateway data transfer in us-east-1, starting Tuesday…"
```
---
## Why
Cost questions are some of the most common — and most painful — questions an engineering team asks. The answer lives in Cost Explorer, behind several clicks, filters and tag conventions that only one person on the team understands.
This project exposes AWS Cost Explorer as a **read-only, well-typed MCP server**, so that any agent can investigate spend, explain variations and suggest savings, using the same data a FinOps engineer would.
It was built from real experience migrating a campaign platform to AWS and driving its infrastructure cost down — the questions this server answers are the ones I had to answer by hand.
## Features
| Tool | What it does | AWS API |
| -------------------- | ------------------------------------------------------------------------- | --------------------------------- |
| `get_cost_breakdown` | Cost for a period, grouped by service, account, region, tag or usage type | `ce:GetCostAndUsage` |
| `compare_periods` | Diff between two periods, ranked by absolute and % change | `ce:GetCostAndUsage` |
| `get_forecast` | Forecast until end of month / custom date | `ce:GetCostForecast` |
| `get_anomalies` | Recent cost anomalies with root causes | `ce:GetAnomalies` |
| `get_rightsizing` | EC2 rightsizing recommendations with estimated savings | `ce:GetRightsizingRecommendation` |
| `list_tag_values` | Discover cost allocation tags so the agent can filter correctly | `ce:GetTags` |
**Resources**
- `aws-cost://summary/month-to-date` — compact markdown summary the agent can load as context.
**Prompts**
- `investigate-cost-spike` — guided workflow: compare → break down → check anomalies → explain.
- `monthly-finops-report` — produces a report for leadership.
### Design principles
- **Read-only by construction.** The server only calls `ce:Get*` APIs. A minimal IAM policy is provided below.
- **Cheap to run.** Cost Explorer charges per API request, so every response is cached (in-memory LRU, configurable TTL) and requests are deduplicated.
- **Agent-friendly output.** Responses are compact, sorted and truncated (top-N + "others") to save context tokens. Raw JSON is available with `format: "json"`.
- **Strict input validation.** All tool inputs are validated with Zod; invalid ranges and granularities return actionable errors the agent can fix itself.
## Quick start
### 1. Requirements
- Node.js ≥ 20
- AWS credentials with the policy below (profile, SSO or env vars)
- Cost Explorer enabled in the account
### 2. Use with Claude Desktop / Claude Code / Cursor
```json
{
"mcpServers": {
"aws-cost": {
"command": "npx",
"args": ["-y", "aws-cost-mcp"],
"env": {
"AWS_PROFILE": "my-readonly-profile",
"AWS_COST_MCP_CACHE_TTL": "900"
}
}
}
}
```
### 3. Run locally (development)
```bash
git clone https://github.com/VictorCarvalho16/aws-cost-mcp
cd aws-cost-mcp
npm install
npm run dev # stdio server with hot reload
npm run inspector # opens the MCP Inspector against the local server
```
## Minimal IAM policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ce:GetCostAndUsage",
"ce:GetCostForecast",
"ce:GetAnomalies",
"ce:GetRightsizingRecommendation",
"ce:GetTags"
],
"Resource": "*"
}
]
}
```
## Configuration
| Variable | Default | Description |
| ---------------------------- | ----------------- | ------------------------------------------------------ |
| `AWS_PROFILE` / `AWS_REGION` | SDK default chain | Standard AWS credentials |
| `AWS_COST_MCP_CACHE_TTL` | `900` | Cache TTL in seconds |
| `AWS_COST_MCP_MAX_ROWS` | `15` | Max rows returned before grouping into "others" |
| `AWS_COST_MCP_CURRENCY` | `USD` | Display currency |
| `AWS_COST_MCP_LOG_LEVEL` | `info` | `debug` logs every AWS call (to stderr — never stdout) |
## Architecture
```
┌──────────────┐ stdio / Streamable HTTP ┌──────────────────────────────┐
│ MCP client │ ────────────────────────▶ │ aws-cost-mcp │
│ (Claude etc.)│ │ ├─ tools/ (Zod schemas) │
└──────────────┘ │ ├─ services/costExplorer.ts │
│ ├─ cache/ (LRU + dedupe) │
│ └─ format/ (md tables) │
└──────────────┬───────────────┘
│ AWS SDK v3
▼
AWS Cost Explorer API
```
```
src/
├── index.ts # entrypoint, transport selection
├── server.ts # McpServer registration (tools, resources, prompts)
├── tools/ # one file per tool: schema + handler
├── services/
│ └── cost-explorer.ts # thin typed wrapper over @aws-sdk/client-cost-explorer
├── cache/
├── format/ # markdown/JSON formatters, top-N truncation
└── config.ts
test/
├── unit/ # handlers with mocked SDK (aws-sdk-client-mock)
└── e2e/ # spawns the server and talks MCP over stdio
```
**Stack:** TypeScript · `@modelcontextprotocol/sdk` · AWS SDK v3 · Zod · Vitest · tsup · GitHub Actions
## Testing
```bash
npm test # unit tests (no AWS needed — SDK is mocked)
npm run test:e2e # starts the server and runs real MCP requests against fixtures
npm run lint && npm run typecheck
```
## Roadmap
### v0.1 — MVP
- [ ] Project scaffold (TypeScript, tsup, Vitest, ESLint, Prettier)
- [ ] `get_cost_breakdown` with Zod validation
- [ ] Markdown formatter with top-N truncation
- [ ] Unit tests with `aws-sdk-client-mock`
- [ ] CI on GitHub Actions (lint, typecheck, test)
### v0.2 — Useful
- [ ] `compare_periods`, `get_forecast`, `list_tag_values`
- [ ] LRU cache + request dedupe
- [ ] `investigate-cost-spike` prompt
- [ ] Publish to npm, add to the MCP Registry
### v0.3 — Production-grade
- [ ] `get_anomalies`, `get_rightsizing`
- [ ] Streamable HTTP transport (for remote/shared deployments)
- [ ] E2E tests over stdio
- [ ] Demo GIF in this README
- [ ] Blog post: "Giving an AI agent read-only access to your AWS bill"
### Ideas
- Multi-account (Organizations) support
- Savings Plans / RI coverage tools
- Export a report as CSV resource
## Security
- Never request write permissions — the server has no code path that mutates AWS resources.
- Logs go to **stderr** only (stdout is reserved for the MCP protocol).
- Credentials are resolved by the AWS SDK default chain and never logged or returned to the client.
Found a vulnerability? Please open a private security advisory instead of an issue.
## Contributing
Issues and PRs are welcome. Run `npm test` before opening a PR and follow Conventional Commits.
## License
MIT © Victor Hugo Araújo de Carvalho
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues