IEXDG Library · Cloud reference · April 27, 2026

The brain runs on Google Cloud
here is exactly how it works, what it costs, and how it stays safe

Plain-language tour for DNicole. Technical depth for Robert and any auditor your enterprise clients send. Every answer to "where does the data live, who can see it, what is the cost, what happens when it breaks" lives below.

Built April 27, 2026 · brain.iexdg.com · iexdg-nexus-vm · drdnicole-youtube-manager · Robert Dove · Dove Web Consulting
⚡ TL;DR

Your brain.iexdg.com lives on a single Google Cloud VM at iexdg-nexus-vm, costs roughly $25 a month, inherits FedRAMP and CMMC compliance, and is now mid-migration from bearer-token sign-in to native Google sign-in.

Every tool Claude uses on your behalf, every Notion query, every GHL contact lookup, every Culture Pulse SOP generation, runs through this VM. It is the heart of the IEXDG operating system and the single artifact your clients audit when they ask "where does our data go." This document is the canonical answer.

What actually runs on Google Cloud

One VM, four services, three integrations · all pinned to the IEXDG project

Google Cloud hosts a single virtual machine called iexdg-nexus-vm. That VM runs four daemons that together expose two public surfaces: a static dashboard at the root of brain.iexdg.com, and the MCP endpoint that Claude Desktop talks to. Everything else (Notion, GoHighLevel, RAG, Culture Pulse data) lives behind the VM and is reached over outbound HTTPS to those upstream APIs.

1
VM in production
4
Daemons running
33
Tools exposed
10,601
RAG chunks

The four daemons on the VM

ServicePortPurposeStatus
caddy80, 443Reverse proxy, TLS termination, static dashboard, route gatingActive
iexdg-mcp127.0.0.1:8765MCP server with bearer auth (legacy, used by cron + scripts)Active
iexdg-mcp-oauth127.0.0.1:8766MCP server with Google OAuth (Apr 27 build, Claude Desktop UI path)Pre-staged
iexdg-api127.0.0.1:8000Dashboard JSON API, GHL/Notion bridge, capture endpointsActive

External surfaces

https://brain.iexdg.com/Static dashboard, the v4.1 cream interface DNicole uses daily
https://brain.iexdg.com/mcpOAuth-protected MCP endpoint, Claude Desktop talks here after Apr 27
https://brain.iexdg.com/mcp-bearerLegacy bearer-protected MCP, used by cron jobs during the 7-day migration
https://brain.iexdg.com/api/healthPublic health probe, no auth, returns service liveness JSON
https://brain.iexdg.com/api/dashboardPublic dashboard data (read-only), returns Notion DB counts and pipeline state
END-TO-END ARCHITECTURE · BRAIN.IEXDG.COM USERS 💬 Dr. DNicole Claude Desktop 🌐 Browser visitors brain.iexdg.com ☁️ HTTPS GOOGLE CLOUD · PROJECT drdnicole-youtube-manager VM · iexdg-nexus-vm · e2-small · us-east4-b · 35.212.85.205 🚦 Caddy · :80 :443 · TLS · routing · static dashboard Auto Let's Encrypt · handle blocks · bearer + OAuth gates ⚙️ iexdg-mcp :8765 bearer cron + scripts 🔐 iexdg-mcp-oauth :8766 OAuth · Apr 27 Claude Desktop UI 📊 iexdg-api :8000 FastAPI dashboard JSON 🧠 RAG knowledge base /opt/iexdg-mcp/rag/ · 10,601 chunks SQLite read-only via ?mode=ro 🔑 Token store /var/lib/iexdg-brain/oauth.db iexdg:iexdg · mode 700 UPSTREAM APIS · CALLED OUTBOUND OVER HTTPS 📓 Notion War Room · Calendar · Trackers 📡 GoHighLevel Contacts · Pipelines · Social 🔍 Perplexity Research · capped daily 📧 Gmail 🎬 YouTube 🤖 Anthropic API
Three internal services on one VM, behind Caddy, calling six upstream APIs outbound. Single VM is intentional for cost. Single project keeps the audit blast radius small.

