Install
openclaw skills install live-searchReal-time answers from the public web via the host app’s local search gateway (Auth Gateway proxy). Typical stacks surface results comparable to major engine...
openclaw skills install live-searchFetch live web results through the host search gateway at http://localhost:$PORT (session-authenticated). The gateway returns JSON with a pre-rendered message (titles as links, snippets, sources)—the same kind of web index results users expect from Google-style or Bing-style search, depending on how the host is configured.
Endpoint path: requests use POST /proxy/prosearch/search. The prosearch segment is a fixed gateway route name in the app; it is not a public product brand to repeat to end users—describe outcomes as “web search results” or “live search.”
No extra Python packages. Search goes through the local gateway at http://localhost:$PORT; authentication is handled by the host app (login session)—no manual API keys in typical setups.
The assistant uses this skill whenever the user needs real-time information from the web.
User asks for something that needs live web data
→ Step 1: Build a tight search keyword (concise, specific)
→ Step 1.5: Decide time freshness — add from_time when recency matters
→ Step 2: Call the search API with curl
→ Step 3: Echo the JSON `message` field VERBATIM (result list with clickable links) — do NOT skip this
→ Step 4: Optionally add analysis/summary after the verbatim block
CRITICAL — Anti-hallucination: The API returns a pre-rendered
messagewith formatted hits (titles as Markdown links, snippets, URLs). The assistant MUST showmessageverbatim as the primary results. It may add interpretation after that block. It must not invent, rewrite, or drop URLs/titles frommessage.
Turn the user’s question into a short query:
| User intent | Example keyword |
|---|---|
| Latest AI news | latest AI news March 2026 or 最新 AI 新闻 (match user language) |
| Gold price now | gold spot price today |
| React 19 features | React 19 new features |
| Local weather | London weather today |
Keyword tips:
today, 2026, latest).When the question implies recency, add from_time (Unix seconds) so stale pages are filtered out.
| User signal | from_time | Typical use |
|---|---|---|
| “today”, “just now”, “past 24h” | now − 86400 | Intraday facts |
| “recent”, “latest”, “this week” | now − 604800 | News, releases |
| “this month” | now − 2592000 | Monthly topics |
| “this year”, “2026” | Jan 1 of that year (local) | Year-scoped events |
| No time signal | omit from_time | Evergreen facts (“What is React?”) |
Compute from_time in bash:
# Last 24 hours
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 86400)")
# Last 7 days
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 604800)")
# Last 30 days
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 2592000)")
Mutual exclusion: When using
from_time/to_time, do not sendcnt— the server enforces exclusion rules. Same forsite+ time filters; follow the API’s rules.
PORT=${AUTH_GATEWAY_PORT:-19000}
PPID_VAL=$(python3 -c "import os; print(os.getppid())")
echo "[Assistant] Parent PID: $PPID_VAL"
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"your search query"}'
Freshness (recommended for time-sensitive queries):
# Last 7 days (“latest”, “recent”)
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 604800)")
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d "{\"keyword\":\"your search query\",\"from_time\":$FROM_TIME}"
# Last 24 hours (“today”, “just now”)
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 86400)")
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d "{\"keyword\":\"your search query\",\"from_time\":$FROM_TIME}"
Optional parameters:
# Result count 10/20/30/40/50 — do not combine with from_time/to_time/site
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"your search query","cnt":20}'
# Time range (do not pass cnt)
FROM_TIME=$(python3 -c "import time; print(int(time.time()) - 604800)")
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d "{\"keyword\":\"your search query\",\"from_time\":$FROM_TIME}"
# Site-restricted search (do not pass cnt)
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"your search query","site":"github.com"}'
# Vertical: gov / news / acad
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"your search query","industry":"news"}'
message first, then analysisAfter JSON returns:
Output the message field exactly as returned. It usually contains up to five top hits, each formatted like:
**n. [Title](url)** — Site (date) ⭐
Snippet...
CRITICAL: Never skip the list and jump to a summary. Titles are already Markdown links; users must be able to click through.
Language for your added commentary: align with the user’s conversation language and the query language when helpful:
message block is always copied verbatim, regardless of language.API returns a long `message` string with numbered results and snippets.
Assistant output:
<paste entire message verbatim>
---
Brief synthesis: … (optional, grounded in what appeared above)
data.docs instead of using message.message.message.Use AUTH_GATEWAY_PORT from the environment (set by the Electron host when the Auth Gateway starts). Child processes inherit it.
macOS / Linux (bash):
PORT=${AUTH_GATEWAY_PORT:-19000}
echo "[Assistant] AUTH_GATEWAY_PORT: $PORT"
Windows (PowerShell):
$PORT = if ($env:AUTH_GATEWAY_PORT) { $env:AUTH_GATEWAY_PORT } else { "19000" }
Write-Host "[Assistant] AUTH_GATEWAY_PORT: $PORT"
Windows (CMD):
if not defined AUTH_GATEWAY_PORT set AUTH_GATEWAY_PORT=19000
set PORT=%AUTH_GATEWAY_PORT%
echo [Assistant] AUTH_GATEWAY_PORT: %PORT%
Default if unset: 19000.
Before curl, you may log the parent PID for tracing.
macOS / Linux:
PPID_VAL=$(python3 -c "import os; print(os.getppid())")
echo "[Assistant] Parent PID: $PPID_VAL"
Windows (PowerShell):
$PPID_VAL = python -c "import os; print(os.getppid())"
Write-Host "[Assistant] Parent PID: $PPID_VAL"
searchPOST /proxy/prosearch/search
Content-Type: application/json
{
"keyword": "<search-query>", // required, UTF-8
"mode": 0, // optional: 0=web 1=VR card 2=hybrid
"cnt": 10, // optional: 10/20/30/40/50
"site": "<domain>", // optional: site-restricted
"from_time": 1710000000, // optional: start (epoch seconds)
"to_time": 1711000000, // optional: end (epoch seconds)
"industry": "news" // optional: gov | news | acad
}
Fields:
keyword (required): query string.mode: 0 default web results; 1 VR “card” style facts (e.g. weather, spot prices); 2 hybrid.cnt: max hits; mutually exclusive with site and from_time/to_time per backend rules.site: restrict to a domain.from_time / to_time: time window in epoch seconds.industry: gov (government), news, acad (academic-oriented).Do not combine
cntwith time filters orsitewhen the API forbids it.
Examples:
PORT=${AUTH_GATEWAY_PORT:-19000}
echo "[Assistant] AUTH_GATEWAY_PORT: $PORT"
PPID_VAL=$(python3 -c "import os; print(os.getppid())")
echo "[Assistant] Parent PID: $PPID_VAL"
# Basic
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"latest AI news"}'
# More results (no time/site)
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"React 19 features","cnt":20}'
# News vertical
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"Federal Reserve statement March 2026","industry":"news"}'
# GitHub-only
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"electron vite template","site":"github.com"}'
# Hybrid mode for structured + web (e.g. commodity spot, weather) — adjust keyword to your locale
curl -s -X POST http://localhost:$PORT/proxy/prosearch/search \
-H 'Content-Type: application/json' \
-d '{"keyword":"gold spot price today","mode":2}'
Success JSON (shape):
{
"success": true,
"message": "Search results for \"latest AI news\"…\n\n**1. [Title](https://…)** — Source (2026-03-15) ⭐\n Snippet…",
"data": {
"query": "latest AI news",
"totalResults": 10,
"docs": [
{
"passage": "…",
"score": 0.85,
"date": "2026-03-15",
"title": "…",
"url": "https://…",
"site": "…",
"images": []
}
],
"requestId": "…"
}
}
messageis the source of truth for what to show users — copy it in full before adding commentary.
Failure JSON (examples; actual strings may be localized by the host):
{
"success": false,
"message": "Not signed in. Web search requires an active session. Please sign in and try again."
}
{
"success": false,
"message": "Search timed out (15s). Please try again."
}
Responses are JSON on stdout. Errors use {"success": false, "message": "..."}.
| Situation | What to do |
|---|---|
Not authenticated (message indicates login required) | Tell the user to sign in, then retry. |
| Timeout | Retry once; if it fails again, relay the error. |
Empty docs but success: true | Still output message; it usually explains there were no hits. |
| Network / connection | Retry once after ~3s; else show message. |
| HTTP errors | Surface message from the API when present. |
data.docs instead of echoing message.message.message.from_time as in Step 1.5.mode: 2 when supported.cnt vs time/site: respect mutual exclusion — see above.message stays verbatim.