Start Here
Everything you need to set up and run Apollo from scratch — in about 20 minutes.
1. Prerequisites
You need an orchestrator CLI (one of two options), a research engine, and an adversary for the cross-lab audit. Both CLI orchestrators authenticate via subscription — no API key plumbing. Only Gemini Deep Research and paid-API adversary modes are billed per call.
- • Codex CLI + ChatGPT Pro/Max (default)
- • Claude Code CLI + Claude Pro/Max
- • Toggle via UI dropdown or APOLLO_ORCHESTRATOR_RUNTIME
- • $0 marginal cost under either subscription
- • Gemini API key with billing enabled
- • For Deep Research / Deep Research Max
- • Paid tier required (~$1–5/research call)
- • auto — opposite CLI of your orchestrator (default, $0)
- • claude_cli · codex_cli — explicit CLI
- • anthropic_api · openai — paid API (~$0.30–1.00 / Tier 1)
- • Default ships with $0 API cost via the auto mode
- ✓ Firebase project (free tier — separate from production ETCOS for v0)
- ✓ Python 3.11+ and node.js ≥18 installed (Claude CLI needs ≥18; auto-discovered from ~/.nvm if system Node is older)
- ✓ Whichever CLI you chose authenticated: codex login or claude login (or both if you want to use auto adversary)
- ✓ Optional: Exa API key (free tier — used as fallback research engine)
2. Setup steps
# From the Apollo repo root
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Copy the template and fill in your API keys:
cp .env.example .env # Then open .env and set the orchestrator + adversary: APOLLO_ORCHESTRATOR_RUNTIME=codex # or "claude" CROSS_LAB_PROVIDER=claude_cli # or auto / codex_cli / anthropic_api / openai # Research engine (required for autonomous deep research): GEMINI_API_KEY=AIza... EXA_API_KEY=... # optional fallback # Only set these if your adversary is anthropic_api or openai: ANTHROPIC_API_KEY=sk-ant-... OPENAI_API_KEY=sk-... # ETCOS publish target (keyless — no service-account file): FIREBASE_PROJECT_ID=etc-pinnacle-os
You don't drop any Firebase key. Opportunities publish under your own @etcorp.ca identity through the publishOpportunity Cloud Function. Locally, the publisher falls back to Application Default Credentials:
gcloud auth application-default login # one-time, keyless ADC
ETC's org blocks service-account key creation, so there are no JSON keys to manage. The Cloud Function enforces the @etcorp.ca check and the composite ≥ 27 gate server-side.
pytest # expect 254 tests passing
python orchestrator/main.py --help
🎯 3. Your first cycle
Run a complete opportunity-research cycle end-to-end. This takes ~10–30 minutes total (Gemini Deep Research is the longest step).
-
Step 1 Plan the cycle
python orchestrator/main.py plan-cycle --quarter 2026-Q2
Apollo picks 3–5 avenue-vertical combinations to research, respecting rotation and your GM priorities. Output: cycles/2026-Q2/avenues-selected.md.
-
Step 2 Research one avenue
python orchestrator/main.py research \ --research-id AR-001 \ --avenue "M&A / Strategic Acquisition" \ --vertical "Critical Minerals & Mining Automation"Gemini Deep Research runs a full autonomous research loop. Apollo decomposes the report into candidate opportunities. Output: cycles/2026-Q2/AR-001-*/findings.md + candidate stubs.
-
Step 3 Score a candidate
python orchestrator/main.py score --opp-id OPP-001
Applies the 9-dimension rubric verbatim. Computes composite, tier, and matrix quadrant. Output: opportunities/OPP-001/backlog-row.json.
-
Step 4 Independent review
Anthropic Claude audits the synthesis (called automatically during scoring for Tier 1 candidates). Output: opportunities/OPP-001/reviews/anthropic-review.md.
-
Step 5 Approve and publish
# Read the brief, then mark as approved: touch opportunities/OPP-001/APPROVED # Push to ETCOS (Firestore): python orchestrator/main.py publish --opp-id OPP-001
Apollo verifies all gates pass, writes to ETCOS, drops a receipt back into the run folder. Cannot publish without the APPROVED file and Evidence Quality ≥ 2.
In production, you run plan-cycle once a quarter, research + score as candidates surface, and prep-review monthly before your GM meeting. Target: 1–2 Phase 1 entries approved per month.
What is Apollo?
An AI agent system that executes Phase 0 of ETC's Opportunity-to-Development Readiness (ODR) process — at scale, with structure, and with checks-and-balances built in.
- ① Identifies new opportunity avenues from a structured framework of 28+ avenues across 7 categories.
- ② Researches selected avenues using best-in-class autonomous research (Google Deep Research) — producing comparative assessments with citations.
- ③ Scores candidates using a 9-dimension question-based rubric.
- ④ Audits its own work with an independent second-lab review (Anthropic Claude).
- ⑤ Prioritizes candidates and prepares a GM-ready monthly pipeline review.
- ⑥ Publishes approved opportunities to ETCOS — but only with human approval.
- ✗ Validate that a customer will actually buy.
- ✗ Replace SME domain judgment.
- ✗ Guarantee accuracy of market estimates.
- ✗ Advance opportunities to Phase 1 on AI alone — every Phase 1 entry requires a confirming human signal (customer conversation, advisor validation, internal SME endorsement, or documented external trigger).
- ✗ Write to ETCOS without an
APPROVEDfile in the run folder.
Each model's blind spots get checked by a different model family. With the runtime selector, every Tier 1 brief gets a genuine cross-vendor audit under subscription auth — no API credits required for the default flow.
Architecture
Five layers, file-system-as-state, MCP servers as the boundary to external systems.
Python dispatcher
runtime = codex / claude"] B -->|loads| C["Skills Layer
8 skills
opportunity-brief · avenue-researcher
scoring-rubric-applier · cycle-planner
evidence-validator · backlog-intake
pipeline-review-prep · livestock-tech"] B -->|spawns| R1[Codex CLI subprocess
ChatGPT Pro/Max] B -->|spawns| R2[Claude Code CLI subprocess
Claude Pro/Max] B -->|calls| D["MCP Tool Layer
14 servers
6 local · 8 Wave-1 upstream"] D --> L["LOCAL (6)
FastMCP Python"] L --> L1[etcos-publisher] L --> L2["cross-lab-reviewer
4 providers · default auto"] L --> L3[etcos-reader] L --> L4[evidence-validator] L --> L5[citation-validator] L --> L6[etc-memory] D --> W["WAVE-1 (8)
Public Data Tier · free"] W --> W1["gemini-deep-research
Google · paid"] W --> W2["exa
web search"] W --> W3["tavily
search fallback"] W --> W4["paper-search-mcp
arXiv · PubMed"] W --> W5["patent-connector
USPTO · EPO"] W --> W6["edgartools
SEC EDGAR"] W --> W7["octagon-sec
SEC analysis"] W --> W8["gov-ca-mcp
open.canada.ca"] C --> F[Data / Artifact Layer
File system] F --> G1[memory/
long-lived: avenues,
rubric, capabilities] F --> G2[cycles/
per-cycle research] F --> G3[opportunities/
per-OPP-ID briefs & scores] L1 -->|approved only| H[(ETCOS Firestore)] L2 -.->|claude_cli / codex_cli
subscription · $0| R3[Opposite CLI subprocess] L2 -.->|anthropic_api / openai
HTTPS · paid| I[(Paid API)] W1 -.->|HTTPS| J[(Gemini API)] style A fill:#eff6ff,stroke:#3b82f6,color:#0f172a style B fill:#1e293b,stroke:#0f172a,color:#fff style C fill:#f1f5f9,stroke:#475569,color:#0f172a style D fill:#f1f5f9,stroke:#475569,color:#0f172a style L fill:#ecfdf5,stroke:#10b981,color:#0f172a style W fill:#fef3c7,stroke:#f59e0b,color:#0f172a style F fill:#f1f5f9,stroke:#475569,color:#0f172a style R1 fill:#ecfdf5,stroke:#10b981,color:#0f172a style R2 fill:#ede9fe,stroke:#8b5cf6,color:#0f172a style R3 fill:#fef3c7,stroke:#f59e0b,color:#0f172a style H fill:#fef3c7,stroke:#f59e0b,color:#0f172a style I fill:#ede9fe,stroke:#8b5cf6,color:#0f172a style J fill:#fef2f2,stroke:#f43f5e,color:#0f172a
Thin Python dispatcher. Loads the skill prompt and routes to either codex exec --json (default) or claude -p --output-format json based on APOLLO_ORCHESTRATOR_RUNTIME or the workbench UI dropdown. Both paths use subscription auth — zero marginal cost. See DEC-008 in coordination/DECISIONS.md.
Versioned, portable markdown specs. Same skill files work in Codex CLI and Claude Code. The "muscle memory" of the agent.
FastMCP Python subprocesses. Each exposes a narrow set of tools. Stdio for local, swappable to HTTPS for Managed Agents in Phase 2 — no rewrite.
Every run gets a folder. Briefs are markdown, scores are JSON, decisions are tracked in git. Auditable, diffable, human-readable.
How a run works
From "I want to investigate critical minerals" to a scored, audited, approved opportunity in ETCOS.
or anthropic_api / openai ADV-->>O: structured review (agreements/disagreements) end O-->>U: backlog-row.json + review U->>U: read brief, add human signal, touch APPROVED U->>O: publish OPP-001 O->>E: write opportunity (gated) E-->>O: doc ID O-->>U: etcos-receipt.json
Steps 1–3, 5–6 (planning, scoring, synthesis, default cross-lab audit) — Codex or Claude CLI under your subscription. Both directions of the cross-lab review are subscription-only when adversary = auto.
Step 4 (Gemini Deep Research) — ~$1–5 per avenue.
Step 6 only if you flip the adversary to anthropic_api or openai — ~$0.30–1.00 per Tier 1 review. Default auto mode skips this entirely.
Capabilities at a glance
What Apollo can do for ETC's strategic growth function.
Honors the WI's "no category unexamined for >2 quarters" rule. Recommends 3–5 avenue-vertical pairs per cycle with rationale.
Gemini Deep Research runs dozens of search iterations per avenue. Replaces 30–50 manual orchestration turns.
Applies the rubric verbatim. Computes composite (9–45), tier (1/2/3/Below), matrix quadrant (Pursue / Invest to Build / Opportunistic / Park).
Tier 1 candidates get an independent review from a different model family (Anthropic vs. OpenAI/Google).
Every factual claim has a hyperlinked source with accessed date. The citation-validator MCP checks they resolve.
Auto-generates a 5–10 minute read with Phase 1 recommendations, Tier 2 discussion items, and reactivation candidates.
Cannot publish without APPROVED file. Cannot advance to Phase 1 if Evidence Quality = 1.
Tracks validated signals and dead-ends across cycles. Never re-pitches a hypothesis that has been parked with rationale.
Generic opportunity-brief skill with vertical specializations (livestock, mining, etc.) layered on top. Add new verticals without rewriting the core.
The 8 Skills
Modular markdown specs that define what the agent does in each step.
🎯
opportunity-brief
Generic, vertical-agnostic · v0.1.0 · KEY DELIVERABLE
▶
Produces a structured opportunity brief for any target vertical, parameterized on target_vertical, originating_avenue, geography, depth (T1/T2/T3).
Output sections: Problem Statement · Why ETC Relevant · Market Map · Pain Points · Pricing & WTP · Software/Channel Partners · Incentives & Funding · Regulatory Overview · ETC Entry Options · Evidence · Open Questions · Sources.
🐄
livestock-tech-opportunity-brief
Specialization · v0.2.0
▶
Inherits from opportunity-brief. Adds livestock-specific guidance: subsystem decomposition, Prairie geography weighting, four practical-bucket Market Map cuts, CCIA/ATQ/ISED checklist, workbook tab convention.
Reference output: Reference_Documents/non_dairy_livestock_opportunity_scoring (5).xlsx.
🔬
avenue-researcher
v0.2.0
▶
Primary path: invokes gemini-deep-research MCP for one autonomous deep research call per avenue.
Fallback: if GEMINI_API_KEY not set, falls back to Exa + Codex tool-loop. Outputs findings.md + per-candidate stubs.
📊
scoring-rubric-applier
v0.1.0
▶
Applies the 9-dimension rubric verbatim from memory/scoring-rubric.json.
Computes composite/tier/quadrant via orchestrator/validators.py. Calls evidence-validator MCP before claiming Phase 1 eligibility.
📅
cycle-planner
v0.1.0
▶
Honors category-rotation hygiene, GM priorities, validated-signals carry-forward, dead-end exclusion. Outputs draft cycles/<Q>/avenues-selected.md for human review.
🔍
evidence-validator (skill)
v0.1.0
▶
Orchestrates the evidence-validator and citation-validator MCPs. Writes verdict back into the brief's Evidence section. Converts weak/unsupported claims into Phase 1 validation questions.
📥
backlog-intake
v0.1.0
▶
Allocates OPP-IDs via orchestrator.ids.next_opp_id(). Lifts brief content into the canonical schema. Initializes scores at 1 (D8 = 1 floor) until scoring runs.
📋
pipeline-review-prep
v0.1.0
▶
GM-readable monthly review pack (5–10 minute read). Buckets: recommended Phase 1 entries · Tier 1 awaiting approval · Tier 2 worth discussing · Phase 1 Active checks · reactivation candidates · recommended rejections · rolling counts · next-cycle preview.
The 14 MCP Servers
6 local FastMCP servers (ETC-specific boundaries + governance) + 8 Wave-1 upstream MCPs (Public Data Tier — free except Gemini). Each owns a narrow, single-purpose tool surface.
Wave-1 integration was approved in DEC-006 and committed 2026-05-12. All 14 are registered in .claude/settings.json and .codex/config.toml and probe-verified live.
LOCAL · 6 Built in this repo
| Server | Purpose | External system | Tools | Tests |
|---|---|---|---|---|
| etcos-publisher v0.2.0 | Gated writes to ETCOS. Enforces APPROVED file + D8 ≥ 2 + schema valid. | Firestore | 4 | 20/20 ✓ |
| cross-lab-reviewer v0.3.0 | Independent audit. 4 providers: claude_cli · codex_cli · anthropic_api · openai. auto = opposite CLI of orchestrator (DEC-008). |
CLI sub or Paid API |
2 | 25/25 ✓ |
| etcos-reader v0.1.0 | Read-only ETCOS queries — duplicate detection, Phase-1-Active list, recent opportunities. | Firestore | 7 | 14/14 ✓ |
| evidence-validator v0.1.0 | Pure-Python gate enforcement: Phase-1 eligibility, publishability, brief completeness. | none | 4 | 17/17 ✓ |
| citation-validator v0.1.0 | URL fetch + heuristic claim-grounding checks. | HTTP | 3 | 19/19 ✓ |
| etc-memory v0.1.0 | Whitelisted reads + typed appends to memory/*.md (validated signals, dead-ends, capabilities). |
filesystem | 5 | 18/18 ✓ |
WAVE-1 · 8 Public Data Tier (upstream, DEC-006)
| Server | Purpose · used by | Package | Cost | Status |
|---|---|---|---|---|
| gemini-deep-research | Primary deep-research engine. Used by avenue-researcher Path A. |
gemini-deep-research-mcp@0.1.3 | $1–5 / call | callable |
| exa | Semantic web search. Path-B research fallback + named-entity lookups. | exa-mcp-server (npx) | free 1k/mo | callable |
| tavily | Search hedge when Exa rate-limits. | tavily-mcp@0.2.19 | free 1k/mo | callable |
| paper-search-mcp | Academic research — arXiv, PubMed, Semantic Scholar, OpenAlex, bioRxiv. | paper-search-mcp@0.1.3 | free | callable |
| patent-connector | Patent landscape — USPTO (EPO is a Wave-2 follow-up). | patent-mcp-server@0.9.3 | free | callable |
| edgartools | SEC EDGAR structured access — 10-K, 10-Q, 8-K, Form 4, 13F, DEF 14A. | sec-edgar-mcp@1.0.8 | free | callable |
| octagon-sec | Agentic SEC analysis across 8,000+ public companies. | octagon-sec-filings-mcp@1.0.0 | free tier | callable |
| gov-ca-mcp | Open Government Canada CKAN — Stats Canada, IRAP/SIF/NSERC, ISC, geological. 250k+ datasets. | ckan-mcp-server@0.0.1 | free | callable |
113 MCP + 65 orchestrator/skill + 70 runtime-selector & workbench. v0 baseline 175 → 254 today. E2E auto-skips when secrets missing.
Every local MCP supports both transports via --transport. Migration to Managed Agents is a deployment change, not a rewrite.
etc-sharepoint, etc-crm, regulatory wrappers (CFIA, ISED, FCC, NRCan), Apify scrapers for PitchBook / Crunchbase. Out of Phase-1 scope by design.
Rafael's PATH has a broken Node v14.15.3 ahead of v25.9.0 — all npx-based MCPs (exa, gemini-deep-research, tavily, octagon-sec) fail at launch until /usr/local/bin/node is reprioritized behind /opt/homebrew/bin/node. Documented in mcp-servers/WAVE_1_DECISIONS.md §Environment.
Browse MCP docs in-page
Click any card to read its README right here — no file-system spelunking needed.
Local MCP READMEs are editable (save writes directly to disk; recoverable via git restore). Wave-1 entries show registration metadata only.
Governance & Gates
Five hard rules enforced in code, not prompts. The agent literally cannot bypass them.
An opportunity cannot move from Phase 0 to Phase 1 with Evidence Quality (D8) = 1. Every Phase 1 entry requires at least one human signal: customer conversation, advisor validation, internal SME endorsement, or documented external trigger.
Tier 3 and below do not advance to Phase 1, regardless of any other signal.
The etcos-publisher MCP refuses to publish unless the run folder contains an APPROVED file touched by a human.
Every brief must include the 12 canonical sections (Problem Statement, Why ETC Relevant, Market Map, Pain Points, Pricing & WTP, Software/Channel Partners, Incentives & Funding, Regulatory Overview, ETC Entry Options, Evidence, Open Questions, Sources). Sections may be empty if not applicable, but headings must be present for downstream parsing.
Especially for willingness-to-pay, partner attractiveness, and regulatory interpretation. Every factual claim has a hyperlinked source with accessed date.
Status — live & operational
Apollo is deployed and in use. Opportunities are published and viewable, and the agent runs locally for research.
Last updated 2026-06-16.
Live now
- ✓ Deployed at apollo-etcos.web.app with Microsoft Entra SSO (@etcorp.ca only).
- ✓ Opportunities publish & are viewable — the pipeline reads live from ETCOS Firestore.
- ✓ User-identity publishing — each user publishes under their own @etcorp.ca account via the
publishOpportunityCloud Function. No service-account keys. - ✓ Keyless CI/CD — merge to
mainruns 254 tests and auto-deploys to production via Workload Identity Federation. - ✓ 14 MCPs (6 local + 8 Wave-1) · 8 skills · runtime-selectable Codex/Claude orchestration.
- ✓ Local researcher operational — the orchestrator CLI + workbench run on a coworker's machine.
What's next
- → Onboard more users. No Google Cloud access needed — install the harness, add API keys, sign in with Microsoft to publish. (Onboarding guide in progress.)
- → Run real research cycles to populate the pipeline with live opportunities.
- → Attach the apollo.etcos.ca custom domain (currently served at apollo-etcos.web.app).
- → Move the repo to the ETCorp org when production-hardened, enabling branch protection.
Managed Agents deployment · remote HTTPS MCP hosting · ETC SharePoint & CRM connectors · regulatory wrappers (CFIA, ISED, NRCan, FCC) · Apify scrapers (PitchBook, Crunchbase) · wiring all 28 avenues · patent EPO coverage. Scope choices for the next iteration, not blockers.
Commands
Seven CLI subcommands plus a local workbench UI. That's the entire operator surface.
Local workbench UI (complement to the CLI)
FastAPI BFF + prototype HTML at prototypes/ui/06-analyst-workbench.html · 13 endpoints
PORT=8000 apollo-web # or: python -m apollo.web.server open http://localhost:8000/06-analyst-workbench.html
- · Pipeline view + opportunity detail (briefs + scores + citations)
- · Runtime selector (Codex / Claude CLI orchestrator)
- · Adversary selector (auto / claude_cli / codex_cli / anthropic_api / openai)
- · "Ask Apollo" side-rail deepening threads (advisory)
- · KPIs · rubric anchors · avenue framework · cycle history
- · SSE file watcher for live updates from CLI runs
- · Kicking off a new research run (POST /api/research not yet wired)
- · Scoring a candidate (POST /api/score not yet wired)
- · Creating the APPROVED file (manual
touch) - · Publishing to ETCOS
Cost
The default (orchestrator CLI + auto adversary) runs almost entirely on your existing CLI subscriptions — only Gemini Deep Research is paid per call.
auto adversary (opposite CLI)- Codex / Claude CLI orchestration$0
- Opposite-CLI cross-lab review$0
- Gemini Deep Research (1 call)$1–5
- Exa, Firebase, HTTP$0
Optional paid-API audit modes (anthropic_api, openai) add ~$0.30–1.00 per Tier 1 review on top.
- 3 cycles/month (low)$0.30–$1.50
- 6 cycles/month (mid)$0.60–$3
- 10 cycles/month (heavy)$1–$5
Monthly caps configured in .env: GEMINI_MONTHLY_CAP_USD=100, ANTHROPIC_MONTHLY_CAP_USD=50, OPENAI_MONTHLY_CAP_USD=50. Alerts at $30.
FAQ
Do I need API keys for all three labs? ▶
No — that was true at the v0 cut, but the runtime selector (DEC-008, 2026-05-15) changed this. Today you only need:
(1) one orchestrator CLI authenticated via codex login or claude login;
(2) the opposite CLI if you want the default auto adversary mode (also subscription auth, $0);
(3) GEMINI_API_KEY for autonomous deep research (paid; falls back to Exa+CLI if unset, but quality drops).
The ANTHROPIC_API_KEY and OPENAI_API_KEY slots are only required if you flip the adversary to the corresponding paid-API mode.
Can I run this without ETCOS / Firebase set up? ▶
Yes — everything except publish works without Firebase. You'll still get briefs, scores, and reviews on disk in the run folders. Set up Firebase only when you're ready to flow approved opportunities into ETCOS.
What if the agent gets something wrong? ▶
The architecture assumes it will. That's why every brief has citations, every Tier 1 candidate gets cross-lab review, and the human approval gate is non-bypassable. The agent is breadth + speed + structure; you are the truth-test.
How do I add a new vertical specialization? ▶
Create skills/<your-vertical>-opportunity-brief/SKILL.md following the pattern in the livestock skill. Inherit from opportunity-brief. Layer on your vertical's source priorities, regulatory framework, and decomposition. Symlink into .claude/skills/ and .codex/skills/.
When do I move to Managed Agents? ▶
When v0 runs reliably on your laptop and you want: (a) hours-long autonomous runs that survive disconnections, (b) sandboxed execution per session, (c) cross-session learning ("dreaming"). The migration is a deployment change — all skills, MCPs, and contracts stay the same.
What's in scope for v0 vs. Phase 2? ▶
v0 (now): single-laptop run, 7 custom MCPs + 2 upstream, 8 skills, full end-to-end cycle on one avenue/vertical. Phase 2: Managed Agents deployment, internal data MCPs (SharePoint, CRM), regulatory-agency wrappers (CFIA, ISED, FCC, NRCan), additional vertical specializations.