Skip to content

Repository files navigation

Brave API

PyPI version Python versions CI Semantic release Documentation License Typed Python

An async Python client for Brave Search, providing streaming AI answers and structured web search in a single, typed interface - with a built-in Model Context Protocol (MCP) server.


Features

  • Brave Ask — complete answers with citations, incremental streaming, follow-up conversations, and optional image input.
  • Brave Search — typed results for web, images, news, videos, and Brave Goggles, with page-based pagination and autocomplete suggestions.
  • Reliable async client — one async with BraveClient() interface with typed Pydantic models, configurable language/region/safe search, timeouts, retries, concurrency, and proxies.
  • MCP server — expose Ask and Search tools to MCP-compatible AI applications over stdio or HTTP.
  • Developer examples — runnable examples for vertical search, streaming, conversations, multimodal input, configuration, and MCP.

Brave Daily showcase

Brave Daily is the live showcase built with this package. It turns Brave Search and Brave Ask into a daily intelligence dashboard with six modules:

  1. Global Pulse — technology, geopolitics, finance, cybersecurity, and science coverage with source diversity and editorial summaries.
  2. Trend Radar — article-volume signals for topics such as AI, quantum computing, space, climate, robotics, and semiconductors.
  3. Threat Wire — cybersecurity and OSINT news with severity classification and extracted CVE/IP indicators.
  4. Market Scanner — crypto, equities, and macroeconomic headlines with Ask-based sentiment summaries.
  5. Data Lab — downloadable JSON, CSV, Markdown, and a lightweight threat feed.
  6. Search Playground — live examples of search(), search_news(), search_images(), search_videos(), and ask() with the corresponding Python snippets.

The dashboard is generated by brave_daily/generate.py and deployed to GitHub Pages by .github/workflows/brave-daily.yml. To generate it locally:

uv run python brave_daily/generate.py --output brave_daily/dist
python -m http.server 8000 --directory brave_daily/dist

Then open http://127.0.0.1:8000. A fresh edition requires a working Brave connection; optional enrichment failures fall back to an explicit unavailable or fallback result so the static dashboard can still be published.

Documentation

The complete documentation is available at brave-api.readthedocs.io.

It includes detailed guides, configuration, MCP setup, examples, error handling, and the generated API reference.

Installation

Requires Python 3.11+.

uv add brave-api-python

For MCP support:

uv add "brave-api-python[mcp]"

With pip:

pip install brave-api-python

From source:

git clone https://github.com/iqbalmh18/brave-api.git
cd brave-api
uv sync --group dev

Quick start

Ask

import asyncio

from brave_api import BraveClient


async def main() -> None:
    async with BraveClient() as client:
        result = await client.ask("What is quantum computing?")

    print(result.text)
    print(f"Sources: {len(result.urls)}")


asyncio.run(main())

Search

async with BraveClient() as client:
    result = await client.search("Python asyncio tutorial")

for item in result.web[:3]:
    print(item.title, item.url)

All public methods are asynchronous and should normally be used inside async with BraveClient().

Search verticals

Every search method returns the same SearchResult response envelope:

async with BraveClient() as client:
    web = await client.search("Python asyncio")
    images = await client.search_images("Python logo")
    news = await client.search_news("Python release")
    videos = await client.search_videos("Python tutorial")
    goggles = await client.search_goggles("privacy search")

print(web.web)
print(images.images)
print(news.news)
print(videos.videos)
print(goggles.web)

Pagination uses Brave's page-based offset value, where 0 is the first page:

async with BraveClient() as client:
    first_page = await client.search_news("Python release", offset=0)
    second_page = await client.search_news("Python release", offset=1)

Use spellcheck=False for exact keyword matching. Use client.suggest() for autocomplete suggestions.

Streaming

from brave_api import BraveClient, StreamEventType

async with BraveClient() as client:
    async for event in client.ask_stream("Explain WebAssembly"):
        if event.type is StreamEventType.TEXT_DELTA:
            print(event.delta, end="", flush=True)

Configuration

from brave_api import BraveClient, ClientConfig

config = ClientConfig(
    language="id",
    ui_lang="id-id",
    country="id",
    safesearch="moderate",
    timeout=60.0,
    max_retries=3,
    proxies=["http://user:password@proxy.example:8080"],
)

async with BraveClient(config) as client:
    result = await client.search("berita teknologi")

See the configuration guide for all supported options.

MCP server

Install the optional MCP dependency:

uv add "brave-api-python[mcp]"

Run locally over stdio:

brave-api-mcp

Or run an HTTP server:

brave-api-mcp --http --host 127.0.0.1 --port 8000

Available search tools include search, search_images, search_news, search_videos, search_goggles, and suggest, in addition to ask.

Examples

Runnable examples are available in examples/:

Run one with:

uv run python examples/search_verticals.py

Development

uv sync --group dev
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright

For API details, error handling, conversations, and complete MCP configuration, see the full documentation.

Star History

Star History Chart

License

MIT. See LICENSE.

About

Brave API is totally free. No login. No API key. No bullshit.

Topics

Resources

Contributing

Stars

53 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages