Files
Frank 689228e60d docs: purge the retired workstation from the knowledge base
Second half of the purge (the first covered the persona, AGENTS.md, README.md,
and the distillation of the per-host pages). Every remaining identifier is
gone: hostname, both LAN addresses, and the Wi-Fi SSID.

34 count-checked substitutions across 22 files — indexes, tool/research pages,
the inventory census, the changelog, one generated HTML report, and five
managed skills. Facts kept, names dropped: a history entry keeps its four-page
listing as a nameless summary, the syslog excerpts keep every timestamp and
line, and the census keeps the .zcompdump rows (the zsh version stamps are the
useful part, the hostname was not).

Deliberately unchanged: install.sh's --host case list and the
packages/<hostname>.pkgs filename, where the hostname is the lookup key.

Left out of scope by Frank's call: agent/memories/** — past-session records the
learn pipeline rewrites.

kb-lint: 0 violations. Residual grep for the hostname, its two IPs, and the
SSID across omp-docs/ and agent/managed-skills/: no hits.
2026-09-28 16:37:38 -07:00

4.6 KiB

type, title, description, tags, timestamp
type title description tags timestamp
reference Pi Web Access Web search, URL fetching, GitHub cloning, PDF extraction, and video understanding for Pi. Zero-config with Exa MCP.
pi
package
web-search
fetch
youtube
unverified
2026-08-28

Pi Web Access

Package: pi-web-access Version: 0.22.0 Author: Nico Bailon

Web search, content extraction, and video understanding for Pi. It calls your self-hosted SearXNG first when one is configured, and falls through to other providers.

Pi-era setup: ~/.pi/web-search.json locked search to SearXNG at http://192.168.0.143:8081 (dankclaw), permitted LAN fetches via ssrf.allowRanges, and set maxInlineContentChars to 50000. The config file is cached in memory per process — a changed file takes effect on the next Pi session.


Install

pi install npm:pi-web-access

Search Providers

Provider chain (in priority order, v0.22):

  1. SearXNG (if configured) — Self-hosted, private search
  2. OpenAI — Codex subscription or API key
  3. Exa — Zero-config via MCP, or API key
  4. Brave — API key
  5. Parallel — API key
  6. TinyFish — API key
  7. Search1API — API key
  8. Searchinfinity — API key
  9. Querit — API key
  10. Tavily — API key
  11. Jina — API key
  12. SERPdive — API key
  13. Kagi — API key
  14. Bocha — API key
  15. Ollama — API key
  16. Perplexity — API key
  17. Gemini API — API key
  18. Gemini Web — Browser-cookie access

A single-provider field (provider or searchProvider) pins the default and takes precedence over searchRouting. searchRouting.providers plus fallbackOn define an explicit ordered fallback over typed failures (transient, quota, network, invalid-response).

Configuration

Location: ~/.pi/web-search.json

{
  "searxngBaseUrl": "http://192.168.0.143:8081",
  "searchProvider": "searxng",
  "maxInlineContentChars": 50000,
  "workflow": "none",
  "ssrf": {
    "allowRanges": ["192.168.0.0/24"]
  },
  "openaiApiKey": "sk-...",
  "braveApiKey": "BSA_...",
  "exaApiKey": "exa-...",
  "perplexityApiKey": "pplx-...",
  "geminiApiKey": "AIza..."
}

Key fields:

  • searxngBaseUrl — the SearXNG instance to call. Env SEARXNG_BASE_URL wins over this file. The client calls GET {base}/search?q=...&format=json with a 30 s timeout; the base URL and its redirects stay subject to the SSRF guard.
  • searchProvider — searxng locks the primary provider. auto picks the first available. A single-provider field wins over searchRouting.
  • maxInlineContentChars — size of each fetch_content / get_search_content content slice. Default 30000, cap 200000. Full fetched content stays stored for later retrieval.
  • ssrf.allowRanges — LAN CIDR ranges allowed through fetch_content. This blocks private IPs by default.
  • workflow — none (raw results, no browser), summary-review (curator window with summary draft), or auto-summary.

Capabilities

web_search({ query: "TypeScript best practices 2025" })

URL Fetching

fetch_content({ url: "https://docs.example.com/guide" })

GitHub Cloning

GitHub URLs are cloned locally. The agent gets real file contents, not rendered HTML.

fetch_content({ url: "https://github.com/owner/repo" })

Video Understanding

Point at a YouTube video or local screen recording and ask questions about visual content.

// YouTube
fetch_content({ url: "https://youtube.com/watch?v=...", prompt: "What book is shown?" })

// Local video
fetch_content({ url: "/path/to/recording.mp4" })

PDF Extraction

fetch_content({ url: "https://example.com/paper.pdf" })

Optional Dependencies

# Video frame extraction
sudo pacman -S ffmpeg yt-dlp

Without these, video analysis (transcripts, visual descriptions via Gemini) still works. Frame extraction requires ffmpeg and yt-dlp. Both are installed on the workstation (verified 2026-08-28: ffmpeg n9.0.1, yt-dlp 2026.08.19).

GitHub URLs get special handling: fetch_content clones the repo locally instead of scraping HTML (root URL returns tree + README, /blob/ returns file contents). Repos over 350 MB get an API-based view; forceClone: true overrides. Clones cache per session under /tmp/pi-github-repos and wipe on session change. Private repos need the gh CLI. Disable with githubClone.enabled: false.

See Also