🎯Why Google Cloud, not AWS, not HighLevel, not a basic VPS

Three reasons that matter for your enterprise sales motion

Reason 1 · FedRAMP and CMMC inheritance

Google Cloud Platform is FedRAMP authorized at the High baseline and your VM inherits that compliance posture by default. CMMC Level 1 is automatic. CMMC Level 2 is achievable with the controls you already have. When a state agency or insurance broker sends an enterprise security questionnaire, the answer "we run on FedRAMP authorized infrastructure" is one line and it is true.

Reason 4 · ML and ownership of leadership IP

The Premium Advisory Tools, the Culture Pulse generator, the SOP synthesizer, the voice drift checker · these all run on infrastructure you control. Future ML models for content scoring, lead quality, churn prediction, voice drift trend live in this same VM. None of it leaves your project.

🏗️The brain VM, in detail

Specifications, ports, processes, storage

Hardware and image

Instance nameiexdg-nexus-vm
Machine typee2-small (2 vCPU bursting, 2 GB RAM)
Disk10 GB pd-balanced (29 GB total root, 12 GB used)
OS imageUbuntu 24.04.4 LTS · kernel 6.17.0-1012-gcp
Region · Zoneus-east4 · us-east4-b
External IP35.212.85.205 · static · STANDARD tier
DNSbrain.iexdg.com → 35.212.85.205 · A record at Squarespace DNS
TLSLet's Encrypt via Caddy · auto-renew · 89-day cycle
FirewallVPC default-allow-http and default-allow-https · :22 SSH via gcloud IAP only

Filesystem layout

PathOwnerModePurpose
/opt/iexdg-mcp/iexdg:iexdg755Application root · Python wrappers, RAG db, venv
/opt/iexdg-mcp/venv/iexdg:iexdg755Python 3.12 virtualenv · isolated deps
/opt/iexdg-mcp/iexdg_content_mcp_v3_2_apr22.pyiexdg:iexdg644The 33-tool source · canonical legacy
/opt/iexdg-mcp/iexdg_mcp_oauth_wrapper.pyiexdg:iexdg644OAuth wrapper · Apr 27 build · pre-staged
/etc/default/iexdg-mcproot:iexdg640Env file · API keys, OAuth client secret · NOT world-readable
/etc/systemd/system/iexdg-mcp*.serviceroot:root644systemd unit files for the 4 daemons
/etc/caddy/Caddyfileroot:root644Caddy config · routing + auth
/var/lib/iexdg-brain/iexdg:iexdg700OAuth token store · iexdg-only readable
/var/log/iexdg-mcp/iexdg:iexdg755Service logs · 30-day rotation via logrotate
/var/log/caddy/caddy:caddy755Caddy access + error logs · 30-day rotation
/srv/brain/public/caddy:caddy755Static dashboard files · index.html and assets

Process tree (post-Apr 27)

systemd
├── caddy.service                 (root → caddy user)
├── iexdg-api.service              (iexdg user, FastAPI :8000)
├── iexdg-mcp.service              (iexdg user, FastMCP bearer :8765)
├── iexdg-mcp-oauth.service        (iexdg user, FastMCP OAuth :8766)
├── iexdg-health-check.timer       → iexdg-health-check.service (every 5 min)
├── iexdg-ghl-observer.timer       → iexdg-ghl-observer.service (every 15 min)
└── iexdg-content-drop.timer       → daily_content_drop.py (2 AM CST)

All four primary services run as the unprivileged iexdg user. None can escalate to root, none can access each other's home directory, none can read /etc/default/iexdg-mcp outside of the systemd-injected env. Service hardening details are documented inside each .service file.

🔐The OAuth path build · April 27, 2026

