Deep Research (Exa MCP)

commands no always-loaded rules -- loads on demand updated 2026-08-04

/deepresearch - Multi-query semantic research using the Exa MCP server. Claude generates diverse queries from your topic, fans them out via parallel Exa MCP tool calls, and synthesizes a structured research.md from full page contents. Requires the Exa MCP server registered via `claude mcp add` and an Exa API key.

Tags

  • commands
  • research
  • web-search
  • exa
  • mcp
  • external-api

README

Deep Research (Exa MCP)

Multi-query semantic research bundled as a CCGM module. Claude generates diverse queries from your topic, fans them out via parallel Exa MCP tool calls, and synthesizes a structured research.md from the full page contents Exa returns.

Supersedes the standalone lem-deepresearch repo (Ollama + SearXNG pipeline). The local pipeline degraded over time as SearXNG's scraped engines (Google, DuckDuckGo, Brave) hit CAPTCHAs and rate limits. Exa's neural search returns reliable, semantically-relevant results without scraping.

How it works

Topic -> Claude generates N diverse queries
      -> Claude issues N parallel Exa MCP tool calls (web_search_exa, research_paper_search_exa, etc.)
      -> Exa returns top-K results per query with full page text
      -> Claude synthesizes research.md from the aggregated results
Step Where Notes
Query generation Claude (the skill) No separate model required
Web search + content fetch Exa MCP server (web_search_exa) Single tool call per query, parallel fan-out
Synthesis Claude (the skill) Reads full page contents, writes structured research.md

Depth presets

Preset Queries Results / query Best for
Lite 3 5 Quick scoping
Standard 5 5 Most research tasks (default)
Full 7 5 New domains, comparative research

Prerequisites

  • Exa account. Sign up at https://exa.ai.
    • Free tier: 1000 searches/mo
    • Pro tier: ~$10/mo for 10k searches
  • EXA_API_KEY set in the shell environment.
  • Exa MCP server registered with the claude mcp CLI (writes to ~/.claude.json).
  • Node + npx available on PATH (the MCP server runs via npx -y exa-mcp-server).

Setup

  1. Install this module via the CCGM installer (./start.sh) and pick the full preset, or add deepresearch explicitly.
  2. Set EXA_API_KEY in your shell:
    echo 'export EXA_API_KEY=your_key_here' >> ~/.zshrc
    source ~/.zshrc
    
  3. Register the Exa MCP server (note the -- before the server name; without it the CLI parses exa as a value to --env):
    claude mcp add --scope user --env EXA_API_KEY="$EXA_API_KEY" -- exa npx -y exa-mcp-server
    
  4. Restart Claude Code so the MCP server loads.
  5. Verify with claude mcp get exa - expect Status: ✓ Connected. In a fresh Claude Code session, the web_search_exa tool (and friends) should be callable.

Manual Installation

Replaces step 1 above if you are not using the CCGM installer. Steps 2-5 still apply — the command is useless without the Exa MCP server registered.

mkdir -p ~/.claude/commands
cp commands/deepresearch.md ~/.claude/commands/deepresearch.md

Usage

/deepresearch "dark mode browser extensions"
/deepresearch "SaaS pricing strategies" --depth full
/deepresearch "React vs Vue" --depth lite --output ~/notes/react-vue.md

The skill writes to ~/code/docs/research/{slug}/research.md by default, or to the path passed via --output.

Cost estimate

At 100 research runs/month with --depth standard (5 queries × 5 results = 25 search calls), expected cost is ~$3-5/mo on the Pro tier. The free tier (1000 searches/mo) covers ~40 runs.

Why MCP rather than a CLI

The earlier draft of this module shipped a Python CLI that called the Exa REST API directly. The MCP architecture is strictly better for a Claude Code skill:

  • No shell-out, no Python venv dependency, no JSON-handshake between CLI and skill
  • Parallel fan-out is native (Claude issues N tool calls in one message)
  • Specialized Exa endpoints (papers, GitHub, companies, Wikipedia) are exposed as separate tools the skill can route to per topic-type
  • Auth flows through the MCP server's env block (registered via claude mcp add --env); no separate env-var checks in our code

Troubleshooting

  • Skill says "Exa MCP tools unavailable." The MCP server did not load. Verify with claude mcp get exa (expect Status: ✓ Connected). If it's not registered, run the claude mcp add command from Setup. Confirm EXA_API_KEY is set in the shell that started Claude Code, and that you restarted Claude Code after the change.
  • Stale ~/.claude/mcp.json from old CCGM docs. Pre-#427 docs told you to hand-edit ~/.claude/mcp.json, but current Claude Code reads ~/.claude.json (managed by the claude mcp CLI). Run bash lib/mcp-migrate.sh from the CCGM checkout to re-register every entry, or re-run ./start.sh (the installer migrates on update).
  • Tool call returns 401 / unauthorized. API key invalid or revoked. Generate a new one at https://exa.ai/dashboard, update your shell rc, restart Claude Code.
  • All queries return zero results. Topic may be too narrow or oddly phrased; try --depth lite to confirm the path works, then revise the topic.
  • exa-mcp-server install fails on first run. npx -y downloads on first invocation. Confirm node and npm are on PATH. Check network access.

