Skip to content

jkudish/librarium

Repository files navigation

Librarium

librarium

Fan out research queries to multiple search and deep-research APIs in parallel.

Inspired by Aaron Francis' counselors, librarium applies the same fan-out pattern to search APIs. Where counselors fans out prompts to multiple LLM CLIs, librarium fans out research queries to search engines, AI-grounded search, and deep-research APIs -- collecting, normalizing, and deduplicating results into structured output.

Installation

npm (requires Node.js >= 20)

npm install -g librarium

pnpm

pnpm install -g librarium

yarn

yarn global add librarium

Homebrew (macOS / Linux)

brew install jkudish/tap/librarium

Standalone binary

curl -fsSL https://raw.githubusercontent.com/jkudish/librarium/main/scripts/install.sh | sh

npx (no install)

npx librarium run "your query"

Upgrade

librarium upgrade

Auto-detects your install method (npm, pnpm, yarn, Homebrew, standalone) and runs the correct upgrade command.

Quick Start

# Auto-configure (discovers API keys from environment)
librarium init --auto

# Run a research query
librarium run "PostgreSQL connection pooling best practices"

# Use a specific group
librarium run "React Server Components" --group quick

# Check async deep research status
librarium status --wait

Providers

Librarium ships with 13 built-in provider adapters organized into three tiers:

Provider ID Tier API Key Env Var
Perplexity Sonar Deep Research perplexity-sonar-deep deep-research PERPLEXITY_API_KEY
Perplexity Deep Research perplexity-deep-research deep-research PERPLEXITY_API_KEY
Perplexity Advanced Deep Research perplexity-advanced-deep deep-research PERPLEXITY_API_KEY
OpenAI Deep Research openai-deep deep-research OPENAI_API_KEY
Gemini Deep Research gemini-deep deep-research GEMINI_API_KEY
Perplexity Sonar Pro perplexity-sonar-pro ai-grounded PERPLEXITY_API_KEY
Brave AI Answers brave-answers ai-grounded BRAVE_API_KEY
Exa Search exa ai-grounded EXA_API_KEY
Perplexity Search perplexity-search raw-search PERPLEXITY_API_KEY
Brave Web Search brave-search raw-search BRAVE_API_KEY
SearchAPI searchapi raw-search SEARCHAPI_API_KEY
SerpAPI serpapi raw-search SERPAPI_API_KEY
Tavily Search tavily raw-search TAVILY_API_KEY

Provider ID Migration (Legacy Aliases)

Perplexity provider IDs were renamed to match current product names:

  • perplexity-sonar -> perplexity-sonar-pro
  • perplexity-deep -> perplexity-sonar-deep

For backward compatibility, librarium still accepts legacy IDs in:

  • run --providers
  • provider config keys in ~/.config/librarium/config.json
  • custom group members
  • fallback targets

Legacy IDs are normalized to canonical IDs and emit a warning. Output files and run.json always use canonical IDs.

You can also add custom providers (npm modules or local scripts) via config. See Custom Providers.

Provider Tiers

Providers are categorized into three tiers based on their capabilities, latency, and depth:

  • deep-research -- Async deep research providers that take minutes to complete but produce comprehensive, multi-source reports. These providers may use a submit/poll/retrieve pattern. Best for thorough research on important topics.

  • ai-grounded -- AI-powered search with inline citations. Returns results in seconds with good quality and source attribution. A solid middle ground between speed and depth.

  • raw-search -- Traditional search engine results. Fast responses with many links and snippets, but no AI synthesis. Useful for broad link discovery and verifying specific facts.

Commands

run

Run a research query across multiple providers.

librarium run <query> [options]
Flag Description
-p, --providers <ids> Comma-separated provider IDs
-g, --group <name> Use a predefined provider group
-m, --mode <mode> Execution mode: sync, async, or mixed
-o, --output <dir> Output base directory
--parallel <n> Max parallel requests
--timeout <n> Timeout per provider in seconds
--json Output run.json to stdout
# Run with specific providers
librarium run "database indexing" --providers perplexity-sonar-pro,exa

# Deep research, wait for completion
librarium run "AI agent architectures" --group deep --mode sync

# Fast results only
librarium run "Node.js 22 features" --group fast

status

Check or wait for async deep-research tasks.