What ships, what is staged, what waits on Robert
What changes  Until tonight, brain.iexdg.com used a static bearer token to authenticate Claude. That works for cron jobs and scripts but Claude Desktop's UI does not accept bearer tokens, only OAuth. We are migrating to Google sign-in so Dr. DNicole can add the connector via Settings without an installer.

Pre-stage state (Apr 27 03:30 UTC)

  • Wrapper · iexdg_mcp_oauth_wrapper.py uploaded to /opt/iexdg-mcp/
  • Systemd unit · iexdg-mcp-oauth.service registered with systemd, currently disabled (will not start until Google credentials are present)
  • Token storage · /var/lib/iexdg-brain/ created, mode 700, owned by iexdg user
  • Caddyfile.oauth.staged · new Caddyfile with the seven OAuth metadata routes uploaded to /etc/caddy/Caddyfile.oauth.staged · not yet active
  • Caddyfile.bak-pre-oauth-apr27 · current live Caddyfile backed up before any swap
  • fastmcp v3.2.4 · installed in /opt/iexdg-mcp/venv alongside authlib, httpx, itsdangerous
  • 33-tool lift verified · the wrapper's pattern of importing the legacy mcp instance and re-registering its 33 tools on a new fastmcp v3 instance was probed and works (ToolManager.\_tools dict size = 33)
  • GHSA-5h2m-4q8j-pqpj patch confirmed · the resource parameter audience check is present in fastmcp 3.2.4 source
  • Live brain unaffected · all three legacy services (mcp, caddy, api) still active, /api/health returns 200

What is needed to ship live

  1. Robert · Google Cloud Console · 10 minutes · Add a new OAuth client of type Web application to the existing drdnicole-youtube-manager project (Phase 1 of the OAuth runbook). Re-using the existing project saves 20 minutes and keeps audit logs in one place. Authorized redirect URI: https://brain.iexdg.com/auth/callback. Grab the Client ID and Client Secret from the credentials modal.
  2. Robert pastes credentials to Claude · 30 seconds · Robert sends the Client ID and Secret in a secure channel
  3. Claude finishes deploy via SSH · 5 minutes · Append credentials to /etc/default/iexdg-mcp, swap Caddyfile, start iexdg-mcp-oauth.service, reload Caddy, run smoke tests against the seven OAuth metadata endpoints
  4. Robert end-to-end test · 5 minutes · From Robert's own Claude Desktop, add custom connector at https://brain.iexdg.com/mcp, complete Google sign-in, verify 33 tools appear
  5. DNicole switchover · 2 minutes · Same UI flow on her Mac, signed in as drdnicole@iexdg.com
  6. T+7 days · sunset bearer for human users · The legacy /mcp-bearer route stays for cron during the migration week, then we remove it (or keep it gated for cron-only)
Why we keep the bearer wrapper running for a week  Risk-mitigation. If anything in the OAuth flow breaks, the existing scripts and cron jobs that hit the legacy /mcp-bearer endpoint never notice the upgrade. We sunset cleanly after 7 stable days.

🛰️Google Cloud APIs and services in use

What is enabled in the IEXDG project right now
API / ServicePurposeStatusCost
Compute EngineThe VM itselfIn use~$14/mo (e2-small + disk)
VPC NetworkingStatic external IP, firewall rulesIn use$7/mo (static IP)
Cloud LoggingAggregated logs for caddy + systemd journalIn use~$0-3/mo (under free tier most months)
Cloud Scheduler3 cron timers via gcloud_setup_schedulers.shIn use$0 (3 jobs free tier)
Secret ManagerMigrate API keys out of /etc/default/iexdg-mcp fileGate 7 open~$1/mo when migrated
IAMService accounts for VM, future ML training, auditsIn use$0
Cloud DNSNot used · DNS hosted at SquarespaceNot enabled$0
Cloud StorageFuture · VM snapshots, backups, RAG corporaPlanned~$0-2/mo when enabled
YouTube Data API v3Daily content drop reads DNicole channelIn use$0 (quota tier)
Gmail APISend + read emails for content drop, repliesIn use$0 (quota tier)

OAuth clients in IEXDG GCP

Client ID prefixTypeCreatedUsed forRedirect URIs
918058969668-aqj...installed (desktop)2026 · pre-IEXDG-VMYouTube + Gmail authentication for daily content drophttp://localhost
(NEW) 918058969668-???webApr 27, 2026 (pending)brain.iexdg.com OAuth for Claude Desktop · this buildhttps://brain.iexdg.com/auth/callback

Re-using the same GCP project for both clients keeps the audit trail in one place. Each client has its own Client ID and Secret, isolated.

💰Monthly cost, line by line

Predictable. Capped at $50. Hard stop at $100.
Line itemUnit costMonthlyNotes
e2-small VM$0.0203/hr$14.62730 hours/month, 24/7
10 GB pd-balanced disk$0.10/GB/mo$1.00Boot + application disk
Static external IP$0.01/hr$7.30STANDARD network tier (us-east4)
Cloud Logging ingest$0.50/GB$0-2~50 MB/day for VM logs, free tier covers most
Network egress (NA)$0.085/GB$0-2Mostly inbound (Notion/GHL pulls)
Cloud Scheduler (3 jobs)free$0First 3 jobs free in any project
Secret Manager (after Gate 7)$0.06/secret/mo$0.50~8 secrets when migrated
Storage egress (browser dashboard)$0.085/GB$0-1HTML + JS, light traffic
Total expected$23 to $28Per month, all-in
Budget alerts  Configured by DNicole on Apr 24. $50/mo budget with notifications at $25, $45, and $50. Hard stop at $100 enforced via the Compute Engine API quota. A runaway script that tries to retrain a model in a loop cannot burn more than the cap before it gets paused.

🛡️Security posture

What clients ask. The honest answers.

Compliance inheritance

  • FedRAMP authorized infrastructure (GCP itself, High baseline)
  • CMMC Level 1 eligible by default
  • CMMC Level 2 achievable with current controls + DR plan + access review schedule
  • SOC 2 Type II coverage from Google
  • HIPAA-eligible if BAA is signed (not yet, applicable for healthcare clients only)