Will install

Path Action Target Type
commands/deepresearch.md commands/deepresearch.md command

Dependencies

No dependencies.

Required by

No other module depends on this one.

Asks during install

  • /deepresearch needs the Exa MCP server (free tier: 1000 searches/mo at https://exa.ai). Step-by-step setup (Exa signup + `claude mcp add`): modules/deepresearch/README.md. Continue?

    Default: yes

    Options: yesno

Included in presets

Install this module

Agent prompt

Recommended for agent users -- hands the whole install off to your assistant.

Fetch https://cd23a9be.ccgm-site.pages.dev/modules/deepresearch.md and install this module into my Claude Code setup.

Native plugin marketplace

One command via the native plugin marketplace -- additive, does not merge settings.json.

claude plugin install deepresearch@ccgm

The marketplace path is additive, not a replacement: it installs commands, agents, and skills as native plugin components, but it does not perform the bash installer's deep settings.json merge, and it does not write the always-loaded global CLAUDE.md context. Rules are only injected via an opt-in SessionStart hook rather than being auto-loaded. Use the bash installer when those pieces matter to you.

Manual, per file

Full control -- copy exactly the files you want from the sections below.

Files

Files

command (1)

commands/deepresearch.md

---
description: Deep multi-query research using parallel Exa MCP tool calls
allowed-tools: Read, Write, Glob, Grep, AskUserQuestion
argument-hint: <topic> [--depth full|standard|lite] [--output <path>] [--plan-dir <path>] [--extend <prior-research-path>]
---

# /deepresearch - Deep Multi-Query Research (Exa MCP)

Generate diverse search queries from a topic, run them in parallel via the Exa MCP server, and synthesize the results (with full page contents, not snippets) into a structured `research.md`.

**Can be used:**
- Standalone: `/deepresearch "dark mode browser extensions"` writes to `~/code/docs/research/`
- From `/xplan` Phase 1
- From any skill that needs deep research

**Prerequisites:**
- Exa MCP server registered via the `claude mcp` CLI (writes to `~/.claude.json`). Register with:
  ```bash
  claude mcp add --scope user --env EXA_API_KEY="$EXA_API_KEY" -- exa npx -y exa-mcp-server
  ```
- `EXA_API_KEY` set in the shell environment (https://exa.ai - free tier covers 1000 searches/mo).
- Restart Claude Code after registering so the MCP server loads. Verify with `claude mcp get exa`.

If the Exa MCP tools (`web_search_exa` etc.) are not available in this session, stop immediately and tell the user how to set them up. Do not fall back to `/research` or `WebSearch` silently.

---

## Input

```
$ARGUMENTS
```

---

## Phase 0: Parse Arguments

Extract from `$ARGUMENTS`:
- **Topic** (required): the research subject
- **`--depth <preset>`**: `lite` (3 queries), `standard` (5 queries, default), or `full` (7 queries)
- **`--output <path>`**: custom output path for `research.md` (must end in `.md`)
- **`--plan-dir <path>`**: when called from `/xplan`, the plan directory; `research.md` is written there
- **`--repo <path>`**: (Optional) an existing repo to ground repo-specific facts against. When set, every repo fact MUST be read from a fetched, SHA-pinned source — see "Source Freshness" below. `/xplan` passes its Phase 0.4.0 anchor worktree path here, not a bare clone.
- **`--extend <path>`**: accepted for compatibility, gracefully ignored

If no topic is provided, use `AskUserQuestion` to ask what to research.

### Source Freshness (only when --repo is set)

A local working tree can lag `origin` by many commits or hold uncommitted WIP, so reading it as-is produces research grounded in stale facts. When `--repo <path>` is given:

1. **Prefer a pre-pinned anchor.** If the caller (e.g. `/xplan`) passed a `Verification anchor: <ref> @ <SHA>` in the prompt, treat that SHA as the source of truth and read repo facts from the path given (an anchor worktree). Do not re-fetch.
2. **Otherwise, pin it yourself.** Resolve the real default branch (`git -C <repo> rev-parse --abbrev-ref origin/HEAD`; fall back to `origin/main`), run `git -C <repo> fetch origin` once, and pin `ANCHOR=$(git -C <repo> rev-parse <origin-default>)`. Read repo facts via `git -C <repo> show <origin-default>:<path>` (or a temp `git worktree add --detach`), never a bare working-tree Read. If the repo has no remote, note "local-only, working tree used as-is" and proceed.
3. **Never mutate the user's clone** — no checkout, no HEAD move, no stash. Pin and read only.

This freshness rule is independent: `/deepresearch` enforces it even when invoked directly with `--repo`, not only when delegated from `/xplan`.

### Determine output path

```
if --plan-dir:    output = {plan-dir}/research.md
elif --output:    output = {output}
else:             slug = kebab-case(topic); mkdir -p ~/code/docs/research/{slug}; output = ~/code/docs/research/{slug}/research.md
```

---

## Phase 1: Determine Depth

If `--depth` was passed (e.g., from xplan), use it directly.

Otherwise, ask the user with `AskUserQuestion`:

> "What level of research should I run?"

| Option | Queries | Time | Best for |
|--------|---------|------|----------|
| Standard (recommended) | 5 | ~30s-1m | Most research tasks |
| Full | 7 | ~1-2m | New domains, comparative research |
| Lite | 3 | ~20s | Quick scoping |

---

## Phase 2: Generate Diverse Queries

Generate `N` diverse queries directly (where `N` is the depth count). Mix angles:
- A broad overview query
- A technical / how-it-works query
- A competitive / comparison query
- A practical / tutorial query
- A risk / pitfall query (`standard` and above)
- A pricing / business-model query (when commercial context matters)
- An academic / paper query (technical/research topics, `full` only)

Each query should be a self-contained sentence or noun phrase. Avoid overlong compound queries (>120 chars) - tighter queries return better results from Exa.

Hold these queries; pass each to the MCP search tool in the next phase.

---

## Phase 3: Run Parallel Exa MCP Searches

Issue **all `N` Exa MCP tool calls in a single assistant message** so they run concurrently. The expected tool name is `web_search_exa` (the default exposed by `exa-mcp-server`). Use `numResults: 5` per query.

For topic types where Exa exposes specialized tools, route accordingly:

| Topic shape | Tool to use | Notes |
|-------------|-------------|-------|
| General research | `web_search_exa` | Default for most queries |
| Academic / scientific | `research_paper_search_exa` | If `full` depth on a research-heavy topic, route 1-2 of the queries here |
| Open-source / dev tooling | `github_search_exa` | Optional supplement; do not replace `web_search_exa` |
| Specific company / product | `company_research_exa` | When the topic is a single named company |
| Encyclopedic background | `wikipedia_search_exa` | Optional - Exa already indexes Wikipedia; only use when you specifically need Wikipedia framing |

**If the Exa MCP tools are unavailable** in this session (the tools do not appear in the available tool list), STOP and tell the user the MCP server is not loaded. Reference the prerequisites above. Do not silently fall back.

For each result that comes back, you have:
- `url`, `title`, `text` (full page content), `publishedDate`, `score`

Aggregate the results in memory across queries.

---

## Phase 4: Synthesize research.md

Cross-reference claims across queries. Note contradictions. Weight by source quality (official docs > peer-reviewed > industry > blogs). Call out high-confidence findings explicitly.

Write the file at the resolved `output_path` using this exact structure.

**When `--repo` was set, research.md MUST open (before the title's content) with a verification-anchor line and a Verified Facts Log**, so downstream planning/review can trust every repo claim:

```markdown
**Verification anchor:** {repo} `{origin-default-ref}` @ `{ANCHOR-SHA}` (the local working tree was {N} commits behind; every repo fact below was read at this anchor, not the working tree).

## 0. Verified Facts Log (every load-bearing repo fact, anchored)

| # | Fact | Truth at anchor | Anchor (`{ref}:<file>:<line>`) |
|---|------|-----------------|--------------------------------|
| VF1 | ... | ... | ... |
```

Every load-bearing repo fact (a file exists, a function is named X, a decision is current/reversed, a dependency is present) gets a row anchored to `<file>:<line>` as read at the anchor — never asserted from memory or a stale Read. This is the pattern that prevents a plan from citing deleted code as present. For greenfield research (no `--repo`), omit the anchor line and Verified Facts Log — there is no repo to anchor against.

Then the standard structure:

```markdown
# Research: {topic}

## Executive Summary
{2-3 paragraphs synthesizing the key findings. Lead with the most important insight.
Note overall confidence based on source quality and corroboration.}

## Contextual Model
{The mental framework for thinking about this problem. Key principles that should guide decisions.}

## Problem Space
{Domain analysis, user pain points, jobs-to-be-done. What does this space look like?}

## Technical Landscape
{Architecture patterns, technology options, scalability considerations, relevant tools/libraries.}

## Competitive Landscape
{Existing solutions, feature gaps, differentiation opportunities, pricing patterns when relevant.}

## Key Insights
{Numbered list of the 5-10 most important findings:
1. **Finding title** - description. (Confidence: High/Medium/Low based on source count and quality)}

## Risk Register
| Risk | Severity | Mitigation |
|------|----------|------------|
{At least 3 rows covering technical, market, and execution risks}

## Sources
{Bulleted list of all source URLs deduplicated across queries. Group by credibility:
Official/Academic first, then Industry/News, then Blogs/Community.}
```

---

## Phase 5: Report

After writing `research.md`, report to the user:
- Output path
- Executive Summary (2-3 sentences)
- Key Insights list (numbered)
- Number of unique sources collected
- Approximate elapsed time

If standalone (not called from `/xplan`), suggest:
- "Run `/xplan` with this research to plan an implementation"