Instruction manual

dzhng/deep-research instruction manual

Small TypeScript standalone deep-research assistant that recursively generates search queries, processes Firecrawl results with an LLM, derives new research directions, and writes a sourced Markdown report; no native Claude Code integration is documented.

1. Purpose, scope, and relationship to Claude Code

Open Deep Research is a small TypeScript research assistant. It accepts a topic, asks follow-up questions, generates search-engine-result-page (SERP) queries, extracts findings from returned web content, and recursively follows promising directions. At the end, it writes a Markdown report with findings and sources. The README describes the design goal as a simple implementation of a deep-research agent, intended to remain under 500 lines of code so that it is easy to understand and extend.

Its main controls are **breadth**, which governs how widely it searches, and **depth**, which governs how many recursive rounds it performs. Searches and result processing can run concurrently. Firecrawl supplies web search and content extraction; an LLM generates queries, analyzes material, proposes new directions, and writes the report.

**Claude Code classification: unclassified.** The supplied first-party files do not mention Claude Code and do not document a Claude plugin, skill, hook, MCP server, installation path, or other Claude-specific mechanism. This repository is therefore documented only as a standalone Node.js application. It may use OpenAI-compatible model endpoints, but that fact does not establish a relationship to Claude Code.

Repository: `https://github.com/dzhng/deep-research`. The metadata identifies TypeScript as the primary language and `main` as the default branch.

2. Requirements and service choices

Use a Node.js environment. Although the README states this generally, `package.json` specifies the Node engine as `22.x`; Node 22 is therefore the source-supported version requirement. The normal hosted configuration needs a Firecrawl API key for search and page extraction and an OpenAI API key for the default `o3-mini` model path.

The application also documents alternative model arrangements. A Fireworks key makes it switch automatically to the DeepSeek R1 model through Fireworks instead of `o3-mini`. A local LLM can be used by omitting `OPENAI_KEY`, setting `OPENAI_ENDPOINT` to the local OpenAI-compatible server, and setting `OPENAI_MODEL` to the loaded model’s name. Elsewhere, the README documents `CUSTOM_MODEL`—rather than `OPENAI_MODEL`—for custom OpenAI-compatible services such as OpenRouter or Gemini. Because the supplied documentation uses both names in different scenarios, preserve the name associated with the workflow you are following rather than assuming they are interchangeable.

The repository does not document account creation, pricing, supported Firecrawl plans, local-model server installation, provider authentication procedures, or model compatibility testing. Obtain credentials and run any local server separately. API keys are placed in `.env.local`; do not commit that file or share its contents. The supplied files do not describe secret encryption or telemetry behavior.

3. Node.js installation and environment configuration

Clone the public repository from the metadata-provided URL, enter its working directory, and install the declared dependencies. The README’s copy-paste installation command is:

npm install

Create `.env.local` in the repository root. For the standard hosted setup, use the documented variable names and replace the placeholders:

FIRECRAWL_KEY="your_firecrawl_key"
# If you want to use your self-hosted Firecrawl, add the following below:
# FIRECRAWL_BASE_URL="http://localhost:3002"

OPENAI_KEY="your_openai_key"

Leave `FIRECRAWL_BASE_URL` commented for the ordinary Firecrawl API. For a self-hosted Firecrawl instance, uncomment it and set it to that service’s address; the only supplied example is `http://localhost:3002`.

For a local LLM, the README says to comment out `OPENAI_KEY`, uncomment or add `OPENAI_ENDPOINT`, and set it to the server address, such as `http://localhost:1234/v1`. It also says to set `OPENAI_MODEL` to the model loaded by that local server. No complete local-LLM `.env.local` block is supplied, so this manual does not invent one.

Installation fetches both runtime and development dependencies listed in `package.json`, including Firecrawl, AI SDK provider packages, Express, TypeScript, `tsx`, concurrency control, tokenization, validation, and formatting packages.

4. Running research interactively

From the configured repository directory, start the assistant with the README’s command:

npm start

This executes `src/run.ts` through `tsx` and loads variables from `.env.local`. The terminal prompts for four kinds of input:

  1. Enter the research query or topic.
  2. Choose breadth. The documented recommendation is `3–10`, with a default of `4`.
  3. Choose depth. The documented recommendation is `1–5`, with a default of `2`.
  4. Answer the generated follow-up questions so the application can refine what should be researched.

After input, the assistant generates and runs search queries, processes and analyzes the results, recursively explores new directions derived from the findings, and then generates a Markdown report. The final file is `report.md` or `answer.md` in the current working directory, depending on the selected mode. The supplied files do not identify the exact mode prompt or define when each filename is chosen, so inspect the resulting working directory rather than relying on an undocumented selection rule.

Breadth and depth affect workload: broader research creates more search directions, while deeper research repeats exploration using accumulated findings. The README provides recommended ranges, not guaranteed cost, duration, or quality levels. API usage and completion time therefore depend on the chosen values, concurrency, provider limits, and returned content.

5. What the research workflow does

The workflow begins with the user’s query plus breadth and depth. It generates follow-up questions to clarify research needs before pursuing the topic. It then asks the model to produce multiple targeted SERP queries based on the research goal and any findings already gathered.

Returned search material is processed into two outputs: **learnings**, meaning extracted findings, and **directions**, meaning possible next questions or avenues. When depth remains, the application combines prior goals, new questions, and accumulated learnings into fresh context and calls the deep-research process again. Each round therefore builds on earlier evidence rather than starting from an unrelated query. When no further depth remains, it compiles the collected material into a readable Markdown report with sources and references.

The README documents concurrent handling of multiple searches and result-processing tasks. Concurrency is an efficiency feature, not a separate user mode: it allows independent work to proceed in parallel subject to the configured limit and external rate limits.

This process is model-assisted rather than a guarantee of factual correctness. The supplied documentation does not describe citation verification, source-ranking rules, duplicate removal, prompt contents, retry policy, or defenses against misleading web pages. Review the report, follow its cited sources, and independently verify consequential claims before relying on them. The repository’s stated function is research assistance and report generation, not authoritative validation.

6. Provider overrides and concurrency control

To select DeepSeek R1 through Fireworks, add the documented variable to `.env.local` and replace the placeholder:

FIREWORKS_KEY="api_key"

When that key is detected, the README says the system automatically uses R1 instead of `o3-mini`. No explicit model-selection command is documented for this path.

For another OpenAI-compatible API, the README supplies these optional variable names:

OPENAI_ENDPOINT="custom_endpoint"
CUSTOM_MODEL="custom_model"

Replace both values with the endpoint and model string required by the chosen compatible provider. OpenRouter and Gemini are given as examples of compatible-API use cases, but the repository does not provide provider-specific URLs, credentials, or tested model names. Do not infer that every provider or model works.

Search concurrency is controlled with the `CONCURRENCY_LIMIT` environment variable. The README recommends increasing it when using paid Firecrawl or a local Firecrawl deployment to improve speed. With a free Firecrawl plan, rate-limit errors may occur; the documented mitigation is to reduce the value to `1`, at the cost of much slower execution. The files do not supply a complete `.env.local` line or state the built-in numeric default, so set only a numeric value appropriate to your service limit. Higher concurrency can make more requests at once; it does not increase research depth or breadth by itself.

7. Docker workflow

The Docker path starts with a cloned repository. Rename `.env.example` to `.env.local`, then place the required API keys in `.env.local`. The README does not supply a copy-paste rename command, so perform that filesystem operation using your normal environment rather than relying on an invented command.

The documented build command is reproduced exactly:

docker build -f Dockerfile

Next, start the Compose services in detached mode:

docker compose up -d

Finally, execute the Docker-specific npm script inside the named service container:

docker exec -it deep-research npm run docker

The `docker` package script runs `tsx src/run.ts`. Unlike the normal `start` script, its command does not explicitly pass `--env-file=.env.local`; the Docker/Compose environment is expected to make configuration available. The final command is interactive (`-it`) because the research runner prompts for the query, breadth, depth, and follow-up answers.

The supplied README gives no image tag, build context, port mapping, volume description, health check, log command, shutdown command, or container troubleshooting procedure. In particular, the published build line is presented without an explicit context argument. This manual preserves that source command and does not add undocumented Docker flags or corrections. Use the Node.js workflow if the documented container path does not fit your environment.

8. Package scripts and developer-facing functions

`package.json` defines six scripts. Use `npm start` for the documented interactive application; it runs `tsx --env-file=.env.local src/run.ts`. The Docker workflow calls `npm run docker`, which runs `tsx src/run.ts` without the explicit environment-file option.

The API entry point can be launched with:

npm run api

That script loads `.env.local` and runs `src/api.ts`. Express and CORS are declared dependencies, but the supplied files document no routes, request schemas, response schemas, authentication, network port, or API examples. Treat the command only as an available entry point, not as a documented public protocol.

Source formatting is available through:

npm run format

It runs Prettier in write mode over TypeScript and TSX files beneath `src`, so it modifies matching source files. The `tsx` script invokes `tsx --env-file=.env.local`, but no target file or supported use case is documented; the normal `start` and `api` scripts are the defined entry points.

There is no working test suite. The `test` script prints `Error: no test specified` and exits with status 1. Consequently, `npm test` must not be interpreted as project validation. The supplied files also document no build, lint, type-check, migration, update, or deployment script.

9. Outputs, limits, licensing, and safe operation

A successful interactive run writes either `report.md` or `answer.md` to the working directory. The report is described as comprehensive, clearly organized, and inclusive of sources and references. No other output location, overwrite behavior, recovery mechanism, export format, or naming customization is documented. Preserve an existing report before another run if overwriting would matter; the source does not state whether files are replaced.

Firecrawl receives search requests and extracts web content. The selected model provider receives material needed for query generation, analysis, follow-up directions, and report writing. A local model and self-hosted Firecrawl can change where processing occurs, but the files provide no privacy architecture or guarantee that all data remains local. Avoid including secrets or sensitive personal material in research prompts unless your provider configuration is appropriate.

If Firecrawl returns rate-limit errors, lower `CONCURRENCY_LIMIT`; `1` is the documented free-plan mitigation. If model selection is unexpected, check whether `FIREWORKS_KEY` is present, because its detection is documented to switch from `o3-mini` to R1. Also verify the variable-name distinction between the local-model instructions (`OPENAI_MODEL`) and custom-provider example (`CUSTOM_MODEL`).

Licensing evidence conflicts: repository metadata and the README say MIT, while `package.json` declares ISC. Do not assume the discrepancy is resolved; inspect the repository’s actual license file before redistribution. No tests, support guarantee, security policy, Claude integration, or reliability benchmark is documented in the supplied evidence.