
Web Search Brave
- 283 installs
- 133 repo stars
- Updated February 24, 2026
- jwynia/agent-skills
web-search-brave is a Claude Code agent skill that queries the Brave Search API for live, citation-friendly web results when developers need current facts with country, language, or time filters.
About
web-search-brave is an agent skill that wires Brave Search into coding workflows through a Deno CLI script against api.search.brave.com. After setting BRAVE_API_KEY, developers run searches that return up to 20 results with titles, URLs, descriptions, and optional extra snippets, using flags for country codes, language, safe-search, freshness windows (pd, pw, pm, py), pagination offset, and JSON output. The skill targets privacy-respecting retrieval when built-in search lacks localization or time controls, such as verifying release notes, regional docs, or news during feature work. It complements generic web-search and Tavily-style ranked search when a Brave API key is already provisioned. Prerequisites include Deno, network access, and a Brave Search API plan; extra snippets may require a paid tier. Version 1.0 ships in the jwynia/agent-skills research tools bundle.
- Brave Search API
- Live retrieval
- Agent tool wiring
- Fresh facts
- Research automation
Web Search Brave by the numbers
- 283 all-time installs (skills.sh)
- +2 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #2,404 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jwynia/agent-skills --skill web-search-braveAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 283 |
|---|---|
| repo stars | ★ 133 |
| Last updated | February 24, 2026 |
| Repository | jwynia/agent-skills ↗ |
How do you add Brave Search to agent workflows?
Wire Brave web search into agent workflows for live retrieval, citation-friendly results, and up-to-date facts during research or implementation tasks.
Who is it for?
Developers who already hold a Brave Search API key and need programmatic, localized, time-filtered web retrieval inside Claude Code or compatible agents.
Skip if: Developers who only need free built-in web search or AI-ranked answer summaries without managing a Brave API key and Deno runtime.
When should I use this skill?
Trigger when the user asks for Brave web search, localized results, freshness-filtered news, or live facts requiring BRAVE_API_KEY-backed retrieval.
What you get
JSON or text search result sets with URLs, snippets, and optional freshness or locale metadata.
- JSON search results
- CLI search output
By the numbers
- Returns up to 20 Brave Search API results per request
- Skill metadata version 1.0 in jwynia/agent-skills
Files
Web Search (Brave Search API)
Search the web using Brave's Search API. Returns web results with descriptions, optional extra snippets, and support for country/language targeting.
Note: This skill requires a Brave Search API key. For basic web search using the agent's built-in capability, see web-search. For AI-optimized results with relevance scores, see web-search-tavily.
When to Use This Skill
Use this skill when:
- You need to find current information not in your training data
- The user asks about recent events, news, or updates
- You need localized search results for a specific country or language
- You want a privacy-respecting search alternative
- Research requires real-time web data
- Keywords mentioned: search, look up, find online, current, latest, news
Do NOT use this skill when:
- Information is already in your knowledge base and doesn't need verification
- The user asks about historical facts that don't change
- You're working with local files or code (use other tools)
- A more specific skill exists for the task (e.g., documentation lookup)
- You need AI-generated answer summaries (use
web-search-tavilyinstead)
Prerequisites
Before using this skill, ensure:
- BRAVE_API_KEY environment variable is set with a valid API key
- Deno is installed (for running the search script)
- Internet access is available
Get a Brave Search API key at: https://brave.com/search/api/
Quick Start
Run a simple search:
deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "your search query"Example with freshness filter:
deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "React 19 new features" --freshness pwScript Usage
deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts [options] "query"Options
| Option | Description | Default |
|---|---|---|
--results <n> | Number of results to return (max 20) | 5 |
--freshness <range> | Time filter: pd, pw, pm, or py | none |
--country <code> | Country code for localized results (e.g., US, GB, DE) | none |
--lang <code> | Search language (e.g., en, fr, de) | none |
--safesearch <level> | Safe search: off, moderate, or strict | moderate |
--extra-snippets | Include additional content snippets | false |
--offset <n> | Pagination offset | 0 |
--json | Output as JSON (for programmatic use) | false |
--help | Show help message | - |
Search Parameters
Freshness Values
Filter results by recency:
- pd: Past day (last 24 hours)
- pw: Past week (last 7 days)
- pm: Past month (last 30 days)
- py: Past year (last 365 days)
Country Codes
Use standard 2-character country codes to get localized results:
US(United States),GB(United Kingdom),DE(Germany),FR(France),JP(Japan), etc.
Safe Search Levels
- off: No filtering
- moderate (default): Filters explicit content
- strict: Strictest filtering
Output Format
Human-Readable Output (default)
Search: "React 19 new features"
Found 5 results in 189ms
1. React 19 Release Notes
https://react.dev/blog/2024/04/25/react-19
React 19 is now available on npm! This release includes...
Age: 2 months ago
2. What's New in React 19
https://example.com/react-19-features
A comprehensive overview of React 19's new features...JSON Output (--json)
{
"query": "React 19 new features",
"results": [
{
"title": "React 19 Release Notes",
"url": "https://react.dev/blog/2024/04/25/react-19",
"description": "React 19 is now available on npm...",
"age": "2 months ago",
"language": "en",
"family_friendly": true
}
],
"response_time": 189,
"total_results": 1250000
}Result Fields
| Field | Type | Description |
|---|---|---|
title | string | Page title |
url | string | Source URL |
description | string | Relevant excerpt from the page |
extra_snippets | string[] | Additional content snippets (only with --extra-snippets) |
age | string | How old the result is (e.g., "2 hours ago") |
language | string | Language of the result |
family_friendly | boolean | Whether the result is family-friendly |
Examples
Example 1: Current Events Search
Scenario: Find recent news about a technology topic
scripts/search.ts "OpenAI GPT-5 announcement" --freshness pw --results 10Expected output: Recent web results about GPT-5 from the past week
Example 2: Documentation Lookup
Scenario: Find specific technical documentation
scripts/search.ts "Deno deploy edge functions tutorial" --results 10 --extra-snippetsExpected output: Comprehensive results with extra snippets from documentation and tutorial sites
Example 3: Localized Search
Scenario: Find results targeted to a specific country and language
scripts/search.ts "aktuelle Nachrichten" --country DE --lang de --freshness pdExpected output: German-language results from Germany from the past day
Example 4: Filtered Search with JSON Output
Scenario: Get structured results with strict safe search
scripts/search.ts "machine learning tutorials" --safesearch strict --extra-snippets --jsonExpected output: JSON results with extra snippets, filtered for safe content
Common Issues and Solutions
Issue: "BRAVE_API_KEY environment variable is not set"
Symptoms: Script exits immediately with API key error
Solution: 1. Get an API key from https://brave.com/search/api/ 2. Set the environment variable:
export BRAVE_API_KEY="your-api-key-here"3. Or run with the variable inline:
BRAVE_API_KEY="your-key" deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "query"Issue: "Invalid Brave Search API key"
Symptoms: 401 authentication error
Solution: 1. Verify your API key is correct (no extra spaces) 2. Check if your API key has expired 3. Verify your Brave Search API subscription is active
Issue: "Brave Search API rate limit exceeded"
Symptoms: 429 error response
Solution: 1. Wait a moment and retry 2. Reduce request frequency 3. Consider upgrading your Brave Search API plan for higher limits
Issue: No results returned
Symptoms: Empty results array
Solution: 1. Try broader search terms 2. Remove country or language filters that might be too restrictive 3. Remove or widen the freshness filter 4. Check if the topic exists online
Limitations
This skill has the following limitations:
- Requires active internet connection
- API rate limits apply based on your Brave Search API plan
- Results depend on Brave's index coverage
- Cannot access paywalled or login-required content
- No built-in AI-generated answer summaries (use
web-search-tavilyfor that) - Maximum 20 results per request
- Extra snippets require a paid API plan
Related Skills
- web-search: Basic web search using the agent's built-in capability
- web-search-tavily: AI-optimized search with relevance scores and answer summaries
- research-workflow: For comprehensive research projects that use multiple searches with planning and synthesis
#!/usr/bin/env -S deno run --allow-env --allow-net=api.search.brave.com
/**
* Web Search CLI - Brave Search API Integration
*
* A standalone CLI script for searching the web using Brave's Search API.
* Provides web results with descriptions, extra snippets, and localization options.
*
* Usage:
* deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "query"
* deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "query" --freshness pw
* deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts "query" --country US --lang en
* # Or if executable: ./scripts/search.ts "query"
*
* Environment Variables:
* BRAVE_API_KEY - Required. Your Brave Search API key from https://brave.com/search/api/
*
* Permissions:
* --allow-env: Read BRAVE_API_KEY environment variable
* --allow-net=api.search.brave.com: Make API requests to Brave Search
*/
// === Constants ===
const VERSION = "1.0.0";
const SCRIPT_NAME = "search";
const API_BASE = "https://api.search.brave.com/res/v1/web/search";
// === Types ===
export interface BraveResult {
title: string;
url: string;
description: string;
extra_snippets?: string[];
age?: string;
language?: string;
family_friendly?: boolean;
}
export interface BraveResponse {
results: BraveResult[];
query: string;
response_time?: number;
total_results?: number;
}
export interface SearchOptions {
query: string;
count?: number;
freshness?: "pd" | "pw" | "pm" | "py";
country?: string;
searchLang?: string;
safesearch?: "off" | "moderate" | "strict";
extraSnippets?: boolean;
offset?: number;
}
// === Core Logic ===
export async function braveSearch(options: SearchOptions): Promise<BraveResponse> {
const apiKey = Deno.env.get("BRAVE_API_KEY");
if (!apiKey) {
throw new Error("BRAVE_API_KEY environment variable is not set");
}
const params = new URLSearchParams();
params.set("q", options.query);
params.set("count", String(options.count ?? 5));
if (options.freshness) {
params.set("freshness", options.freshness);
}
if (options.country) {
params.set("country", options.country);
}
if (options.searchLang) {
params.set("search_lang", options.searchLang);
}
if (options.safesearch) {
params.set("safesearch", options.safesearch);
}
if (options.extraSnippets) {
params.set("extra_snippets", "true");
}
if (options.offset !== undefined && options.offset > 0) {
params.set("offset", String(options.offset));
}
const startTime = Date.now();
const response = await fetch(`${API_BASE}?${params.toString()}`, {
method: "GET",
headers: {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"X-Subscription-Token": apiKey,
},
});
if (!response.ok) {
const errorText = await response.text();
if (response.status === 401) {
throw new Error("Invalid Brave Search API key");
} else if (response.status === 429) {
throw new Error("Brave Search API rate limit exceeded");
} else if (response.status === 400) {
throw new Error(`Bad request: ${errorText}`);
}
throw new Error(`Brave Search API error (${response.status}): ${errorText}`);
}
const data = await response.json();
const endTime = Date.now();
const webResults = data.web?.results ?? [];
return {
results: webResults.map((r: Record<string, unknown>) => ({
title: (r.title as string) || "",
url: (r.url as string) || "",
description: (r.description as string) || "",
extra_snippets: r.extra_snippets as string[] | undefined,
age: r.age as string | undefined,
language: r.language as string | undefined,
family_friendly: r.family_friendly as boolean | undefined,
})),
query: options.query,
response_time: endTime - startTime,
total_results: data.web?.total_count,
};
}
// === Help Text ===
function printHelp(): void {
console.log(`
${SCRIPT_NAME} v${VERSION} - Web search using Brave Search API
Usage:
deno run --allow-env --allow-net=api.search.brave.com scripts/search.ts [options] "query"
Arguments:
"query" The search query (required)
Options:
--results <n> Number of results (default: 5, max: 20)
--freshness <range> Time filter: pd (day), pw (week), pm (month), py (year)
--country <code> Country code (e.g., US, GB, DE)
--lang <code> Search language (e.g., en, fr, de)
--safesearch <level> Safe search: off, moderate (default), strict
--extra-snippets Include extra content snippets
--offset <n> Pagination offset (default: 0)
--json Output as JSON
-h, --help Show this help
Environment:
BRAVE_API_KEY Required. Get one at https://brave.com/search/api/
Examples:
# Basic search
./scripts/search.ts "React hooks tutorial"
# Search recent results from past week
./scripts/search.ts "AI announcements" --freshness pw
# Localized search
./scripts/search.ts "local news" --country DE --lang de
# Paginated search with extra snippets
./scripts/search.ts "Deno deploy" --results 10 --extra-snippets --json
`);
}
// === Main CLI Handler ===
async function main(args: string[]): Promise<void> {
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
printHelp();
Deno.exit(0);
}
// Parse arguments
const options: SearchOptions = {
query: "",
count: 5,
};
let outputJson = false;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === "--json") {
outputJson = true;
} else if (arg === "--extra-snippets") {
options.extraSnippets = true;
} else if (arg === "--results" && args[i + 1]) {
options.count = Math.min(parseInt(args[++i], 10), 20);
} else if (arg === "--freshness" && args[i + 1]) {
options.freshness = args[++i] as "pd" | "pw" | "pm" | "py";
} else if (arg === "--country" && args[i + 1]) {
options.country = args[++i];
} else if (arg === "--lang" && args[i + 1]) {
options.searchLang = args[++i];
} else if (arg === "--safesearch" && args[i + 1]) {
options.safesearch = args[++i] as "off" | "moderate" | "strict";
} else if (arg === "--offset" && args[i + 1]) {
options.offset = parseInt(args[++i], 10);
} else if (!arg.startsWith("--") && !arg.startsWith("-")) {
options.query = arg;
}
}
if (!options.query) {
console.error("Error: No search query provided\n");
printHelp();
Deno.exit(1);
}
try {
const result = await braveSearch(options);
if (outputJson) {
console.log(JSON.stringify(result, null, 2));
} else {
console.log(`\nSearch: "${result.query}"\n`);
console.log(`Found ${result.results.length} results in ${result.response_time}ms\n`);
for (const [i, r] of result.results.entries()) {
console.log(`${i + 1}. ${r.title}`);
console.log(` ${r.url}`);
console.log(` ${r.description.slice(0, 200)}${r.description.length > 200 ? "..." : ""}`);
if (r.age) {
console.log(` Age: ${r.age}`);
}
if (r.extra_snippets && r.extra_snippets.length > 0) {
console.log(` Extra snippets:`);
for (const snippet of r.extra_snippets) {
console.log(` - ${snippet.slice(0, 150)}${snippet.length > 150 ? "..." : ""}`);
}
}
console.log();
}
}
} catch (error) {
console.error("Error:", error instanceof Error ? error.message : String(error));
Deno.exit(1);
}
}
// === Entry Point ===
if (import.meta.main) {
main(Deno.args);
}
Related skills
How it compares
Choose web-search-brave when Brave API localization and freshness controls matter; use built-in search or Tavily when ranked summaries are enough.
FAQ
What does web-search-brave require to run?
web-search-brave requires a BRAVE_API_KEY environment variable, network access to api.search.brave.com, and Deno to execute scripts/search.ts. The skill defaults to five results but accepts up to 20 per request with optional freshness and locale flags.
When should developers pick web-search-brave over built-in search?
web-search-brave fits when developers need Brave-specific privacy controls, country or language targeting, or freshness filters like past day or past week. Built-in search or Tavily may be simpler when those Brave API controls are not required.