Content
# CloudGo.ai MCP – Multicloud Read‑Only Inventory Server
<div align="center">
<img src="testLogo.png" alt="CloudGo AI MCP Logo" width="256" height="256">
**Multicloud inventory and usage tracking for AWS, GCP, and Azure**
[](https://www.python.org/downloads/)
[](https://modelcontextprotocol.io)
[](https://docs.pytest.org/)
</div>
**CloudGo.ai MCP** is a minimal, stdio‑based Model Context Protocol (MCP) server that exposes
read‑only multicloud inventory tools for **AWS**, **GCP**, and **Azure**.
## Why use it?
- Inspect AWS, GCP, and Azure resources through one MCP interface
- Keep access read-only for safer cloud discovery and audit workflows
- Search inventory, summarize resources, and jump directly to console URLs
- Optionally run guarded cloud CLI commands with explicit allowlists
## Common workflows
- “What clouds are connected?”
- “Summarize all compute resources across clouds”
- “Find production resources in us-west-2”
- “Open this resource in the cloud console”
---
<p align="center">
<img src="docs/demo.gif" alt="CloudGo AI MCP demo" width="900" />
</p>
## Quick start
From the project root:
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
cp config.example.yaml config.yaml
python -m cloudgo_ai_mcp.server
```
To run tests: `pip install -e ".[dev]"` then `pytest`.
If `config.yaml` is missing when you run the server, it is created automatically from `config.example.yaml` (all clouds disabled). Set `CLOUDGO_AI_MCP_CONFIG` (or legacy `CLOUDGO_MCP_CONFIG`) to use a config file elsewhere. With all clouds disabled, the server still starts and tools return empty or safe results so you can confirm the MCP server runs before adding credentials.
---
## Features
- **Multicloud Support**: Single interface for AWS, GCP, and Azure resources
- **Read-Only**: Designed for inventory collection, not resource modification
- **Normalized Data Model**: Unified resource representation across all clouds
- **Usage Tracking**: Metrics, activity logs, and optimization recommendations
- **Smart Caching**: TTL-based inventory caching for performance
- **Console Deep Links**: `get_console_url` returns direct links to open resources in AWS/GCP/Azure consoles
- **Optional CLI**: Safe `run_cli_command` for `aws`/`gcloud`/`az` with allowlist, denylist, and output limits
- **Prompts**: Built-in MCP prompts for inventory briefs, usage review, safe CLI assistance, and more
- **MCP-Native**: Runs as stdio server, ideal for Claude Desktop or other MCP hosts
---
### Data Flow
1. **Collection**: Collectors fetch resources from cloud APIs and normalize them
2. **Storage**: Normalized resources are cached in InventoryStore (TTL: 300s)
3. **Query**: Tools query the store to provide filtered, paginated, and searchable access
4. **Usage**: Usage collectors fetch real-time metrics and activity logs on demand
---
## Security and Scope
- **READ‑ONLY ONLY**: This server is designed **solely** for read‑only, inventory‑style access
(e.g., `Describe*`, `List*` APIs). **Do not** grant credentials that can create, modify,
or delete cloud resources.
- **No secrets management**: This project does **not** manage or rotate credentials for you;
it simply uses credentials you provide via environment variables / config.
- **Your responsibility**: You are responsible for:
- Scoping IAM roles / service accounts to the minimum read‑only permissions you need.
- Keeping any config files and credential material out of version control.
- **Non-mutating permission audit**: `check_permissions` only performs read tests and metadata inspection. It does not attempt cloud write APIs as part of verification.
See [SECURITY.md](SECURITY.md) for detailed security information and [docs/credentials.md](docs/credentials.md) for credential setup guidance.
---
## Installation
From the project root:
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```
This installs the package in editable mode with all required dependencies.
---
## Configuration
Use `config.example.yaml` as a starting point:
```bash
cp config.example.yaml config.yaml
```
Fill in values directly or export environment variables referenced in the file
(`AWS_ACCESS_KEY_ID`, `GOOGLE_APPLICATION_CREDENTIALS`, `AZURE_CLIENT_ID`, etc.).
`${ENV_VAR}` placeholders in the YAML are automatically expanded at runtime.
The example file ships with all cloud providers disabled so first boot is safe by default; enable only the providers you intend to use.
By default, the server looks for `config.yaml` in the working directory. You can
override this with the `CLOUDGO_AI_MCP_CONFIG` environment variable (or legacy `CLOUDGO_MCP_CONFIG`).
### CLI (optional)
The `run_cli_command` tool is **disabled by default**. To enable it, set in `config.yaml`:
```yaml
cli:
enabled: true
allowed_binaries: ["aws", "gcloud", "az"]
output_limit_bytes: 65536
# Optional: restrict subcommands, e.g. ["ec2", "s3"] for AWS
# allowed_subcommand_prefixes: ["ec2", "s3"]
```
Risky commands (e.g. `ssh`, `tunnel`, `interactive`) are blocked by a built-in denylist. See [Security](#security-and-scope) and [SECURITY.md](SECURITY.md).
### Credential Setup
For detailed guidance on setting up secure, least-privilege credentials, see:
- **[docs/credentials.md](docs/credentials.md)** - Comprehensive guide on:
- Recommended IAM roles and least-privilege policies
- Using short-lived credentials (STS, Workload Identity, Managed Identity)
- Scoping access to specific regions, projects, or subscriptions
---
## Running the Server
### Locally
```bash
export CLOUDGO_AI_MCP_CONFIG=/absolute/path/to/config.yaml
python -m cloudgo_ai_mcp.server
```
The server uses **stdio** for transport, as expected by MCP‑compatible hosts.
### With Claude Desktop
In your Claude Desktop MCP configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS), add:
```json
{
"mcpServers": {
"cloudgo-ai-mcp": {
"command": "python",
"args": ["-m", "cloudgo_ai_mcp.server"],
"env": {
"CLOUDGO_AI_MCP_CONFIG": "/ABSOLUTE/PATH/config.yaml"
}
}
}
}
```
Adjust the path to `config.yaml` for your environment.
---
## Tools
### Inventory Tools
- **`health`**: Returns startup credential validation results
- **`list_clouds`**: Returns list of enabled clouds from config
- **`cloud_identities`**: Returns caller identity per provider (account, ARN, project, service account email, etc.)
- **`cloud_scopes`**: Discovers available scope (AWS regions, GCP projects, Azure subscriptions)
- **`check_permissions`**: Runs non-mutating read tests and metadata inspection to assess effective access without cloud write probes
- **`inventory_summary`**: Returns summary of inventory with counts by type and cloud
- **`refresh_inventory`**: Force-refresh one cloud or all enabled clouds
- **`list_resources`**: List resources with filtering by type, cloud, and region (supports pagination)
- **`get_resource`**: Get a specific resource by its unified_id
- **`get_console_url`**: Get a canonical console deep link and navigation hints for a resource (AWS/GCP/Azure)
- **`search_resources`**: Search resources by query string with scoring
- **`export_inventory_bundle`**: Export inventory as JSON, Markdown, or concise text format
### Usage Tools
- **`get_resource_usage`**: Get usage data for a resource including:
- CloudWatch/Cloud Monitoring/Azure Monitor metrics
- Activity logs (CloudTrail/Audit Logs/Activity Log)
- Optimization recommendations (Compute Optimizer/Recommender/Advisor)
### CLI tool (optional)
- **`run_cli_command`**: Run a cloud CLI command (`aws`, `gcloud`, `az`) with security guardrails. Requires `cli.enabled: true` in config. Uses an allowlist of binaries, a denylist for interactive/SSH/tunnel commands, and strict output limits. Pass argv as a list (e.g. `["aws", "ec2", "describe-instances", "--region", "us-east-1"]`).
### Prompts
Pre-built prompts guide the agent through common workflows (parameters are injected when the prompt is used):
| Prompt | Description |
|--------|-------------|
| **inventory_brief** | Summarize multicloud inventory (optional deep dive by type). |
| **cost_usage_review** | Review usage over N days and include optimization recommendations. |
| **safe_cli_assist** | Generate and validate a safe CLI command for a given intent and cloud. |
| **jump_to_console** | Find a resource by query and return a direct console URL. |
| **permission_audit** | Audit which clouds are connected and what permissions credentials have. |
| **export_for_audit** | Export inventory for compliance (JSON, Markdown, or concise text format). |
| **whats_in_region** | List and summarize resources in a specific cloud region or project. |
| **compare_clouds** | Compare inventory counts and types across AWS, GCP, and Azure. |
### Example Usage
```python
# Get inventory summary
summary = await inventory_summary()
# Returns: {"generated_at": ..., "counts": {"total": 150, "by_cloud": {...}, "by_type": {...}}}
# List EC2 instances
instances = await list_resources(resource_type="ec2:instance", cloud="aws", limit=50)
# Search for resources
results = await search_resources(query="production", cloud="aws", limit=25)
# Get usage metrics for a resource
usage = await get_resource_usage(
unified_id="aws:ec2:instance:us-west-2:123456789012:i-0abc123",
days=7,
include_recommendations=True
)
# Get a direct console link for a resource (after get_resource or search_resources)
console = await get_console_url(unified_id="aws:ec2:instance:us-east-1:123456789012:i-0abc123")
# Returns: url, hints, resource_type, region, cloud
# Run a safe CLI command (requires cli.enabled: true in config)
result = await run_cli_command(["aws", "ec2", "describe-instances", "--region", "us-east-1", "--max-items", "5"])
```
---
## Project Layout
```text
cloudgo-ai-mcp/
cloudgo_ai_mcp/
__init__.py
config.py # Configuration loading (server, aws, gcp, azure, cli)
server.py # MCP server, tools, prompts, CLI guardrails
models.py # Normalized resource models, unified ID
store.py # Inventory caching
console_urls.py # Console deep links (AWS/GCP/Azure)
collectors.py # AWS/GCP/Azure collectors
usage_collectors.py # Usage metrics collectors
tests/
test_config.py # Safe defaults in config.example.yaml and load_config
test_models.py # generate_unified_id, ResourceRef, NormalizedResource
test_store.py # build_counts, InventoryStore
test_console_urls.py # get_console_url
test_server_cli.py # CLI allowlist/denylist, redaction
test_server_guidance.py # FastMCP instructions, prompts, and export format routing
docs/
credentials.md # Credential setup guide
config.example.yaml # Configuration template
config.yaml # Your configuration (not in git)
pyproject.toml # Package and pytest/ruff config
README.md
SECURITY.md
LICENSE
CHANGELOG.md
```
---
## Resource Types
Resource types are provider-native and parser-derived in lowercase `service:kind` form (no hardcoded cross-cloud normalization).
Examples:
- AWS: `ec2:instance`, `s3:bucket`, `lambda:function`
- GCP: `compute:instance`, `storage:bucket`, `pubsub:topic`
- Azure: `compute:virtualmachines`, `storage:storageaccounts`, `network:virtualnetworks`
---
## Unified IDs
Resources are identified by deterministic unified IDs:
- **AWS**: `aws:ec2:instance:us-west-2:123456789012:i-0abc123`
- **GCP**: `gcp:compute:instance:us-central1:myproject:instance-1`
- **Azure**: `azure:compute:virtualmachines:westus:subId:/subscriptions/.../virtualMachines/vm1`
Format: `{cloud}:{type}:{region}:{account_or_project}:{native_id}`
---
## Caching
Inventory data is cached per cloud in-memory (default TTL: 300 seconds). This means:
- First call to `inventory_summary` or `list_resources` triggers collection
- Subsequent calls within TTL use cached data for fresh clouds
- Stale clouds refresh independently
- `refresh_inventory` can force-refresh one cloud or all clouds
Usage data (`get_resource_usage`) is always fetched fresh (not cached).
---
## Development
### Running Tests
Tests use pytest and require no cloud credentials or network (all tests are unit tests with in-memory data).
```bash
pip install -e ".[dev]"
pytest
# Or: pytest tests/ -v
```
| Test module | Coverage |
|-------------|----------|
| `test_config.py` | Safe config defaults and `config.example.yaml` release defaults |
| `test_models.py` | `generate_unified_id` (AWS/GCP/Azure), `InventoryCounts`, `ResourceRef`, `NormalizedResource` |
| `test_store.py` | `build_counts`, `InventoryStore` (set/get/delete/merge) |
| `test_console_urls.py` | `get_console_url` for EC2, S3, GCP compute, Azure resource |
| `test_server_cli.py` | CLI allowlist/denylist (`_cli_argv_rejected`), output redaction (`_redact_output`) |
| `test_server_guidance.py` | FastMCP instructions, prompt workflow guidance, and `export_inventory_bundle` markdown aliasing |
Pytest is configured in `pyproject.toml` (`testpaths = ["tests"]`, `asyncio_mode = "auto"`).
### Linting and formatting (Ruff)
```bash
pip install -e ".[dev]"
# Check only (no edits)
ruff check .
ruff format --check .
# Fix and format
ruff check . --fix
ruff format .
```
Configuration is in `pyproject.toml` under `[tool.ruff]` (Python 3.10, line length 100, select E/F/I/UP/B/C4).
### Project Structure
- `cloudgo_ai_mcp/` – Main package
- `server.py` – MCP server, tools, prompts, credential validation, CLI guardrails
- `console_urls.py` – Console deep links (get_console_url)
- `collectors.py` – Cloud-specific resource collectors
- `usage_collectors.py` – Cloud-specific usage/metrics collectors
- `models.py` – Data models and unified ID generation
- `store.py` – Inventory caching layer
- `config.py` – Configuration loading (server, aws, gcp, azure, cli)
---
## Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
See [SECURITY.md](SECURITY.md) for security reporting guidelines.
---
## License
MIT License. See [LICENSE](LICENSE).
---
## Support
- **Documentation**: See [docs/credentials.md](docs/credentials.md) for credential setup
- **Security Issues**: See [SECURITY.md](SECURITY.md)
- **Changelog**: See [CHANGELOG.md](CHANGELOG.md)
---
## Acknowledgments
Built with:
- [MCP SDK](https://github.com/modelcontextprotocol/python-sdk) - Model Context Protocol
- [boto3](https://boto3.amazonaws.com/) - AWS SDK
- [google-cloud](https://cloud.google.com/python) - GCP SDK
- [azure-mgmt](https://github.com/Azure/azure-sdk-for-python) - Azure SDK
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.