Skip to content

Commit a59d6ac

Browse files
vrijmetseMustafa Abdat
andauthored
refactor(tools): add multi-provider support to web_search tool (aden-hive#795)
* feat(tools): add Google Custom Search as alternative to Brave Search Adds google_search tool using Google Custom Search API as an alternative to the existing web_search tool (Brave Search). Changes: - Add google_search_tool with full implementation - Register Google credentials (GOOGLE_API_KEY, GOOGLE_CSE_ID) - Register tool in tools/__init__.py - Add README with setup instructions Closes aden-hive#793 * test(tools): add unit tests for google_search tool Adds 7 tests mirroring web_search_tool test patterns: - Missing API key error handling - Missing CSE ID error handling - Empty query validation - Long query validation - num_results clamping - Default parameters - Custom language/country parameters All tests pass. * refactor(tools): add multi-provider support to web_search tool BREAKING CHANGE: None - backward compatible. Brave remains default. - Add Google Custom Search as alternative provider in web_search - Add 'provider' parameter: 'auto' (default), 'google', 'brave' - Auto mode tries Brave first for backward compatibility - Remove separate google_search_tool (consolidated into web_search) - Update tests to cover multi-provider functionality (13 tests) - Update README documentation Users with BRAVE_SEARCH_API_KEY: No changes needed Users with GOOGLE_API_KEY + GOOGLE_CSE_ID: Can use provider='google' Users with both: Brave preferred by default, use provider='google' to force Closes aden-hive#793 * feat(tools): fixed readme --------- Co-authored-by: Mustafa Abdat <abdamus@hilti.com>
1 parent 9d39c09 commit a59d6ac

File tree

6 files changed

+357
-105
lines changed

6 files changed

+357
-105
lines changed

tools/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ cp .env.example .env
2525
| Variable | Required For | Get Key |
2626
| ---------------------- | ----------------------------- | ------------------------------------------------------- |
2727
| `ANTHROPIC_API_KEY` | MCP server startup, LLM nodes | [console.anthropic.com](https://console.anthropic.com/) |
28-
| `BRAVE_SEARCH_API_KEY` | `web_search` tool | [brave.com/search/api](https://brave.com/search/api/) |
28+
| `BRAVE_SEARCH_API_KEY` | `web_search` tool (Brave) | [brave.com/search/api](https://brave.com/search/api/) |
29+
| `GOOGLE_API_KEY` | `web_search` tool (Google) | [console.cloud.google.com](https://console.cloud.google.com/) |
30+
| `GOOGLE_CSE_ID` | `web_search` tool (Google) | [programmablesearchengine.google.com](https://programmablesearchengine.google.com/) |
31+
32+
> **Note:** `web_search` supports multiple providers. Set either Brave OR Google credentials. Brave is preferred for backward compatibility.
2933
3034
Alternatively, export as environment variables:
3135

@@ -68,7 +72,7 @@ python mcp_server.py
6872
| `apply_patch` | Apply unified patches to files |
6973
| `grep_search` | Search file contents with regex |
7074
| `execute_command_tool` | Execute shell commands |
71-
| `web_search` | Search the web using Brave Search API |
75+
| `web_search` | Search the web (Google or Brave, auto-detected) |
7276
| `web_scrape` | Scrape and extract content from webpages |
7377
| `pdf_read` | Read and extract text from PDF files |
7478

tools/src/aden_tools/credentials/search.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
Contains credentials for search providers like Brave Search, Google, Bing, etc.
55
"""
6+
67
from .base import CredentialSpec
78

89
SEARCH_CREDENTIALS = {
@@ -15,14 +16,22 @@
1516
help_url="https://brave.com/search/api/",
1617
description="API key for Brave Search",
1718
),
18-
# Future search providers:
19-
# "google_search": CredentialSpec(
20-
# env_var="GOOGLE_SEARCH_API_KEY",
21-
# tools=["google_search"],
22-
# node_types=[],
23-
# required=True,
24-
# startup_required=False,
25-
# help_url="https://developers.google.com/custom-search/v1/overview",
26-
# description="API key for Google Custom Search",
27-
# ),
19+
"google_search": CredentialSpec(
20+
env_var="GOOGLE_API_KEY",
21+
tools=["google_search"],
22+
node_types=[],
23+
required=True,
24+
startup_required=False,
25+
help_url="https://console.cloud.google.com/",
26+
description="API key for Google Custom Search",
27+
),
28+
"google_cse": CredentialSpec(
29+
env_var="GOOGLE_CSE_ID",
30+
tools=["google_search"],
31+
node_types=[],
32+
required=True,
33+
startup_required=False,
34+
help_url="https://programmablesearchengine.google.com/",
35+
description="Google Custom Search Engine ID",
36+
),
2837
}

tools/src/aden_tools/tools/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
credentials = CredentialManager()
1111
register_all_tools(mcp, credentials=credentials)
1212
"""
13+
1314
from typing import List, Optional, TYPE_CHECKING
1415

1516
from fastmcp import FastMCP
@@ -27,11 +28,15 @@
2728
from .file_system_toolkits.view_file import register_tools as register_view_file
2829
from .file_system_toolkits.write_to_file import register_tools as register_write_to_file
2930
from .file_system_toolkits.list_dir import register_tools as register_list_dir
30-
from .file_system_toolkits.replace_file_content import register_tools as register_replace_file_content
31+
from .file_system_toolkits.replace_file_content import (
32+
register_tools as register_replace_file_content,
33+
)
3134
from .file_system_toolkits.apply_diff import register_tools as register_apply_diff
3235
from .file_system_toolkits.apply_patch import register_tools as register_apply_patch
3336
from .file_system_toolkits.grep_search import register_tools as register_grep_search
34-
from .file_system_toolkits.execute_command_tool import register_tools as register_execute_command
37+
from .file_system_toolkits.execute_command_tool import (
38+
register_tools as register_execute_command,
39+
)
3540
from .csv_tool import register_tools as register_csv
3641

3742

@@ -56,9 +61,7 @@ def register_all_tools(
5661
register_pdf_read(mcp)
5762

5863
# Tools that need credentials (pass credentials if provided)
59-
# web_search handles both credential sources internally:
60-
# - If credentials provided: uses credentials.get("brave_search")
61-
# - If credentials is None: falls back to os.getenv("BRAVE_SEARCH_API_KEY")
64+
# web_search supports multiple providers (Google, Brave) with auto-detection
6265
register_web_search(mcp, credentials=credentials)
6366

6467
# Register file system toolkits

tools/src/aden_tools/tools/web_search_tool/README.md

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,64 @@
11
# Web Search Tool
22

3-
Search the web using the Brave Search API.
3+
Search the web using multiple providers with automatic detection.
44

55
## Description
66

77
Returns titles, URLs, and snippets for search results. Use when you need current information, research topics, or find websites.
88

9+
Supports multiple search providers:
10+
- **Brave Search API** (default, for backward compatibility)
11+
- **Google Custom Search API** (fallback)
12+
913
## Arguments
1014

1115
| Argument | Type | Required | Default | Description |
1216
|----------|------|----------|---------|-------------|
1317
| `query` | str | Yes | - | The search query (1-500 chars) |
14-
| `num_results` | int | No | `10` | Number of results to return (1-20) |
15-
| `country` | str | No | `us` | Country code for localized results (us, uk, de, etc.) |
18+
| `num_results` | int | No | `10` | Number of results (1-10 for Google, 1-20 for Brave) |
19+
| `country` | str | No | `us` | Country code for localized results |
20+
| `language` | str | No | `en` | Language code (Google only) |
21+
| `provider` | str | No | `auto` | Provider: "auto", "google", or "brave" |
1622

1723
## Environment Variables
1824

25+
Set credentials for at least one provider:
26+
27+
### Option 1: Google Custom Search
28+
| Variable | Required | Description |
29+
|----------|----------|-------------|
30+
| `GOOGLE_API_KEY` | Yes | API key from [Google Cloud Console](https://console.cloud.google.com/) |
31+
| `GOOGLE_CSE_ID` | Yes | Search Engine ID from [Programmable Search Engine](https://programmablesearchengine.google.com/) |
32+
33+
### Option 2: Brave Search
1934
| Variable | Required | Description |
2035
|----------|----------|-------------|
2136
| `BRAVE_SEARCH_API_KEY` | Yes | API key from [Brave Search API](https://brave.com/search/api/) |
2237

38+
## Provider Selection
39+
40+
- `provider="auto"` (default): Uses Brave if available, otherwise Google (backward compatible)
41+
- `provider="brave"`: Force Brave Search
42+
- `provider="google"`: Force Google Custom Search
43+
44+
## Example Usage
45+
46+
```python
47+
# Auto-detect provider based on available credentials
48+
result = web_search(query="climate change effects")
49+
50+
# Force specific provider
51+
result = web_search(query="python tutorial", provider="google")
52+
result = web_search(query="local news", provider="brave", country="id")
53+
```
54+
2355
## Error Handling
2456

2557
Returns error dicts for common issues:
26-
- `BRAVE_SEARCH_API_KEY environment variable not set` - Missing API key
58+
- `No search credentials configured` - No API keys set
59+
- `Google credentials not configured` - Missing Google keys when provider="google"
60+
- `Brave credentials not configured` - Missing Brave key when provider="brave"
2761
- `Query must be 1-500 characters` - Empty or too long query
28-
- `Invalid API key` - API key rejected (HTTP 401)
29-
- `Rate limit exceeded. Try again later.` - Too many requests (HTTP 429)
62+
- `Invalid API key` - API key rejected
63+
- `Rate limit exceeded` - Too many requests
3064
- `Search request timed out` - Request exceeded 30s timeout
31-
- `Network error: <error>` - Connection or DNS issues

0 commit comments

Comments
 (0)