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:
- Parallel AI — checked first via
PARALLEL_API_KEY - Brave Search — fallback via
BRAVE_API_KEY - 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_KEYandBRAVE_API_KEYare configured, as enforced by the logic inscripts/lib/env.py. - Store API keys in
~/.config/last30days/.envfor global use or.claude/last30days.envfor project-specific overrides. - The skill automatically detects available backends using
get_web_search_sourceand fails gracefully to assistant-performed searches if no keys are present. - Verify activation using
python3 scripts/last30days.py --diagnosebefore 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →