Serper
Google search via Serper API. Fetches results AND reads the actual web pages to extract clean full-text content via trafilatura. Not just snippets — full article text.
How It Works
- Serper API call — fast Google search, returns result URLs instantly
- Concurrent page scraping — all result pages are fetched and extracted in parallel using trafilatura with a 3-second timeout per page
- Streamed output — results print one at a time as each page finishes
Each invocation gives you 5 results (default mode) or up to 6 results (current mode), each with full page content. This is already a lot of information.
Query Discipline
Craft ONE good search query. That is almost always enough.
Each call returns multiple results with full page text — you get broad coverage from a single query. Do not run multiple searches to "explore" a topic. One well-chosen query with the right mode covers it.
At most two calls if the user's request genuinely spans two distinct topics (e.g. "compare X vs Y" where X and Y need separate searches, or one default + one current call for different aspects). Never more than two.
Do NOT:
- Run the same query with different wording to "get more results"
- Run sequential searches to "dig deeper" — the full page content is already deep
- Run one search to find something, then another to follow up — read the content you already have
When to Use This Skill
Use serper when:
- Any question that needs current, factual information from the web
- Research topics that need full article content, not just snippets
- News and current events
- Product info, prices, comparisons, reviews
- Technical docs, how-to guides
- Anything where reading the actual page matters
Do NOT use this skill for:
- Questions you can answer from your training data
- Pure math, code execution, creative writing
- Greetings, chitchat
IMPORTANT: This skill already fetches and extracts full page content. Do NOT use web_fetch, WebFetch, or any other URL-fetching tool on the URLs returned by this skill. The content is already included in the output.
Two Search Modes
There are exactly two modes. Pick the right one based on the query:
default — General search (all-time)
- All-time Google web search, 5 results, each enriched with full page content
- Use for: general questions, research, how-to, evergreen topics, product info, technical docs, comparisons, tutorials, anything NOT time-sensitive
current — News and recent info
- Past-week Google web search (3 results) + Google News (3 results), each enriched with full page content
- Use for: news, current events, recent developments, breaking news, announcements, anything time-sensitive
Mode Selection Guide
| Query signals |
Mode |
| "how does X work", "what is X", "explain X" |
default |
| Product research, comparisons, tutorials |
default |
| Technical documentation, guides |
default |
| Historical topics, evergreen content |
default |
| "news", "latest", "today", "this week", "recent" |
current |
| "what happened", "breaking", "announced", "released" |
current |
| Current events, politics, sports scores, stock prices |
current |
Locale (REQUIRED for non-English queries)
Default is global — no country filter, English results. This ONLY works for English queries.
You MUST ALWAYS set --gl and --hl when ANY of these are true:
- The user's message is in a non-English language
- The search query you construct is in a non-English language
- The user mentions a specific country, city, or region
- The user asks for local results (prices, news, stores, etc.) in a non-English context
If the user writes in German, you MUST pass --gl de --hl de. No exceptions.
| Scenario |
Flags |
| English query, no country target |
(omit --gl and --hl) |
| German query OR user writes in German OR targeting DE/AT/CH |
--gl de --hl de |
| French query OR user writes in French OR targeting France |
--gl fr --hl fr |
| Any other non-English language/country |
--gl XX --hl XX (ISO codes) |
Rule of thumb: If the query string contains non-English words, set --gl and --hl to match that language.
How to Invoke
python3 scripts/search.py -q "QUERY" [--mode MODE] [--gl COUNTRY] [--hl LANG]
Examples
# English, general research
python3 scripts/search.py -q "how does HTTPS work"
# English, time-sensitive
python3 scripts/search.py -q "OpenAI latest announcements" --mode current
# German query — set locale + current mode for news/prices
python3 scripts/search.py -q "aktuelle Preise iPhone" --mode current --gl de --hl de
# German news
python3 scripts/search.py -q "Nachrichten aus Berlin" --mode current --gl de --hl de
# French product research
python3 scripts/search.py -q "meilleur smartphone 2026" --gl fr --hl fr
Output Format
The output is a streamed JSON array — elements print one at a time as each page is scraped:
[{"query": "...", "mode": "default", "locale": {"gl": "world", "hl": "en"}, "results": [{"title": "...", "url": "...", "source": "web"}, ...]}
,{"title": "...", "url": "...", "source": "web", "content": "Full extracted page text..."}
,{"title": "...", "url": "...", "source": "news", "date": "2 hours ago", "content": "Full article text..."}
]
The first element is search metadata. Each following element contains a result with full extracted content.
Result fields:
title — page title
url — source URL
source — "web", "news", or "knowledge_graph"
content — full extracted page text (falls back to search snippet if extraction fails)
date — present when available (news results always, web results sometimes)
CLI Reference
| Flag |
Description |
-q, --query |
Search query (required) |
-m, --mode |
default (all-time, 5 results) or current (past week + news, 3 each) |
--gl |
Country code (e.g. de, us, fr, at, ch) |
--hl |
Language code (e.g. en, de, fr) |
1---2name: serper3description: Google search via Serper API with full page content extraction. Fast API lookup + concurrent page scraping (3s timeout). One well-crafted query returns rich results — avoid multiple calls. Two modes, explicit locale control. API key via .env.4---5
6# Serper
7
8Google search via Serper API. Fetches results AND reads the actual web pages to extract clean full-text content via trafilatura. Not just snippets — full article text.
9
10### How It Works
11
121. **Serper API call** — fast Google search, returns result URLs instantly
132. **Concurrent page scraping** — all result pages are fetched and extracted in parallel using trafilatura with a **3-second timeout per page**
143. **Streamed output** — results print one at a time as each page finishes
15
16Each invocation gives you 5 results (default mode) or up to 6 results (current mode), each with full page content. This is already a lot of information.
17
18---
19
20## Query Discipline
21
22**Craft ONE good search query. That is almost always enough.**
23
24Each call returns multiple results with full page text — you get broad coverage from a single query. Do not run multiple searches to "explore" a topic. One well-chosen query with the right mode covers it.
25
26**At most two calls** if the user's request genuinely spans two distinct topics (e.g. "compare X vs Y" where X and Y need separate searches, or one `default` + one `current` call for different aspects). Never more than two.
27
28**Do NOT:**
29- Run the same query with different wording to "get more results"
30- Run sequential searches to "dig deeper" — the full page content is already deep
31- Run one search to find something, then another to follow up — read the content you already have
32
33---
34
35## When to Use This Skill
36
37**Use serper when:**
38- Any question that needs current, factual information from the web
39- Research topics that need full article content, not just snippets
40- News and current events
41- Product info, prices, comparisons, reviews
42- Technical docs, how-to guides
43- Anything where reading the actual page matters
44
45**Do NOT use this skill for:**
46- Questions you can answer from your training data
47- Pure math, code execution, creative writing
48- Greetings, chitchat
49
50**IMPORTANT: This skill already fetches and extracts full page content. Do NOT use web_fetch, WebFetch, or any other URL-fetching tool on the URLs returned by this skill. The content is already included in the output.**
51
52---
53
54## Two Search Modes
55
56There are exactly two modes. Pick the right one based on the query:
57
58### `default` — General search (all-time)
59- All-time Google web search, **5 results**, each enriched with full page content
60- Use for: general questions, research, how-to, evergreen topics, product info, technical docs, comparisons, tutorials, anything NOT time-sensitive
61
62### `current` — News and recent info
63- Past-week Google web search (3 results) + Google News (3 results), each enriched with full page content
64- Use for: news, current events, recent developments, breaking news, announcements, anything time-sensitive
65
66#### Mode Selection Guide
67
68| Query signals | Mode |
69|---------------|------|
70| "how does X work", "what is X", "explain X" | `default` |
71| Product research, comparisons, tutorials | `default` |
72| Technical documentation, guides | `default` |
73| Historical topics, evergreen content | `default` |
74| "news", "latest", "today", "this week", "recent" | `current` |
75| "what happened", "breaking", "announced", "released" | `current` |
76| Current events, politics, sports scores, stock prices | `current` |
77
78---
79
80## Locale (REQUIRED for non-English queries)
81
82**Default is global** — no country filter, English results. This ONLY works for English queries.
83
84**You MUST ALWAYS set `--gl` and `--hl` when ANY of these are true:**
85- The user's message is in a non-English language
86- The search query you construct is in a non-English language
87- The user mentions a specific country, city, or region
88- The user asks for local results (prices, news, stores, etc.) in a non-English context
89
90**If the user writes in German, you MUST pass `--gl de --hl de`. No exceptions.**
91
92| Scenario | Flags |
93|----------|-------|
94| English query, no country target | *(omit --gl and --hl)* |
95| German query OR user writes in German OR targeting DE/AT/CH | `--gl de --hl de` |
96| French query OR user writes in French OR targeting France | `--gl fr --hl fr` |
97| Any other non-English language/country | `--gl XX --hl XX` (ISO codes) |
98
99**Rule of thumb:** If the query string contains non-English words, set `--gl` and `--hl` to match that language.
100
101---
102
103## How to Invoke
104
105```bash
106python3 scripts/search.py -q "QUERY" [--mode MODE] [--gl COUNTRY] [--hl LANG]
107```
108
109### Examples
110
111```bash
112# English, general research
113python3 scripts/search.py -q "how does HTTPS work"
114
115# English, time-sensitive
116python3 scripts/search.py -q "OpenAI latest announcements" --mode current
117
118# German query — set locale + current mode for news/prices
119python3 scripts/search.py -q "aktuelle Preise iPhone" --mode current --gl de --hl de
120
121# German news
122python3 scripts/search.py -q "Nachrichten aus Berlin" --mode current --gl de --hl de
123
124# French product research
125python3 scripts/search.py -q "meilleur smartphone 2026" --gl fr --hl fr
126
127```
128
129---
130
131## Output Format
132
133The output is a **streamed JSON array** — elements print one at a time as each page is scraped:
134
135```json
136[{"query": "...", "mode": "default", "locale": {"gl": "world", "hl": "en"}, "results": [{"title": "...", "url": "...", "source": "web"}, ...]}
137,{"title": "...", "url": "...", "source": "web", "content": "Full extracted page text..."}
138,{"title": "...", "url": "...", "source": "news", "date": "2 hours ago", "content": "Full article text..."}
139]
140```
141
142The first element is search metadata. Each following element contains a result with full extracted content.
143
144Result fields:
145- `title` — page title
146- `url` — source URL
147- `source` — `"web"`, `"news"`, or `"knowledge_graph"`
148- `content` — full extracted page text (falls back to search snippet if extraction fails)
149- `date` — present when available (news results always, web results sometimes)
150
151---
152
153## CLI Reference
154
155| Flag | Description |
156|------|-------------|
157| `-q, --query` | Search query (required) |
158| `-m, --mode` | `default` (all-time, 5 results) or `current` (past week + news, 3 each) |
159| `--gl` | Country code (e.g. `de`, `us`, `fr`, `at`, `ch`) |
160| `--hl` | Language code (e.g. `en`, `de`, `fr`) |