Deep Research (Exa MCP)
/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
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_KEYset in the shell environment.- Exa MCP server registered with the
claude mcpCLI (writes to~/.claude.json). - Node + npx available on
PATH(the MCP server runs vianpx -y exa-mcp-server).
Setup
- Install this module via the CCGM installer (
./start.sh) and pick thefullpreset, or adddeepresearchexplicitly. - Set
EXA_API_KEYin your shell:echo 'export EXA_API_KEY=your_key_here' >> ~/.zshrc source ~/.zshrc - Register the Exa MCP server (note the
--before the server name; without it the CLI parsesexaas a value to--env):claude mcp add --scope user --env EXA_API_KEY="$EXA_API_KEY" -- exa npx -y exa-mcp-server - Restart Claude Code so the MCP server loads.
- Verify with
claude mcp get exa- expectStatus: ✓ Connected. In a fresh Claude Code session, theweb_search_exatool (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(expectStatus: ✓ Connected). If it's not registered, run theclaude mcp addcommand from Setup. ConfirmEXA_API_KEYis set in the shell that started Claude Code, and that you restarted Claude Code after the change. - Stale
~/.claude/mcp.jsonfrom old CCGM docs. Pre-#427 docs told you to hand-edit~/.claude/mcp.json, but current Claude Code reads~/.claude.json(managed by theclaude mcpCLI). Runbash lib/mcp-migrate.shfrom 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 liteto confirm the path works, then revise the topic. exa-mcp-serverinstall fails on first run.npx -ydownloads on first invocation. Confirmnodeandnpmare onPATH. 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:
yesOptions:
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.
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"