From 1de793fb8d9aa796a6407bac96f6d0f8ee09539f Mon Sep 17 00:00:00 2001 From: zap Date: Tue, 10 Mar 2026 19:55:44 +0000 Subject: [PATCH] feat(search): add local meta search wrapper --- skills/local-meta-search/SKILL.md | 36 +++++++++++++ skills/local-meta-search/scripts/search.sh | 61 ++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 skills/local-meta-search/SKILL.md create mode 100755 skills/local-meta-search/scripts/search.sh diff --git a/skills/local-meta-search/SKILL.md b/skills/local-meta-search/SKILL.md new file mode 100644 index 0000000..fb7ee1e --- /dev/null +++ b/skills/local-meta-search/SKILL.md @@ -0,0 +1,36 @@ +--- +name: local-meta-search +description: Search via local SearXNG first and automatically fall back to the local Brave MCP service when SearXNG is unavailable or weak. Use for normal web lookups when privacy/local-first search is preferred. +metadata: + openclaw: + requires: + bins: ["bash", "jq", "mcporter", "bb"] + emoji: "🧭" +--- + +# Local Meta Search + +## Policy + +1. Try **SearXNG first**. +2. If SearXNG fails or returns weak/empty output, try **Brave MCP**. +3. Clearly label which backend produced the final results. + +## Backends + +- SearXNG: `skills/searxng-local-search/scripts/search.sh` +- Brave MCP: `skills/brave-mcp-search/scripts/search.sh` + +## Quick usage + +```bash +scripts/search.sh "query" +``` + +Optional JSON options: + +```bash +scripts/search.sh "query" '{"count":5}' +``` + +Options are passed through as best-effort to the underlying backend. diff --git a/skills/local-meta-search/scripts/search.sh b/skills/local-meta-search/scripts/search.sh new file mode 100755 index 0000000..6569de7 --- /dev/null +++ b/skills/local-meta-search/scripts/search.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="/home/openclaw/.openclaw/workspace" +SEARX_SCRIPT="$ROOT/skills/searxng-local-search/scripts/search.sh" +BRAVE_SCRIPT="$ROOT/skills/brave-mcp-search/scripts/search.sh" + +if [[ $# -lt 1 ]]; then + echo 'Usage: scripts/search.sh "query" '\''{"count":5}'\''' >&2 + exit 1 +fi + +QUERY="$1" +OPTS="${2:-}" +TMP1="$(mktemp)" +TMP2="$(mktemp)" +trap 'rm -f "$TMP1" "$TMP2"' EXIT + +run_searx() { + if [[ -n "$OPTS" ]]; then + "$SEARX_SCRIPT" "$QUERY" "$OPTS" >"$TMP1" 2>&1 + else + "$SEARX_SCRIPT" "$QUERY" >"$TMP1" 2>&1 + fi +} + +run_brave() { + if [[ -n "$OPTS" ]]; then + "$BRAVE_SCRIPT" "$QUERY" "$OPTS" >"$TMP2" 2>&1 + else + "$BRAVE_SCRIPT" "$QUERY" >"$TMP2" 2>&1 + fi +} + +searx_good=false +if run_searx; then + if grep -qE '^[0-9]+\.' "$TMP1"; then + searx_good=true + fi +fi + +if [[ "$searx_good" == true ]]; then + printf 'Backend: SearXNG\n\n' + cat "$TMP1" + exit 0 +fi + +if run_brave; then + printf 'Backend: Brave MCP (fallback)\n\n' + cat "$TMP2" + exit 0 +fi + +echo 'Error: both SearXNG and Brave MCP failed.' >&2 +echo >&2 +echo '--- SearXNG output ---' >&2 +cat "$TMP1" >&2 || true +echo >&2 +echo '--- Brave MCP output ---' >&2 +cat "$TMP2" >&2 || true +exit 3