{"id":51536977,"url":"https://github.com/hritvikgupta/nimbus","last_synced_at":"2026-07-09T09:30:48.118Z","repository":{"id":369799506,"uuid":"1289981064","full_name":"hritvikgupta/nimbus","owner":"hritvikgupta","description":"Talk to your cloud — an open-source AI agent that reads your code, operates AWS \u0026 GCP, and opens PRs. Self-hostable.","archived":false,"fork":false,"pushed_at":"2026-07-07T01:31:14.000Z","size":132591,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-07T03:08:19.751Z","etag":null,"topics":["ai-agent","aws","claude","cloud","developer-tools","devops","docker","gcp","infrastructure","llm","mcp","model-context-protocol","self-hosted"],"latest_commit_sha":null,"homepage":"https://trynimbus.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hritvikgupta.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":"DCO","cla":null}},"created_at":"2026-07-05T12:47:11.000Z","updated_at":"2026-07-07T01:31:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hritvikgupta/nimbus","commit_stats":null,"previous_names":["hritvikgupta/nimbus"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hritvikgupta/nimbus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hritvikgupta%2Fnimbus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hritvikgupta%2Fnimbus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hritvikgupta%2Fnimbus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hritvikgupta%2Fnimbus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hritvikgupta","download_url":"https://codeload.github.com/hritvikgupta/nimbus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hritvikgupta%2Fnimbus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35295105,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","aws","claude","cloud","developer-tools","devops","docker","gcp","infrastructure","llm","mcp","model-context-protocol","self-hosted"],"created_at":"2026-07-09T09:30:47.296Z","updated_at":"2026-07-09T09:30:48.108Z","avatar_url":"https://github.com/hritvikgupta.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"public/favicon.svg\" alt=\"Nimbus\" width=\"72\" height=\"72\" /\u003e\n\n# Nimbus\n\n\u003csub\u003e[**Website**](https://trynimbus.dev) \u0026nbsp;·\u0026nbsp; [**Documentation**](https://docs.trynimbus.dev) \u0026nbsp;·\u0026nbsp; [**Quick start**](#run-with-docker-recommended)\u003c/sub\u003e\n\n**Talk to your cloud.**\n\nAn AI-powered cloud control plane. One agent that reads your code, understands your\narchitecture, acts on real AWS \u0026amp; GCP credentials, and fixes your repos — all through\nplain conversation.\n\n[![License: BSL 1.1](https://img.shields.io/badge/License-BSL%201.1-black.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A520-black.svg)](https://nodejs.org)\n[![React](https://img.shields.io/badge/React-18-black.svg)](https://react.dev)\n[![Made with Vite](https://img.shields.io/badge/Vite-5-black.svg)](https://vitejs.dev)\n\n\u003cimg src=\"public/og-image.jpg\" alt=\"Nimbus dashboard\" width=\"820\" /\u003e\n\n\u003c/div\u003e\n\n---\n\n## What is Nimbus?\n\nInstead of switching between cloud consoles, terminals, CI dashboards and IaC files, you work\nin **one place** with an agent that can design infrastructure, deploy it, watch it, and repair\nthe code behind it. Think of it as a senior platform engineer that lives inside your team chat.\n\nNimbus is built around three ideas:\n\n- **Intent-driven operations** — describe the outcome you want; Nimbus produces a plan, you\n  approve it, it executes. Reads are autonomous; every write is confirmed.\n- **One shared workspace per project** — channels, cloud connections, machines, repairs and the\n  architecture canvas are shared with your team. Only your private chat with Nimbus stays personal.\n- **Real execution, with evidence** — every claim is grounded in something the agent actually\n  read or ran (a file, a log, a live resource), and every change is auditable.\n\n## Features\n\n| | |\n|---|---|\n| 💬 **Conversational agent** | A ReAct chat loop with tool use — inspect inventory, read logs \u0026amp; telemetry, estimate cost, deploy, and open PRs. Design mode sketches architecture; Agent mode operates the real clouds. |\n| 🎨 **Live architecture canvas** | Ask Nimbus to design a system and watch the nodes render live (React Flow) — load balancer → app → database → cache. |\n| ☁️ **Multi-cloud** | Connect **AWS** (keys or IAM role, short-lived STS) and **GCP** (service-account JSON or keyless *Connect with Google* OAuth) via per-user, per-project MCP servers. |\n| 🧭 **Live cloud data** | Overview, Resources and Cost pull real inventory, telemetry and spend once a cloud is connected. |\n| 🛠️ **Shared-compute repairs** | Connect a laptop or CI runner; Nimbus drives your local **Claude Code** turn-by-turn to fix a repo, then pushes a branch and opens a PR. Machines are pooled per project. |\n| 🔌 **GitHub \u0026amp; more** | Connect repositories through Composio; the agent reads your code, PRs and CI before acting. |\n| 👥 **Teams \u0026amp; permissions** | Invite by email; per-member toggles for Channels, Machines \u0026amp; repairs, and Cloud \u0026amp; resources. |\n| 🔐 **Secure by design** | Credentials encrypted at rest (AES-256-GCM), never printed or logged; membership-enforced access; server-side audit trail. |\n\n\u003cdiv align=\"center\"\u003e\n\n**Design infrastructure on a live canvas**\n\n\u003cimg src=\"docs/images/canvas.png\" alt=\"Nimbus architecture canvas\" width=\"840\" /\u003e\n\n**Rent a machine on demand · Repair code on real machines**\n\n\u003cimg src=\"docs/images/rent-a-machine.png\" alt=\"Rent a machine\" width=\"420\" /\u003e\u0026nbsp;\u003cimg src=\"docs/images/repairs.png\" alt=\"Repairs\" width=\"420\" /\u003e\n\n\u003c/div\u003e\n\n## How it works\n\n```mermaid\nflowchart LR\n    A[\"Web app\u003cbr/\u003echat · canvas · dashboard\"] --\u003e|HTTP /api| G\n    B[\"Connected machine\u003cbr/\u003e@nimbus/cli\"] -. \"poll · repairs\" .-\u003e G\n    F[\"Rented machine\u003cbr/\u003eFly\"] -. \"driven via API\" .-\u003e G\n\n    G([\"Nimbus Agent\u003cbr/\u003eReAct loop + tools\"])\n\n    G --\u003e SEC[\"Plan-then-act\u003cbr/\u003ewrites need approval\"]\n    G --\u003e MCP[\"Per-user MCP servers\"] --\u003e CLOUD[\"AWS · GCP\u003cbr/\u003efull CLI surface\"]\n    G --\u003e CANVAS[\"Live architecture canvas\"]\n    G --\u003e REPAIR[\"Repairs → open PR\u003cbr/\u003eClaude Code\"]\n    G --\u003e OBS[\"Cost · logs · telemetry\"]\n    G --\u003e VAULT[\"Encrypted credential vault\u003cbr/\u003eAES-256-GCM\"]\n\n    classDef agent fill:#FF9900,stroke:#FF9900,color:#111111,font-weight:bold;\n    classDef box fill:#161b22,stroke:#30363d,color:#e6edf3;\n    class G agent;\n    class A,B,F,SEC,MCP,CLOUD,CANVAS,REPAIR,OBS,VAULT box;\n```\n\nYou talk to the Nimbus agent from the web app (or `@mention` it in a channel). It reads your code\nand real cloud state, and grounds every answer in evidence — a file, a log line, a live resource.\nIt acts through **per-user MCP servers** scoped to your own credentials, giving it the full `aws`\nand `gcloud` surface. **Reads are autonomous; anything that changes a billable resource waits for\nyour approval.** Secrets stay in the encrypted vault and never reach the model. Repairs run on a\nmachine you connect (your laptop, CI, or a rented one) and come back as a pull request.\n\n## Architecture\n\nNimbus is a **React SPA** talking to a **thin Express API** that fans out to services,\nrepositories, agents and per-user cloud MCP servers. A separate **CLI worker** connects\noutside machines for repairs.\n\n```\n┌──────────────────────┐        ┌───────────────────────────────────────────────┐\n│  Web app (Vite/React)│  /api  │  API server (Express)                          │\n│  localhost:5280      │ ─────► │  localhost:8788                                │\n│  • chat + canvas     │  proxy │                                                │\n│  • dashboard         │        │  routes/       → HTTP handlers (per resource)  │\n│  • connections       │        │  services/     → cloud, telemetry, cost, spec… │\n└──────────────────────┘        │  repositories/ → SQLite persistence            │\n                                │  agents/       → ReAct chat loop + analysis    │\n┌──────────────────────┐        │  tools/        → agent tools (canvas, repair…) │\n│  Connected machine   │  poll  │  libs/         → model, MCP, composio, aws/gcp │\n│  @nimbus/cli + Claude │ ◄────► │  mcp/          → aws / gcloud / cloud-run MCP  │\n│  Code (your laptop)  │  (PR)  └───────────────────────────────────────────────┘\n└──────────────────────┘                    │\n                                 SQLite (better-sqlite3) · creds encrypted at rest\n```\n\nUser identity comes **strictly from the session cookie**; `req.user.id` is the isolation\nboundary every service and MCP call is scoped to.\n\n### Tech stack\n\n- **Frontend** — React 18, Vite 5, React Router, React Flow, `@ai-sdk/react`, react-markdown\n- **Backend** — Node ≥ 20, Express, `better-sqlite3`, Helmet, Zod\n- **AI** — Vercel AI SDK (`ai`), Databricks (primary) with OpenRouter cross-provider fallback,\n  Model Context Protocol (`@modelcontextprotocol/sdk`)\n- **Integrations** — Composio (GitHub), AWS \u0026amp; GCP MCP servers, Fly.io (provisioning / rented machines)\n\n## Run with Docker (recommended)\n\nThe fastest way to run Nimbus. The image bundles everything the cloud MCP servers need —\n`git`, `uv` (AWS), the `gcloud` CLI (GCP) and Node — so there's nothing else to install. You only\nprovide your `.env`.\n\n```bash\ngit clone https://github.com/hritvikgupta/nimbus.git\ncd nimbus\ncp .env.example .env\n\n# 1. Generate the master encryption key and append it to .env (protects stored credentials):\necho \"NIMBUS_ENC_KEY=$(openssl rand -base64 32)\" \u003e\u003e .env\n\n# 2. Open .env and fill in your AI model — LLM_PROVIDER, LLM_MODEL, OPENROUTER_API_KEY.\n#    (Optional: FLY_API_TOKEN to rent machines, COMPOSIO_API_KEY for GitHub.)\n\n# 3. Run it:\ndocker compose up --build\n# open http://localhost:8788\n```\n\n\u003e No `openssl`? Use `node -e \"console.log(require('crypto').randomBytes(32).toString('base64'))\"` and paste the result as `NIMBUS_ENC_KEY=` in `.env`.\n\nOne container serves the app **and** the API on port `8788`. Your data (the SQLite DB + encrypted\nconnections) persists in the `nimbus-data` volume across restarts.\n\n\u003e Prefer plain `docker`? `docker build -t nimbus . \u0026\u0026 docker run -p 8788:8788 --env-file .env -v nimbus-data:/app/server/.data nimbus`\n\nTo run from source instead (for development), follow the steps below.\n\n## Quick start (from source)\n\n### Prerequisites\n\n- **Node.js ≥ 20** and npm\n- An **LLM provider** — a Databricks serving endpoint *or* an OpenRouter API key\n- *(optional)* a **Composio** API key for GitHub, and AWS/GCP credentials to connect real clouds\n- For the cloud MCP servers: [`uv`](https://docs.astral.sh/uv/) (AWS) and the\n  [`gcloud` CLI](https://cloud.google.com/sdk/docs/install) (GCP) — bundled automatically in Docker\n\n### 1. Install\n\n```bash\ngit clone https://github.com/hritvikgupta/nimbus.git\ncd nimbus\nnpm install\n```\n\n### 2. Configure\n\n```bash\ncp .env.example .env\n```\n\nFill in `.env` (see [Configuration](#configuration)). At minimum, set a `NIMBUS_ENC_KEY` and one\nLLM provider:\n\n```bash\n# generate the master encryption key\nnode -e \"console.log(require('crypto').randomBytes(32).toString('base64'))\"\n```\n\n### 3. Set up the cloud MCP servers\n\nThe agent talks to your clouds through three MCP servers vendored under\n[`server/mcp/`](server/mcp) — **AWS** (`aws-mcp`, Python via `uvx`), **Cloud Run**\n(`cloud-run-mcp`) and **gcloud** (`gcloud-mcp`). Their source lives in the repo; install their\ndependencies (and build the gcloud bundle) once:\n\n```bash\nnpm run setup:mcp\n```\n\nThis runs `npm install` for the Node servers, builds `gcloud-mcp`, and checks for\n[`uv`](https://docs.astral.sh/uv/) (needed to launch the AWS server). You can skip this if you\nonly use one cloud — the corresponding server is only spawned when a matching connection exists.\n\n**Host prerequisites** (the MCP servers shell out to these — install the ones for the clouds you use):\n\n| Cloud | Requires on the host | Why |\n|---|---|---|\n| **AWS** | [`uv`](https://docs.astral.sh/uv/) | Launches `aws-api-mcp-server` (Python); pulls its deps from PyPI on first run. Gives the full `call_aws` tool. |\n| **GCP** | the [`gcloud` CLI](https://cloud.google.com/sdk/docs/install) on `PATH` | `gcloud-mcp` executes `gcloud` commands — the full `run_gcloud_command` surface. |\n\nOnce installed, the agent has the **complete AWS and gcloud command surface** plus Cloud Run\ndeploy/logs — the servers themselves are the full upstream implementations, not trimmed subsets.\nYou still connect your own cloud credentials in the app (**Connections**).\n\n### 4. Run\n\nNimbus is two processes — the API and the web app. Run them in two terminals:\n\n```bash\nnpm run api     # backend  → http://localhost:8788\nnpm run dev     # frontend → http://localhost:5280   (proxies /api to :8788)\n```\n\nOpen **http://localhost:5280**, create an account, and the guided walkthrough will introduce\nthe workspace. Connect a repo and a cloud from **Connections**, then start chatting.\n\n## Configuration\n\nAll configuration is via environment variables in `.env` (loaded by `npm run api`).\n\n| Variable | Required | Description |\n|---|---|---|\n| `NIMBUS_ENC_KEY` | **yes** (prod) | Base64 32-byte master key; encrypts cloud credentials at rest (AES-256-GCM). |\n| `LLM_PROVIDER` | yes | `databricks` or `openrouter`. |\n| `LLM_MODEL` | yes | Model id for the selected provider. |\n| `DATABRICKS_HOST` / `DATABRICKS_TOKEN` / `DATABRICKS_MODEL` | if databricks | Primary serving endpoint. |\n| `OPENROUTER_API_KEY` | if openrouter | Cross-provider fallback / primary. |\n| `COMPOSIO_API_KEY` | optional | GitHub (and other app) connections. |\n| `GITHUB_TOKEN` | optional | Higher GitHub API rate limits. |\n| `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` | optional | GCP keyless *Connect with Google*. |\n| `FLY_API_TOKEN` / `FLY_ORG` / `FLY_REGION` / `FLY_APP` / `FLY_MACHINE_IMAGE` | optional | Provisioning \u0026amp; rented machines. |\n| `AGENT_PORT` | optional | API port (default `8788`). |\n| `APP_URL` | optional | Public app URL — GCP OAuth redirects + links (dev `http://localhost:5280`; Docker `http://localhost:8788`). |\n| `ALLOW_SIGNUP` | optional | `false` closes registration on public deploys. |\n| `AGENT_DAILY_LIMIT` | optional | Per-user daily cap on expensive agent/cloud actions. |\n| `CORS_ORIGINS` | optional | Comma-separated allowlist; empty = same-origin only. |\n| `DOCS_HOST` | optional | Extra host to serve docs from (besides `docs.*`). |\n| `OPS_SCAN_MINUTES` | optional | `\u003e 0` enables the scheduled incident scan. |\n| `WEBHOOK_BASE` | optional | Public base URL for inbound webhooks. |\n\n**What you actually need:**\n\n- **Always:** `NIMBUS_ENC_KEY` + an AI model (`LLM_PROVIDER` + `LLM_MODEL` + `OPENROUTER_API_KEY`, or the Databricks trio). Your provider, your key, your billing.\n- **To rent machines (Fly):** your own `FLY_API_TOKEN` (+ optional `FLY_*`). Leave blank to disable the feature. Rented machines need **no public URL** — the worker runs inside this server and drives Fly via its API. The person renting supplies their own coding-agent key per rental in the UI.\n- **To connect your own laptop/CI for repairs:** nothing here — that machine runs the [`@nimbus/cli`](cli/README.md) worker and *polls* this server, so **it** is pointed at Nimbus (`nimbus start \u003ckey\u003e --url https://your-host`), not the other way around.\n- **When hosting publicly:** set `APP_URL` to your real URL (used for GCP OAuth redirects + links), and optionally `WEBHOOK_BASE`, `CORS_ORIGINS`, `ALLOW_SIGNUP=false`.\n\n\u003e **Never commit your real `.env`.** It is gitignored; `.env.example` is the template.\n\n## Connect a machine (repairs)\n\nRepairs run on real machines you own via the [`@nimbus/cli`](cli/README.md) worker. It polls\nNimbus (outbound only — works behind any NAT/firewall); when a fix is dispatched it clones the\nrepo, drives your local Claude Code to find and fix the issue, and opens a PR.\n\n```bash\nnpm install -g @nimbus/cli\n# In the app: Repairs → Connect a machine → Generate key\nnimbus start \u003cworker-key\u003e\n```\n\nThe machine needs **Claude Code** (installed + logged in), **git**, and **gh**. See\n[`cli/README.md`](cli/README.md) for the full worker docs.\n\n## Project structure\n\n```\nnimbus/\n├── src/                 # React SPA — pages, components, context, styles\n├── server/              # Express API\n│   ├── server.mjs       #   thin HTTP entry — mounts routers\n│   ├── routes/          #   HTTP handlers (one file per resource)\n│   ├── services/        #   business logic (cloud, telemetry, cost, spec, repair…)\n│   ├── repositories/    #   persistence (SQLite via better-sqlite3)\n│   ├── agents/          #   ReAct chat loop + codebase-analysis agent\n│   ├── tools/           #   agent tools (canvas, repair, telemetry, code…)\n│   ├── libs/            #   external clients (model, MCP, composio, aws, gcp)\n│   ├── mcp/             #   AWS / gcloud / Cloud Run MCP servers\n│   └── middlewares/     #   session auth + cloud scoping\n├── cli/                 # @nimbus/cli — the connected-machine repair worker\n├── docs-site/           # Fumadocs documentation site (statically exported)\n├── deploy/              # Fly.io deploy configs (landing + docs)\n├── docs/               # architecture \u0026 design docs (production-readiness, rented-compute…)\n└── public/              # static assets (logos, brand)\n```\n\n## Deployment\n\nNimbus targets **[Fly.io](https://fly.io)**. The API server also serves the statically-exported\ndocs site (from `docs-site/out`) whenever the request host matches `docs.*`, so `docs.yourdomain`\nneeds no separate process.\n\n```bash\ncd docs-site \u0026\u0026 npm run build     # regenerate docs-site/out\n# then deploy the API + built SPA to Fly (see docs/production-readiness)\n```\n\nProduction hardening — deploy architecture, security tiers and scaling — is documented under\n[`docs/production-readiness/`](docs/production-readiness).\n\n## Security\n\n- **Credentials encrypted at rest** with AES-256-GCM; the master key (`NIMBUS_ENC_KEY`) lives only\n  in the environment.\n- **Secrets are never printed, logged, or returned** in chat or API responses.\n- **Plan-then-act** — the agent never creates, scales, modifies or deletes a billable resource\n  without showing a plan and getting explicit confirmation.\n- **Membership-enforced access** on the server for every project-scoped action.\n- Cloud MCPs run with **only the project's credentials**; AWS STS / GCP tokens are short-lived.\n\nFound a vulnerability? See [SECURITY.md](SECURITY.md). Please do **not** open a public issue.\n\n## Contributing\n\nContributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, conventions,\nand PR process.\n\n## License\n\n**Nimbus is source-available under the [Business Source License 1.1](LICENSE).** © 2026 Hritvik Gupta.\n\nYou may **read, self-host, modify, and use it** freely — for internal, development, evaluation, and\nnon-commercial purposes. You may **not** offer Nimbus to third parties as a competing hosted/managed\nservice. On the **Change Date (2030-01-01)** each released version converts to **Apache 2.0**.\n\n- **Trademarks** (\"Nimbus\", the logo) are reserved — see [TRADEMARKS.md](TRADEMARKS.md).\n- **Third-party components** (the vendored MCP servers under `server/mcp/`) keep their own Apache-2.0\n  licenses — see [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).\n- Need a commercial or hosting license? Contact the maintainer.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhritvikgupta%2Fnimbus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhritvikgupta%2Fnimbus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhritvikgupta%2Fnimbus/lists"}