librarium status [options]
Flag Description
--wait Block and poll until all async tasks complete
--retrieve Fetch completed results and write output files
--json Output JSON
# Check pending tasks
librarium status

# Wait for completion then retrieve results
librarium status --wait --retrieve

ls

List all available providers with their status.

librarium ls [--json]

Shows each provider's ID, display name, tier, source (builtin, npm, script), enabled state, and whether an API key is configured.

groups

List and manage provider groups.

# List all groups
librarium groups

# Add a custom group
librarium groups add my-stack perplexity-sonar-pro exa tavily

# Remove a custom group
librarium groups remove my-stack

# Output as JSON
librarium groups --json

init

Set up librarium configuration. Auto mode discovers API keys from your environment and enables matching providers.

# Auto-discover (non-interactive)
librarium init --auto

# Interactive setup
librarium init

doctor

Health check: tests API connectivity for all enabled providers.

librarium doctor [--json]

config

Print the resolved configuration (global merged with project).

# Show resolved config
librarium config

# Show only global config
librarium config --global

# Output raw JSON
librarium config --json

cleanup

Remove old output directories.

# Delete directories older than 30 days (default)
librarium cleanup

# Custom age threshold
librarium cleanup --days 7

# Preview what would be deleted
librarium cleanup --dry-run

Groups

Groups are named collections of provider IDs. Librarium ships with six default groups:

Group Providers Use Case
deep perplexity-sonar-deep, perplexity-deep-research, perplexity-advanced-deep, openai-deep, gemini-deep Thorough async research
quick perplexity-sonar-pro, brave-answers, exa Fast AI-grounded answers
raw perplexity-search, brave-search, searchapi, serpapi, tavily Traditional search results
fast perplexity-sonar-pro, perplexity-search, brave-answers, exa, brave-search, tavily Quick results from multiple tiers
comprehensive All deep-research + all ai-grounded Deep + AI-grounded combined
all All 13 providers Maximum coverage

Custom Groups

Add custom groups via CLI or config file:

# Via CLI
librarium groups add my-research perplexity-sonar-pro exa brave-search

# Via config.json
{
  "groups": {
    "my-research": ["perplexity-sonar-pro", "exa", "brave-search"]
  }
}

Execution Modes

Librarium supports three execution modes, configurable via --mode or the defaults.mode config key:

  • sync -- Wait for all providers to complete, including deep-research providers. Deep research runs synchronously (can take several minutes).

  • async -- Submit deep-research tasks and return immediately. Use librarium status --wait --retrieve to poll and fetch results later.

  • mixed (default) -- Run ai-grounded and raw-search providers synchronously. Submit deep-research providers asynchronously. You get fast results right away and can retrieve deep research later.

Provider Fallback

When a provider fails for any reason (exception, error response, timeout), librarium can automatically try a lighter alternative. Add an optional fallback field to any provider's config:

{
  "providers": {
    "gemini-deep": {
      "apiKey": "$GEMINI_API_KEY",
      "enabled": true,
      "fallback": "openai-deep"
    },
    "openai-deep": {
      "apiKey": "$OPENAI_API_KEY",
      "enabled": false
    }
  }
}

