Setting Up Web Search Backends (Brave and Parallel AI) for last30days-skill

To enable automated web search in last30days-skill, configure either PARALLEL_API_KEY or BRAVE_API_KEY in your environment files, with Parallel AI automatically taking precedence over Brave when both are present.

The last30days-skill aggregates recent content from platforms like Reddit, X, and YouTube, and can optionally enrich these results with real-time web search data. Activating this capability requires supplying API credentials for supported search backends in specific configuration files that the skill reads at runtime according to the logic in scripts/lib/env.py.

How the Backend Selection Works

The skill automatically selects the best available web search provider based on a hardcoded priority system. The get_web_search_source function in scripts/lib/env.py (lines 36-44) checks for API keys in the following order:

  1. Parallel AI — checked first via PARALLEL_API_KEY
  2. Brave Search — fallback via BRAVE_API_KEY
  3. OpenRouter/Perplexity — last resort via OPENROUTER_API_KEY

If none of these keys are detected, the skill runs without native web search capabilities and relies on the assistant to perform searches instead. The selection logic appears as:

def get_web_search_source(config: dict) -> Optional[str]:
    if config.get('PARALLEL_API_KEY'):
        return 'parallel'          # preferred

    if config.get('BRAVE_API_KEY'):
        return 'brave'             # fallback

    if config.get('OPENROUTER_API_KEY'):
        return 'openrouter'        # last resort

    return None

Configuration Hierarchy and File Locations

The skill loads configuration through three layers of precedence, implemented in env.get_config() in scripts/lib/env.py (lines 15-33):

  • Environment variables (os.environ) — highest priority
  • Project-specific file ./.claude/last30days.env — overrides global settings
  • Global config file ~/.config/last30days/.env — default location

The function merges these layers, allowing project-specific overrides while maintaining global defaults.

Step-by-Step Setup Guide

Parallel AI Configuration

Parallel AI offers the preferred search backend with structured objective-based queries.

First, obtain your API key from parallel.ai — typically formatted as sk-par-....

Then create the configuration file in your preferred location. For global use across all projects:

mkdir -p ~/.config/last30days
echo "PARALLEL_API_KEY=sk-par-your_key_here" > ~/.config/last30days/.env
chmod 600 ~/.config/last30days/.env

For project-specific overrides:

mkdir -p .claude
echo "PARALLEL_API_KEY=sk-par-your_key_here" > .claude/last30days.env

The parallel_search.search_web function in scripts/lib/parallel_search.py (lines 26-74) constructs JSON payloads with parameters for objective, max_results, and max_chars_per_result, submitting via HTTP POST and normalizing responses to extract url, title, and snippet fields.

Brave Search Configuration

Brave Search serves as the secondary backend, offering traditional web search with optional LLM context enrichment.

Obtain your API key from the Brave Search Dashboard after enabling a paid subscription — UUID format like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

Configure the key globally:

mkdir -p ~/.config/last30days
cat > ~/.config/last30days/.env <<'EOF'
BRAVE_API_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
EOF
chmod 600 ~/.config/last30days/.env

Optionally enable the LLM-Context endpoint for richer snippets by setting BRAVE_LLM_CONTEXT=1 as an environment variable. The brave_search.search_web function in scripts/lib/brave_search.py (lines 36-92) constructs GET requests to https://api.search.brave.com/res/v1/web/search, supports freshness parameters for date ranges, normalizes HTML removal, filters excluded domains, and assigns a default relevance score of 0.6.

Verifying Your Setup

Run the diagnostic command to confirm which backend is active:

python3 scripts/last30days.py --diagnose

Examine the output for the web search backend line:


Web search backend: parallel

If the output shows none instead of parallel or brave, the skill cannot locate your API key in any configuration layer.

Integration in the Research Pipeline

When executing a research query, the main orchestrator in scripts/last30days.py calls _search_web, which delegates to the selected backend based on the env.get_web_search_source return value:

elif backend == "brave":
    raw_results = brave_search.search_web(
        topic, from_date, to_date,
        config["BRAVE_API_KEY"],
        depth=depth, use_llm_context=use_llm_ctx,
    )
elif backend == "parallel":
    raw_results = parallel_search.search_web(
        topic, from_date, to_date,
        config["PARALLEL_API_KEY"], depth=depth,
    )

The returned dictionaries undergo enrichment with IDs, date confidence scoring, and relevance ranking before incorporation into the final brief.

Summary

  • Parallel AI takes precedence over Brave when both PARALLEL_API_KEY and BRAVE_API_KEY are configured, as enforced by the logic in scripts/lib/env.py.
  • Store API keys in ~/.config/last30days/.env for global use or .claude/last30days.env for project-specific overrides.
  • The skill automatically detects available backends using get_web_search_source and fails gracefully to assistant-performed searches if no keys are present.
  • Verify activation using python3 scripts/last30days.py --diagnose before running research queries.

Frequently Asked Questions

What happens if I configure multiple API keys simultaneously?

The skill strictly follows the priority order defined in env.get_web_search_source: Parallel AI first, Brave second, and OpenRouter third. If you provide all three keys, Parallel AI will be selected automatically. To force a specific backend, provide only that backend's API key and remove others from your configuration files.

Why does my configuration file need 600 permissions?

While the skill will read the file regardless of permissions, setting chmod 600 on ~/.config/last30days/.env prevents other system users from reading your sensitive API credentials. This follows security best practices for files containing authentication tokens that grant access to paid search APIs.

Can I use environment variables instead of files?

Yes. Environment variables take the highest precedence in the configuration hierarchy. You can export PARALLEL_API_KEY or BRAVE_API_KEY directly in your shell, and env.get_config() will prioritize these values over entries in .env files. This approach is particularly useful for CI/CD pipelines where writing configuration files is impractical.

How do I troubleshoot when --diagnose shows "none"?

If the diagnostic output reports Web search backend: none, verify three things: first, ensure the key variable name matches exactly (PARALLEL_API_KEY or BRAVE_API_KEY, case-sensitive); second, confirm the file path is either ~/.config/last30days/.env or ./.claude/last30days.env; third, check that the file contains no syntax errors or whitespace issues around the equals sign.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →