{
  "markdown": "<img src=\"docs/brand/logo.svg\" alt=\"cloud-tools\" height=\"72\">\n\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.munhq%2Fcloud--tools-000)](https://registry.modelcontextprotocol.io/v0/servers?search=cloud-tools)\n[![Smithery](https://img.shields.io/badge/Smithery-munhq%2Fcloud--tools-7c3aed)](https://smithery.ai/servers/munhq/cloud-tools)\n[![Glama](https://img.shields.io/badge/Glama-munhq%2Fcloud--tools-4f46e5)](https://glama.ai/mcp/servers/munhq/cloud-tools)\n\n[![Install in Cursor](https://img.shields.io/badge/Install-Cursor-000?logo=cursor)](cursor://anysphere.cursor-deeplink/mcp/install?name=cloud-tools&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBtdW5ocS9jbG91ZC10b29scyJdfQ==)\n[![Install in VS Code](https://img.shields.io/badge/Install-VS%20Code-007ACC?logo=visualstudiocode)](vscode:mcp/install?%7B%22name%22%3A%22cloud-tools%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40munhq%2Fcloud-tools%22%5D%7D)\n\nMulti-cloud cost, inventory and waste analysis in Rust — exposed as an **MCP server** so an AI agent can query spend and waste directly, and as an **HTTP API** for everything else.\n\nIt reports spend and waste: idle instances, oversized nodes, previous-generation hardware, unattached resources, and commitments you are not using.\n\n## Eight tools, one shape\n\nEvery tool takes `cloud` and nothing else it does not need. **Credentials never\nappear in a tool call** — the server reads them from its own environment, so the\nagent never handles a secret and never needs to be told one.\n\n```json\n{ \"cloud\": \"aws\" }\n{ \"cloud\": \"gcp\" }\n```\n\nStart with `check_access`. It takes no arguments, contacts no cloud, and reports\nwhich clouds this server can reach and what is missing for the ones it cannot.\n\n| Tool | AWS | GCP | Cloudflare | OVH |\n|---|:--:|:--:|:--:|:--:|\n| `check_access` | reports configuration for all four | | | |\n| `get_costs` | yes | needs a billing table | yes | yes |\n| `compare_costs` | yes | needs a billing table | — | — |\n| `get_inventory` | — | yes | yes | yes |\n| `get_waste` | yes | yes | — | — |\n| `get_commitments` | yes | yes | — | — |\n| `get_recommendations` | — | yes | — | — |\n| `get_cross_cloud_summary` | every cloud the server can reach | | | |\n\nA dash is not a silent empty result. The tool answers, for example,\n`waste analysis is not implemented for ovh; supported: aws, gcp`, so an agent\ncannot read a gap as a clean bill.\n\n### Reading a zero correctly\n\n`get_waste` and `get_inventory` return a `coverage` field and an `errors` list.\nA zero total means one of two entirely different things:\n\n| coverage | meaning |\n|---|---|\n| `complete` | Nothing is wasted. |\n| `PARTIAL — N API call(s) failed…` | **Part of the account could not be read.** |\n\nA partial result is not a clean bill of health.\n\n## Configuring the server\n\nCredentials are read from the environment of the machine running cloud-tools.\nNothing is stored, and every call is read-only.\n\n### AWS\n\nResolved in this order, first match winning:\n\n1. `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`\n2. `~/.aws/credentials`, profile from `AWS_PROFILE`, otherwise `[default]`\n3. An ECS task role\n4. An EC2 instance role\n\nAn SSO-only profile is not read directly. Export it first:\n`aws configure export-credentials --profile <name> --format env`.\n\nTo scan a *different* account, pass a role to assume. A role ARN is not a\nsecret, so it stays an argument:\n\n```json\n{ \"cloud\": \"aws\", \"target\": { \"role_arn\": \"arn:aws:iam::…:role/ReadOnly\" } }\n```\n\n`CLOUD_TOOLS_AWS_ROLE_ARN` and `CLOUD_TOOLS_AWS_EXTERNAL_ID` set a default for\nthat, if every call should assume the same role.\n\n`get_waste` reads EC2 instances, volumes, snapshots, AMIs, Elastic IPs, key\npairs and reserved instances; RDS; S3; Lambda; DynamoDB; ECS; ElastiCache; load\nbalancers; NAT gateways; CloudWatch log groups with no retention; and Compute\nOptimizer. Idle and oversized come from CloudWatch CPU series, so they are\nmeasured rather than guessed.\n\n### GCP\n\nApplication Default Credentials — `gcloud auth application-default login` is\nenough — or `GOOGLE_APPLICATION_CREDENTIALS` pointing at a service-account file.\n\n| Variable | Purpose |\n|---|---|\n| `CLOUD_TOOLS_GCP_PROJECTS` | Comma-separated project IDs to query |\n| `CLOUD_TOOLS_GCP_BILLING_TABLE` | BigQuery billing export, `project.dataset.table` |\n\nProjects can also be chosen per call with `target.project_ids`, which is how one\nagent scans several.\n\n`billing_table` matters. Google publishes no per-service spend API, so real\ncosts come from the BigQuery billing export. Without it, `get_costs` falls back\nto the Budgets API and labels the result `\"source\": \"budgets\"` with a note\nsaying these are budget amounts, not spend. `compare_costs` requires it outright.\n\n### Cloudflare\n\n```\nCLOUDFLARE_API_TOKEN     a token with read access to account resources\nCLOUDFLARE_ACCOUNT_ID\n```\n\n### OVH\n\n```\nOVH_APPLICATION_KEY\nOVH_APPLICATION_SECRET\nOVH_CONSUMER_KEY\nOVH_ENDPOINT             ovh-eu (default), ovh-us or ovh-ca\n```\n\n## Install\n\n> **Not released yet.** The newest tag is `v0.1.0`, which shipped `.tar.gz`\n> archives under the old asset names, and `@munhq/cloud-tools` is not on npm. The\n> three commands below start working the moment `v0.2.0` is tagged. Until then,\n> build from source: `cargo build --release`.\n\n\n### As an MCP server\n\n```bash\nclaude mcp add cloud-tools -- npx -y @munhq/cloud-tools\n```\n\nAnything that reads a JSON config — Claude Desktop, Cursor, Windsurf, Zed, Cline:\n\n```json\n{ \"mcpServers\": { \"cloud-tools\": { \"command\": \"npx\", \"args\": [\"-y\", \"@munhq/cloud-tools\"] } } }\n```\n\nThe npm package is a small wrapper, because the server is a compiled binary and\nnot JavaScript. On install it resolves the release asset for your platform,\nverifies it against the published `SHA256SUMS`, caches it under\n`~/.cache/cloud-tools/bin/` and executes it.\n\n### As a binary\n\nPrebuilt binaries for Linux, macOS and Windows, x86_64 and arm64, are attached to\neach [release](https://github.com/munhq/cloud-tools/releases). The script below\ndownloads the one for your machine and checks it against `SHA256SUMS`:\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/munhq/cloud-tools/main/install.sh | bash\n```\n\nOr take a single asset directly:\n\n```bash\ncurl -fsSLO https://github.com/munhq/cloud-tools/releases/latest/download/cloud-tools-x86_64-linux\nchmod +x cloud-tools-x86_64-linux\n```\n\n### As a container\n\n```bash\ndocker run -i --rm \\\n  -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_REGION \\\n  munhq/cloud-tools\n```\n\n## Running it\n\nBuilt as a library (`cloud_tools`) with an optional binary. Two feature flags, both on by default:\n\n- `mcp` — MCP server over stdio and streamable HTTP, via `rmcp`\n- `http` — HTTP API via axum\n\n```bash\ncargo build --release\n./target/release/cloud-tools            # MCP server on stdio\n```\n\nAs an MCP server it plugs into any MCP-capable agent. The agent calls the thirteen tools above directly and reasons over the results.\n\nTo embed it instead, depend on the library and turn the binary features off:\n\n```toml\ncloud-tools = { git = \"https://github.com/munhq/cloud-tools\", default-features = false }\n```\n\n## Status\n\nWorking and used against live AWS, GCP, Cloudflare and OVH accounts. Waste\nanalysis exists for AWS and GCP only — Cloudflare and OVH have none at all, not\nmerely fewer rules, and `get_waste` says so rather than returning an empty list.\nAWS has no inventory tool yet, though the listing calls behind one already exist.\nContributions adding provider coverage are welcome.\n\n## Privacy Policy\n\ncloud-tools collects nothing. There is no telemetry, no analytics and no\nphone-home of any kind — verified by the fact that the only hosts in the source\nare cloud provider APIs plus github.com, which the npm wrapper uses to download\nthe binary for your platform.\n\n**What is collected.** Nothing. No account, no sign-up, no identifier.\n\n**What is processed, and where.** Credentials you pass are used to sign requests\nto your own cloud provider and are held in memory for the life of that call. The\nserver runs on your machine, so nothing is sent to munhq or to any third party.\nThe responses go back to the MCP client that asked for them and nowhere else.\n\n**Storage and retention.** Nothing is written to disk and nothing is retained.\nThe one exception is the npm wrapper, which caches the downloaded binary under\n`~/.cache/cloud-tools/bin/` so it is not re-fetched on every run. That cache\nholds a program, never your data or your credentials.\n\n**Logging.** Diagnostics go to stderr, which your MCP client captures.\nCredentials are never logged. Error messages quote the provider's own response,\nwhich may name a project, an account id or a resource — the same information the\ntool was asked to report.\n\n**Third-party sharing.** None. The only network destinations are the cloud APIs\nof the providers whose credentials you supply:\nAWS (`*.amazonaws.com`), Google Cloud (`*.googleapis.com`), Cloudflare\n(`api.cloudflare.com`) and OVH (`*.api.ovh.com`, `api.us.ovhcloud.com`).\n\n**Permissions.** Read-only is sufficient for every tool. All seven declare\n`readOnlyHint: true`, and nothing in this server creates, modifies or deletes a\ncloud resource.\n\n**Contact.** hello@munhq.com. The canonical version of this policy is at\nhttps://munhq.com/privacy/cloud-tools.\n\n## Licence\n\nApache-2.0. See [LICENSE](LICENSE).\n",
  "bytes": 9339,
  "sha": "3f2d618c8459e0148b81ee06fee462e6b7bf8b6b698cf6d846092b022fb56d06",
  "repo_slug": "munhq/cloud-tools",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_munhq_cloud_tools_0d07f589/readme"
}