Behavior:

  • Fallback triggers after the primary provider's execution fails (error or timeout)
  • Only single-level fallback is supported (a fallback's own fallback is ignored)
  • The fallback provider must be configured with a valid API key but can be enabled: false (it will only activate as a backup)
  • If the fallback provider is already running in the same dispatch (e.g., explicitly listed in --providers), it won't be triggered again
  • Output files use the fallback provider's ID (e.g., openai-deep.md)

In run.json, both the original error report and the fallback result appear in the providers array. The fallback report includes a fallbackFor field indicating which provider it replaced:

{
  "id": "openai-deep",
  "tier": "deep-research",
  "status": "success",
  "fallbackFor": "gemini-deep"
}

Configuration

Librarium uses a layered configuration system:

  1. Global config: ~/.config/librarium/config.json
  2. Project config: .librarium.json (in current directory)
  3. CLI flags: Passed directly to commands

Each layer overrides the previous:

  • defaults: project overrides global
  • providers: deep-merged by provider ID (project overrides keys on conflict)
  • customProviders: merged by provider ID (project overrides global on same ID)
  • trustedProviderIds: union + dedupe across global and project
  • groups: project overrides global group names on conflict

Global Config Example

{
  "version": 1,
  "defaults": {
    "outputDir": "./agents/librarium",
    "maxParallel": 6,
    "timeout": 30,
    "asyncTimeout": 1800,
    "asyncPollInterval": 10,
    "mode": "mixed"
  },
  "providers": {
    "perplexity-sonar-pro": {
      "apiKey": "$PERPLEXITY_API_KEY",
      "enabled": true
    },
    "brave-answers": {
      "apiKey": "$BRAVE_API_KEY",
      "enabled": true
    },
    "exa": {
      "apiKey": "$EXA_API_KEY",
      "enabled": true
    },
    "tavily": {
      "apiKey": "$TAVILY_API_KEY",
      "enabled": true
    }
  },
  "customProviders": {},
  "trustedProviderIds": [],
  "groups": {
    "my-custom-group": ["perplexity-sonar-pro", "exa"]
  }
}

API keys use the $ENV_VAR pattern -- the value "$PERPLEXITY_API_KEY" resolves to process.env.PERPLEXITY_API_KEY at runtime. Keys are never stored in plaintext.

Some providers support optional model overrides. For example, to override Gemini Deep Research:

{
  "providers": {
    "gemini-deep": {
      "apiKey": "$GEMINI_API_KEY",
      "enabled": true,
      "model": "gemini-2.5-flash"
    }
  }
}

Project Config Example

{
  "defaults": {
    "outputDir": "./research",
    "timeout": 60
  },
  "providers": {
    "perplexity-sonar-pro": {
      "enabled": false
    },
    "my-script-provider": {
      "enabled": true
    }
  },
  "customProviders": {
    "my-script-provider": {
      "type": "script",
      "command": "node",
      "args": ["./scripts/librarium-provider.mjs"]
    }
  },
  "trustedProviderIds": ["my-script-provider"],
  "groups": {
    "project-research": ["my-script-provider", "exa"]
  }
}

Custom Providers

Librarium supports external providers without changing core code. Add definitions to config and trust them explicitly.

For provider-author implementation details (module contract, script runtime semantics, timeouts, and troubleshooting), see docs/provider-development.md.

Trust Model

  • Custom providers load only when their ID appears in trustedProviderIds
  • Trust lists from global and project config are unioned and deduped
  • Built-in IDs are reserved; custom providers cannot override built-ins

NPM Provider Example

{
  "customProviders": {
    "my-npm-provider": {
      "type": "npm",
      "module": "librarium-provider-myteam",
      "export": "createProvider",
      "options": { "preset": "fast" }
    }
  },
  "trustedProviderIds": ["my-npm-provider"],
  "providers": {
    "my-npm-provider": {
      "enabled": true,
      "apiKey": "$MY_PROVIDER_API_KEY"
    }
  }
}

module resolution order is:

  1. Current project (process.cwd())
  2. Librarium runtime install context

In standalone/Homebrew binary installs, npm custom providers are skipped with a warning.

Script Provider Example

{
  "customProviders": {
    "my-script-provider": {
      "type": "script",
      "command": "node",
      "args": ["./scripts/librarium-provider.mjs"],
      "cwd": ".",
      "env": { "LOG_LEVEL": "warn" },
      "options": { "flavor": "deep" }
    }
  },
  "trustedProviderIds": ["my-script-provider"],
  "providers": {
    "my-script-provider": {
      "enabled": true
    }
  }
}

Script providers are invoked as one process per operation (describe, execute, submit, poll, retrieve, test) with JSON over stdin/stdout.

Script Protocol (v1)

Request envelope:

{
  "protocolVersion": 1,
  "operation": "execute",
  "providerId": "my-script-provider",
  "query": "research topic",
  "options": { "timeout": 30 },
  "providerConfig": { "enabled": true },
  "sourceOptions": { "flavor": "deep" }
}

Response envelope:

{
  "ok": true,
  "data": {
    "provider": "my-script-provider",
    "tier": "ai-grounded",
    "content": "# Result",
    "citations": [],
    "durationMs": 1200
  }
}

Error response:

{
  "ok": false,
  "error": "upstream timeout"
}

describe must return provider metadata and capabilities:

{
  "ok": true,
  "data": {
    "displayName": "My Script Provider",
    "tier": "deep-research",
    "envVar": "MY_PROVIDER_API_KEY",
    "requiresApiKey": true,
    "capabilities": {
      "submit": true,
      "poll": true,
      "retrieve": true,
      "test": true
    }
  }
}

Output Format

Each research run creates a timestamped output directory:

./agents/librarium/1771500000-postgresql-pooling/
  prompt.md              # The research query
  run.json               # Run manifest (machine-readable)
  summary.md             # Synthesized summary with statistics
  sources.json           # Deduplicated citations across all providers
  perplexity-sonar-pro.md    # Per-provider markdown results
  perplexity-sonar-pro.meta.json  # Per-provider metadata (model, timing, citations)
  brave-answers.md
  brave-answers.meta.json
  async-tasks.json       # Present if any async tasks were submitted

run.json Schema

{
  "version": 1,
  "timestamp": 1771500000,
  "slug": "postgresql-pooling",
  "query": "PostgreSQL connection pooling best practices",
  "mode": "mixed",
  "outputDir": "/absolute/path/to/output",
  "providers": [
    {
      "id": "perplexity-sonar-pro",
      "tier": "ai-grounded",
      "status": "success",
      "durationMs": 2340,
      "wordCount": 850,
      "citationCount": 12,
      "outputFile": "perplexity-sonar-pro.md",
      "metaFile": "perplexity-sonar-pro.meta.json"
    }
  ],
  "sources": {
    "total": 45,
    "unique": 28,
    "file": "sources.json"
  },
  "asyncTasks": [],
  "exitCode": 0
}

Exit Codes

Code Meaning
0 All providers succeeded
1 Partial success (some providers failed)
2 Total failure (all providers failed, or configuration error)

Using with AI Agents

Librarium is designed to be used by AI coding agents. There are three ways to set it up:

Option 1: Claude Code Skill (Recommended)

The built-in skill teaches Claude Code how to use librarium through a 7-phase research workflow.

# Install via CLI
librarium install-skill

# Or manually
mkdir -p ~/.claude/skills/librarium
curl -o ~/.claude/skills/librarium/SKILL.md https://raw.githubusercontent.com/jkudish/librarium/main/SKILL.md

Once installed, Claude Code will automatically use librarium when you ask it to research a topic. Triggers: /librarium, /research, /deep-research.

Option 2: Agent Prompt

Drop this into any AI agent's system prompt to give it librarium capabilities:

You have access to the `librarium` CLI for deep multi-provider research.

To research a topic, run:
  librarium run "<query>" --group <group>

Groups:
  quick          — Fast AI-grounded answers (seconds)
  deep           — Thorough async research (minutes)
  fast           — Quick results from multiple tiers
  comprehensive  — Deep + AI-grounded combined
  all            — All 13 providers

Output lands in ./agents/librarium/<timestamp>-<slug>/:
  summary.md     — Synthesized overview with stats
  sources.json   — Deduplicated citations ranked by frequency
  {provider}.md  — Per-provider detailed results
  run.json       — Machine-readable manifest

For async deep research, check status with:
  librarium status --wait

Cross-reference sources appearing in multiple providers for higher confidence.

Option 3: CLAUDE.md Project Instructions

Add to your project's CLAUDE.md for project-scoped research:

## Research

Use `librarium` for research queries. It's installed globally.
- Quick lookups: `librarium run "query" --group quick`
- Deep research: `librarium run "query" --group deep --mode sync`
- Results land in `./agents/librarium/` — read `summary.md` first, then `sources.json` for citations

7-Phase Research Workflow

The skill guides agents through:

  1. Query Analysis -- Classify the research question and pick the right provider group
  2. Provider Selection -- Match query type to tier (quick for facts, deep for thorough research, all for max coverage)
  3. Dispatch -- Run the query with appropriate flags
  4. Monitor -- Track async deep-research tasks
  5. Retrieve -- Fetch completed async results
  6. Analyze -- Read summary.md, sources.json, and per-provider output files
  7. Synthesize -- Cross-reference multi-provider findings, weight by citation frequency

Publishing

The release workflow at .github/workflows/release.yml handles npm publishing. It requires a NPM_TOKEN repository secret configured in GitHub Settings > Secrets.

Sponsoring

If librarium saves you time, consider sponsoring development. ❤️

License

MIT

About

Multi-provider deep research CLI — fans out queries to multiple search/AI APIs in parallel

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors