Skip to content

claytonshaver/cloud-spawn-be

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cloud-spawn-be

The CloudSpawn MCP (Model Context Protocol) server. Connects to Claude Desktop and exposes GCP infrastructure provisioning as conversational tools — deploy services, create databases, store secrets, and more, all through natural language.

Architecture

┌─────────────────────────────────────────────────────────────────┐
│  Claude Desktop                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │  MCP Client (stdin/stdout)                                │  │
│  └──────────────────────┬────────────────────────────────────┘  │
└─────────────────────────┼───────────────────────────────────────┘
                          │ MCP Protocol
┌─────────────────────────┼───────────────────────────────────────┐
│  cloud-spawn-be         │                                       │
│  ┌──────────────────────▼────────────────────────────────────┐  │
│  │  MCP Server (index.ts)                                    │  │
│  │  ┌──────────────────────────────────────────────────────┐ │  │
│  │  │  Auth Middleware (withAuth)                           │ │  │
│  │  │  Validates API key → derives customer_id             │ │  │
│  │  │  Rate limiting · Activity logging                    │ │  │
│  │  └──────────────┬───────────────────────────────────────┘ │  │
│  │  ┌──────────────▼───────────────────────────────────────┐ │  │
│  │  │  Tools (9 registered)                                │ │  │
│  │  │  deploy_service · deploy_static_site · create_db     │ │  │
│  │  │  create_bucket · store_secret · get_service_url      │ │  │
│  │  │  get_customer_status · teardown · register_customer  │ │  │
│  │  └──────────────┬───────────────────────────────────────┘ │  │
│  └─────────────────┼────────────────────────────────────────┘   │
│  ┌─────────────────▼────────────────────────────────────────┐   │
│  │  GCP Clients (admin SA impersonation)                    │   │
│  │  Cloud Run · Cloud SQL · GCS · Secret Manager · LB      │   │
│  └─────────────────┬────────────────────────────────────────┘   │
│  ┌─────────────────▼────────────────────────────────────────┐   │
│  │  Platform DB (cs_platform_mgmt on Cloud SQL)             │   │
│  │  users · customers · api_keys · activity_log             │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│  GCP (cs-platform project)                                      │
│  Cloud Run · Cloud SQL · GCS · Secret Manager · Global LB      │
└─────────────────────────────────────────────────────────────────┘

Auth Flow

Tool call with api_key
        │
        ▼
┌───────────────┐     ┌──────────────────┐     ┌────────────────┐
│  Rate Limit   │────▶│  Validate Key    │────▶│  Set           │
│  Check        │     │  (SHA-256 hash,  │     │  customer_id   │
│  (10/5min     │     │  timingSafeEqual)│     │  from auth     │
│  → 15min lock)│     │                  │     │  context       │
└───────────────┘     └──────────────────┘     └───────┬────────┘
                                                       │
                                                       ▼
                                               ┌────────────────┐
                                               │  Execute Tool  │
                                               │  Handler       │
                                               └───────┬────────┘
                                                       │
                                                       ▼
                                               ┌────────────────┐
                                               │  Log Activity  │
                                               │  (async,       │
                                               │  non-blocking) │
                                               └────────────────┘

GCP Resource Model

All customer resources live in a single shared GCP project (cs-platform). Isolation is enforced through naming conventions, resource labels, and API key scoping:

cs-platform (shared project)
├── Cloud Run
│   └── {customerId}-{serviceName}        labels: customer-id, managed-by
├── Cloud SQL (cs-platform-db instance)
│   ├── cs_{customerId}_{dbName}          customer databases
│   └── cs_platform_mgmt                 platform management database
├── Cloud Storage
│   └── {projectId}-{customerId}-{slug}   labels: customer-id, managed-by
├── Secret Manager
│   └── {customerId}_{secretName}         labels: customer-id
└── Global HTTPS Load Balancer
    ├── cs-bs-{customerId}-{service}      backend services (Cloud Run)
    ├── cs-be-{customerId}-{site}         backend buckets (static sites)
    └── URL Map routes {customer}-{name}.cloudspawn.app → backends

Project Structure

src/
├── index.ts                 # MCP server entry point (stdio transport)
├── config.ts                # Environment variable loading
├── types/
│   └── index.ts             # Shared TypeScript interfaces
├── gcp/
│   ├── client.ts            # Admin SA impersonation setup
│   ├── cloud-run.ts         # Cloud Run service CRUD + LB registration
│   ├── cloud-sql.ts         # Database creation on shared instance
│   ├── storage.ts           # GCS bucket management + file uploads
│   ├── secret-manager.ts    # Secret storage + Cloud Run injection
│   ├── load-balancer.ts     # Global HTTPS LB infrastructure
│   ├── platform-db.ts       # Platform management DB (users, keys, etc.)
│   ├── projects.ts          # GCP API enablement
│   └── teardown.ts          # Resource cleanup orchestration
├── tools/
│   ├── deploy-service.ts    # Deploy container to Cloud Run
│   ├── deploy-static-site.ts# Deploy HTML/CSS/JS to GCS + LB
│   ├── create-database.ts   # Create PostgreSQL database
│   ├── create-bucket.ts     # Create GCS bucket
│   ├── store-secret.ts      # Store secret, optionally inject into service
│   ├── get-service-url.ts   # Get Cloud Run + custom domain URL
│   ├── get-customer-status.ts# List all resources for a customer
│   ├── register-customer.ts # Register a new customer namespace
│   └── teardown-customer.ts # Destroy all customer resources
└── utils/
    ├── auth.ts              # withAuth middleware for API key validation
    ├── errors.ts            # Tool response helpers + GCP error mapping
    └── logger.ts            # Structured JSON logging to stderr

Setup

Prerequisites

  • Node.js 20+
  • GCP project with Cloud SQL, Cloud Run, GCS, Secret Manager, and Load Balancing APIs enabled
  • An admin service account with appropriate IAM roles
  • Application Default Credentials configured (gcloud auth application-default login)

Install

npm install

Environment Variables

Create a .env file:

# Required
CLOUDSPAWN_ORG_ID=123456789            # GCP organization ID
CLOUDSPAWN_BILLING_ACCOUNT_ID=AABBCC   # GCP billing account ID
CLOUDSPAWN_ADMIN_SA=cs-admin@project.iam.gserviceaccount.com
CLOUDSPAWN_PLATFORM_PROJECT=cs-platform
CLOUDSPAWN_PLATFORM_DB_PASSWORD=       # Password for cs_platform_admin DB user

# Optional (with defaults)
CLOUDSPAWN_REGION=us-central1
CLOUDSPAWN_DOMAIN=cloudspawn.app

Build & Run

npm run build        # Compile TypeScript → build/
npm start            # Run the MCP server (stdio transport)
npm run dev          # Watch mode for development

Claude Desktop Configuration

Add to your Claude Desktop MCP config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "cloudspawn": {
      "command": "node",
      "args": ["/path/to/cloud-spawn-be/build/index.js"],
      "env": {
        "CLOUDSPAWN_ORG_ID": "...",
        "CLOUDSPAWN_BILLING_ACCOUNT_ID": "...",
        "CLOUDSPAWN_ADMIN_SA": "...",
        "CLOUDSPAWN_PLATFORM_PROJECT": "...",
        "CLOUDSPAWN_PLATFORM_DB_PASSWORD": "..."
      }
    }
  }
}

Tools

Every tool requires an api_key parameter. The API key determines which customer's resources the tool operates on — customer_id is derived from the key and cannot be overridden.

Tool Description
register_customer Register a new customer namespace, optionally create initial DB
deploy_service Deploy a container image to Cloud Run with custom domain
deploy_static_site Deploy HTML/CSS/JS files to GCS with CDN + custom domain
create_database Create a PostgreSQL database on the shared Cloud SQL instance
create_bucket Create a GCS bucket for file storage
store_secret Store a secret, optionally inject into a Cloud Run service
get_service_url Get the URL for a deployed Cloud Run service
get_customer_status List all resources (services, DBs, buckets, secrets)
teardown_customer Irreversibly destroy all customer resources

Security

  • API key scoping: Each key is bound to exactly one customer_id via FK. withAuth overrides any user-supplied customer_id.
  • Key storage: Only SHA-256 hashes are stored. Full key is returned once at creation.
  • Timing attacks: Key validation uses crypto.timingSafeEqual on the hash.
  • Rate limiting: 10 failed auth attempts in 5 minutes locks the source for 15 minutes.
  • SQL injection: All queries use parameterized placeholders ($1, $2).
  • Error messages: Generic "Invalid or missing API key" on failure — no information leakage.

About

Backend for cloud spawn

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors