内容
# finops-mcp
MCP服务器,用于自动优化AWS成本。它摄取AWS Compute Optimizer的过度配置建议(EKS节点组、RDS实例、ECS服务、Lambda函数)以及Kubernetes pod/HPA调整建议,将它们映射到本地的Terraform/OpenTofu代码库或Helm values.yaml文件中,应用最小的安全调整补丁,在本地验证,并草拟具有结构化PR正文的Git分支。它还可以检测EC2/RDS上的重复空闲窗口,并草拟启动/停止计划——如果不存在调度器基础设施,则生成调度器基础设施。
**它从不直接对云环境应用更改。** 所有输出都是本地分支的代码更改,供人类审查。
支持的资源类型:`eks_nodegroup`、`rds_instance`、`ecs_service`、`lambda_function`、`k8s_workload`(pod请求/限制 + HPA副本数,通过Helm values.yaml;VPA/Goldilocks/Kubecost JSON导出的建议通过`FINOPS_K8S_RECS_FILE`),以及EC2/RDS实例调度。
## 工作原理
```
AWS Compute Optimizer ──▶ 1.遥测数据摄入(过滤重要的、安全建议)
(+ K8s建议导出, 2. 代码库映射 (在*.tf / *.tfvars /
+ CloudWatch时间) values.yaml中找到资源,跟踪变量间接)
3. 安全补丁 (最小差异,仅允许列出的属性)
4. 本地验证 (terraform validate/plan或HCL/YAML lint,
加上差异范围漂移防护)
5. PR草拟 (隔离的finops/*分支 + 结构化PR正文)
```
## 工具
| 工具 | 功能 |
|---|---|
| `get_cost_recommendations` | 从Compute Optimizer获取过度配置建议(无凭证时备用模拟) |
| `map_resource_to_code` | 在本地IaC中找到推荐资源的声明,跟踪`var.x`到tfvars或变量默认值;K8s工作负载的values.yaml |
| `draft_optimization` | 补丁一个建议,验证,生成PR正文,创建`finops/*`分支 |
| `run_finops_cycle` | 遍历所有建议的完整循环;`mode="interactive"`或`mode="scheduled"`(写入`finops_run_log.json`) |
| `verify_repository` | 独立的lint / `terraform validate` / 差异范围检查仓库 |
| `analyze_usage_windows` | 从CloudWatch每周小时配置文件中检测EC2/RDS上的重复空闲窗口,并建议启动/停止计划 |
| `draft_schedule` | 为一个计划建议更新Terraform中的`Schedule`标签(可选用户首选`schedule_override`),验证,草拟PR分支 |
| `draft_scheduler_bootstrap` | 在未检测到账户中的调度器时,生成标签驱动的调度器本身(Lambda + EventBridge + IAM + 计划定义)为新的Terraform文件在`finops/bootstrap-*`分支 |
## 安装
```bash
git clone https://github.com/jorosenberg/finops-mcp
cd finops-mcp
pip install -e .
```
## 使用MCP客户端注册
Claude Desktop(`claude_desktop_config.json`)或任何MCP兼容客户端:
```json
{
"mcpServers": {
"finops-optimizer": {
"command": "python",
"args": ["-m", "finops_mcp.server"],
"cwd": "<path-to>/finops-mcp",
"env": {
"FINOPS_REPO_PATH": "<path-to-your-terraform-repo>",
"FINOPS_MODE": "auto",
"AWS_REGION": "us-east-1"
}
}
}
}
```
Claude Code: `claude mcp add finops-optimizer -- python -m finops_mcp.server`
## 配置
| 环境变量 | 含义 | 默认值 |
|---|---|---|
| `FINOPS_MODE` | `auto`(真实AWS如果凭证有效,否则模拟),`aws`,或`mock` | `auto` |
| `FINOPS_REPO_PATH` | 工具省略`repo_path`时的默认Terraform仓库 | 当前工作目录 |
| `FINOPS_MIN_MONTHLY_SAVINGS` | 美元中的显著性阈值 | `20` |
| `FINOPS_K8S_RECS_FILE` | K8s工作负载建议(VPA/Goldilocks/Kubecost)的可选JSON导出 | — |
| `FINOPS_MIN_IDLE_HOURS_WEEK` | 建议计划的最小重复空闲时间 | `40` |
| `FINOPS_IDLE_CONFIDENCE` | 小时必须空闲的分数才能计为空闲 | `0.9` |
| `FINOPS_EC2_IDLE_CPU` | CPU % 以下的EC2小时计为空闲 | `3.0` |
| `AWS_REGION` | 查询建议的区域 | `us-east-1` |
| `FINOPS_PUSH` | 调度器仅:`true`将分支推送到源 | `false` |
### AWS前提条件
- 可通过boto3解析的凭证(`aws configure`,SSO或环境变量)用于具有`compute-optimizer:Get*`(加`cloudwatch:GetMetricData`,`ec2:DescribeInstances`,`rds:DescribeDBInstances`用于使用窗口分析)的身份 - 避免根凭证
- [Compute Optimizer已在账户中启用](https://docs.aws.amazon.com/compute-optimizer/latest/ug/getting-started.html);首次发现可能需要长达24小时才能出现,并需要足够的CloudWatch历史记录
- 无工作凭证时,服务器提供确定性模拟数据,并在`aws_fallback_reason`中报告原因
## 安全保证
- 仅允许列出的调整属性才会被修补 - Terraform:`instance_type(s)`,`instance_class`,`min/max/desired_size`,`allocated_storage`,`cpu`,`memory`,`memory_size`,`desired_count`,`Schedule`标签;YAML:`cpu`,`memory`,`minReplicas`,`maxReplicas`,`replicas`,`replicaCount`
- 包含机密的线路(密码/令牌/密钥),VPC/子网/安全组块和`backend`状态配置永远不会被修改 - 在修补时强制执行,并在`git diff`上重新检查
- 外部管理生命周期资源(例如Karpenter节点池,ASG成员)被检测并跳过
- 验证失败会自动回滚工作树(生成的引导文件在失败时被删除)
- 每个建议都有自己的隔离`finops/rightsize-*`,`finops/schedule-*`或`finops/bootstrap-*`分支;除非明确请求,否则不会推送任何内容
- 引导程序生成拒绝覆盖不看起来是finops生成的现有文件
## 实例调度(使用时间)
`analyze_usage_windows`从每小时CloudWatch指标(EC2 `CPUUtilization`,RDS `DatabaseConnections`)中提取,折叠成一个168槽的每周小时配置文件,并建议具有重复空闲窗口的资源的启动/停止计划(如果一个小时在≥90%的观察周内为空闲,则该小时计为空闲,可通过`FINOPS_IDLE_CONFIDENCE`调整;最小重复空闲时间`FINOPS_MIN_IDLE_HOURS_WEEK`,默认为40小时/周)。
`draft_schedule`强制执行计划GitOps风格:它将`Schedule = "<window>"`标签插入资源的Terraform `tags`映射中 - 与[AWS Instance Scheduler](https://aws.amazon.com/solutions/implementations/instance-scheduler-on-aws/)和其他标签驱动的调度器兼容。
更喜欢不同于遥测派生的窗口?将`schedule_override`传递给`draft_schedule`(格式:`mon-fri-HH-HH`,`daily-HH-HH`,`sat-sun-HH-HH`)。
**账户中尚无调度器?** `draft_schedule`检测到这一点(对调度器Lambda / EventBridge规则/ Instance Scheduler堆栈的只读探测)并在输出中警告。`draft_scheduler_bootstrap`然后生成一个完整的轻量级调度器作为新的Terraform文件在您的仓库中 - `finops-scheduler.tf`(Lambda + EventBridge 15分钟规则+ IAM +计划定义的`locals`映射,时区感知)和`finops_scheduler_lambda.py`(〜75行可审查的Lambda源) - 在`finops/bootstrap-*`分支上。您审查并应用`terraform apply`;MCP永远不会部署任何内容。
调度安全排除项:ASG中的EC2实例,RDS Multi-AZ/ read replicas / Aurora成员,标记为`Environment=prod/production`的资源,以及已携带`Schedule`标签的资源。节省估计仅为计算(EBS/RDS存储在停止时仍计费),来自近似的按需价格表。
## 调度运行(触发器B)
`finops_scheduler.py`每周五15:00无头运行完整循环,并记录到`finops_pipeline.log` + `finops_run_log.json`:
```bash
pip install schedule
FINOPS_REPO_PATH=/path/to/repo python finops_scheduler.py
# 设置FINOPS_RUN_NOW=true立即触发测试
```
## 无AWS试用
`sample-infra/`是一个演示仓库(EKS节点组,RDS实例,ECS服务,Lambda函数,EC2实例和K8s工作负载的Helm图表 - 具有tfvars间接,保护的网络块和敏感行),它与内置模拟建议匹配:
```bash
cd sample-infra && git init -b main && git add -A && git commit -m initial && cd ..
FINOPS_MODE=mock python -c "from finops_mcp import server; print(server.run_finops_cycle(repo_path='sample-infra'))"
FINOPS_MODE=mock python -c "from finops_mcp import server; print(server.draft_schedule('rec-sched-ec2-dev-runner', repo_path='sample-infra'))"
FINOPS_MODE=mock python -c "from finops_mcp import server; print(server.draft_scheduler_bootstrap(repo_path='sample-infra', timezone='America/New_York'))"
```
预期结果:五个调整分支(EKS,RDS,ECS,Lambda,K8s),`finops/schedule-*`分支将`Schedule`标签添加到dev-runner和staging-db,以及包含生成的调度器的`finops/bootstrap-*`分支 - 每个都有一个PR正文在`.finops/`下。
## 示例PR正文
```markdown
# chore(finops): 调整orders-db(rds_instance)以优化成本
- **目标资源:** orders-db(arn:aws:rds:...)
- **当前配置:** instance_class=db.r5.2xlarge
- **优化配置:** instance_class=db.r5.xlarge
- **预计节省:** $487.20/月(〜$5,846.40/年)
- **理由:** Compute Optimizer发现过度配置 - cpu p95 = 11.2%;
连接p95 = 42,历时14天的观察期。
```
## 许可证
MIT