Network

  • TLS 1.3 on brain.iexdg.com (Let's Encrypt via Caddy, auto-renew)
  • HTTPS-only, port 80 redirects to 443
  • SSH closed publicly, only via gcloud IAP tunneling with explicit grant
  • Internal services bind 127.0.0.1 only, never reachable from internet
  • Outbound HTTPS for upstream APIs, no inbound from upstreams

Identity + access

  • Bearer token for legacy MCP, will sunset by T+7 days
  • OAuth 2.1 + PKCE via Google for Claude Desktop (Apr 27 build)
  • Dynamic Client Registration per RFC 7591, required by Anthropic UI
  • Allowlist by Google account at consent screen test users
  • Refresh tokens default 30 days (configurable), rotation on every use
  • Revocation endpoint available at /revoke per RFC 7009

Secrets

  • Today · API keys live in /etc/default/iexdg-mcp mode 640 root:iexdg, only the iexdg user reads them
  • Gate 7 open · migrate to GCP Secret Manager (~1 hour of work, not blocking deploy)
  • Bearer token at /etc/caddy/brain_bearer.txt (root:caddy, mode 640)
  • OAuth tokens in /var/lib/iexdg-brain/oauth.db (iexdg only, mode 700)
The honest gap  Gate 7 (Secret Manager migration) is still open. If a copy of the VM disk is leaked, the API keys in /etc/default/iexdg-mcp are readable. Migrating to Secret Manager closes this · the file becomes a placeholder, secrets resolve at process start via Application Default Credentials. Not blocking the OAuth ship tonight, but worth scheduling for the May sprint.

Backup and disaster recovery

RPO 24 hours · RTO 30 minutes · honest about current gaps

What is backed up today

Source codeGit on Robert's Mac · pushed to GitHub on demand · canonical local files in /Documents/Belay/IEXDG/
RAG knowledge dbSQLite at /opt/iexdg-mcp/rag/iexdg_knowledge.db · rebuildable from Notion + content corpus
Notion dataLives in Notion's own infrastructure · they handle backup and restore
Brand corrections logNotion · same as above
CaddyfileLocal in /Documents/Belay/IEXDG/vm_deploy/Caddyfile + timestamped backups on the VM
Secrets/etc/default/iexdg-mcp · NOT auto-backed-up · Robert has them in 1Password
VM disk snapshotNOT yet automated · planned for May sprint

Recommended snapshot policy (next sprint)

gcloud compute resource-policies create snapshot-schedule iexdg-weekly \
    --description "Weekly snapshot of iexdg-nexus-vm" \
    --max-retention-days=30 \
    --start-time=05:00 \
    --weekly-schedule=Sunday \
    --on-source-disk-delete=keep-auto-snapshots \
    --region=us-east4

gcloud compute disks add-resource-policies iexdg-nexus-vm \
    --resource-policies=iexdg-weekly \
    --zone=us-east4-b

Cost: ~$0.026/GB/month for snapshot storage. 10 GB disk × 4 weeks retention = $1/mo. Negligible.

Recovery procedure if the VM dies

  1. Identify latest snapshot: gcloud compute snapshots list --filter='sourceDisk:iexdg-nexus-vm'
  2. Create disk from snapshot: gcloud compute disks create iexdg-nexus-vm-restored --source-snapshot=<snapshot-name> --zone=us-east4-b
  3. Boot a new VM with that disk attached
  4. Re-attach the static IP to the new VM
  5. Verify Caddy auto-renews TLS, services come up, /api/health returns 200
  6. Estimated total time · 30 minutes if Robert is at the keyboard

📊Monitoring and alerting

Self-healing first, alerting second

Health worker (every 5 minutes)

The iexdg-health-check.timer fires every 5 minutes and runs workers/health_check.py with 7 checks:

  1. caddy responsive on :80
  2. iexdg-mcp.service active
  3. iexdg-api.service active
  4. /api/health returns 200 within 10 seconds
  5. Disk usage below 85%
  6. Memory available above 200 MB
  7. TLS cert expires more than 7 days from now

Any failure triggers systemctl restart on the affected service via a sudoers drop-in. If restart fails twice in 15 minutes, the worker writes a notice to /var/log/iexdg-mcp/health.alerts.

Public health endpoint

Anyone can hit https://brain.iexdg.com/api/health with no auth and get a JSON response showing all four services' liveness. This is what the dashboard reads, what the health worker reads, and what an external uptime monitor (Robert's UptimeRobot, future) reads.

{"ok":true,"service":"iexdg-api","ts":"2026-04-27T07:29:18Z","notion_configured":true,"version":"0.1.0"}

Future · alerts to Slack and email

When the May sprint adds Cloud Monitoring, the health-alerts log will be tail-piped to Cloud Pub/Sub which fans out to a Slack webhook and an email to dovewebconsulting@gmail.com. RPO 5 minutes for any service crash. Cost: $0 within Cloud Monitoring's free tier.

👥Onboarding and offboarding admins

Per Nexus Turnkey Gate 20

Onboarding a new admin (e.g. junior consultant)

  1. DNicole or Robert grants IAM role roles/compute.osLogin on the project
  2. New admin runs gcloud auth login with their Google account
  3. SSH access: gcloud compute ssh iexdg-nexus-vm --zone=us-east4-b
  4. Their public key is auto-injected into instance metadata · no manual key file copy
  5. If they need sudo: add to the iexdg-admins Linux group on the VM (currently only Robert)
  6. Document their email, their role, and their access end date in the IAM Audit row

💥Failure modes and recovery

What can go wrong, what we do
ModeSymptomDetectionRecovery
F1 · VM downbrain.iexdg.com not reachableHealth worker every 5 min · external uptime pingRestore from latest snapshot · 30 min RTO
F2 · TLS cert expiredBrowser cert warningHealth worker checks 7-day expiry bufferCaddy auto-renews · manual fallback caddy reload
F3 · Caddyfile syntax errorCaddy fails to reload, Caddyfile.bak-* still loadedcaddy validate before swap · fail-safe rollback in deploy scriptRevert to backup · cp Caddyfile.bak-* Caddyfile && systemctl reload caddy
F4 · OAuth provider outageGoogle sign-in fails for Claude Desktop usersManual report from DNicole or external monitorBearer route on /mcp-bearer still serves cron, manual users fall back to Path 2 installer
F5 · Disk fullService writes fail, /var/log fillsHealth worker disk-usage gate at 85%Logrotate already configured · manual cleanup of /var/log/iexdg-mcp/*.log.* if persistent
F6 · GCP us-east4 outageWhole region offlineExternal uptime pingCross-region snapshot (planned May) restores in us-central1 · manual DNS update at Squarespace
F7 · API key compromiseAnomalous activity in GHL or Gmail logsManual review · future Cloud Anomaly DetectionRotate the affected key in /etc/default/iexdg-mcp · restart affected service
F8 · Cron quota exhausted (e.g. YouTube)Daily content drop failsHealth alerts log · daily content drop email failureQuota request to Google · or back off polling frequency
F9 · ubuntu-2404-lts image renamedVM rebuild fails because image family does not existBuild error during snapshot restoreUse ubuntu-2204-lts for stability · or check gcloud compute images list --family first (per BB F9 lesson)

📖Glossary

Plain-language definitions for terms in this doc
VM
Virtual machine. A computer that does not physically exist, runs as a slice of a larger Google Cloud server. brain.iexdg.com runs on one of these.
e2-small
Google Cloud's name for the smallest sensible VM size, with 2 CPU cores that can burst higher and 2 GB of memory. About $14 a month.
Caddy
A web server. Sits in front of all our internal services, handles HTTPS, routes incoming requests to the right backend.
FastMCP
A Python library that turns a set of functions into an MCP server. The 33 tools Claude can call live inside our FastMCP server.
MCP
Model Context Protocol. The new standard way for Claude to call functions outside its own model. Anthropic's spec.
OAuth
An identity protocol where you sign in with one account (Google, Microsoft) and that account vouches for you to a separate service. The Apr 27 build adds OAuth so Claude Desktop can authenticate via Google sign-in.
Bearer token
A long random string that proves "I have permission to call this." Older method, now legacy on brain.iexdg.com (kept for cron only).
RAG
Retrieval Augmented Generation. The brain's searchable knowledge base of DNicole's writing, brand standards, and prior decisions. 10,601 chunks.
FedRAMP
A US federal government cloud security standard. Google Cloud is FedRAMP authorized, which means our VM inherits enough compliance posture to satisfy government client questionnaires.
CMMC
Cybersecurity Maturity Model Certification. Required for defense-adjacent work. Level 1 is automatic on GCP. Level 2 is reachable.
Secret Manager
Google Cloud's encrypted vault for API keys and OAuth secrets. Gate 7 of the Nexus turnkey playbook is to migrate our keys into it. Currently open.
DCR
Dynamic Client Registration (RFC 7591). The OAuth feature that lets Claude Desktop auto-create its own OAuth client without manual setup per user. Mandatory for the Custom Connector UI.
PKCE
Proof Key for Code Exchange. A small extra step in the OAuth flow that prevents an attacker who intercepts the auth code from using it. Mandatory in OAuth 2.1.
RPO
Recovery Point Objective. The maximum acceptable amount of data loss measured in time. Our target is 24 hours, achievable with weekly snapshots when Gate 8 closes.
RTO
Recovery Time Objective. The maximum acceptable downtime after a failure. Our target is 30 minutes for full VM rebuild.