[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93463":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":9,"totalLinesOfCode":9,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":9,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":17,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":9,"createdAt":9,"pushedAt":9,"updatedAt":21,"readmeContent":22,"aiSummary":9,"trendingCount":16,"starSnapshotCount":16,"syncStatus":23,"lastSyncTime":24,"discoverSource":25},93463,"wigolo","KnockOutEZ\u002Fwigolo","KnockOutEZ","The go-to web for your AI coding agent — local-first search, fetch, crawl & research over MCP. No API keys, no cloud, $0\u002Fquery. Public beta.",null,"https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo","TypeScript",1115,80,5,8,0,187,80.73,false,"main","2026-07-22 04:02:09","\u003Cdiv align=\"center\">\n\n\u003Cimg alt=\"wigolo — the go-to web for your agent\" src=\"assets\u002Fbrand\u002Fwigolo-banner.png\" width=\"640\">\n\nLocal-first web intelligence for AI agents — **no keys, no cloud, no metered bill.**\n\n\u003Csub>works with&nbsp;&nbsp;**Claude Code · Cursor · Codex · Gemini CLI · VS Code · Windsurf · Zed · Antigravity**\u003C\u002Fsub>\n\u003Cbr>\n\u003Csub>and beyond&nbsp;&nbsp;**LangChain · CrewAI · LlamaIndex · Vercel AI SDK · n8n & self-hosted agents · any MCP client · plain REST**\u003C\u002Fsub>\n\n[![npm](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Fwigolo?color=cb3837&logo=npm)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fwigolo)\n[![npm downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdm\u002Fwigolo?color=cb3837&logo=npm&label=downloads)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fwigolo)\n[![GitHub stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002FKnockOutEZ\u002Fwigolo?style=flat&logo=github&color=e3b341)](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Fstargazers)\n[![CI](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002FKnockOutEZ\u002Fwigolo\u002Fci.yml?branch=main&logo=github&label=CI)](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Factions\u002Fworkflows\u002Fci.yml)\n[![node](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fnode-%E2%89%A520-339933?logo=node.js&logoColor=white)](https:\u002F\u002Fnodejs.org)\n[![MCP](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMCP-server-7c3aed)](https:\u002F\u002Fmodelcontextprotocol.io)\n[![license](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-AGPL--3.0-2563eb)](#license)\n[![status](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fstatus-public%20beta-b7791f)](#beta--feedback)\n\n\u003Ca href=\"https:\u002F\u002Ftrendshift.io\u002Frepositories\u002F79424?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-79424\" target=\"_blank\">\u003Cimg src=\"https:\u002F\u002Ftrendshift.io\u002Fapi\u002Fbadge\u002Frepositories\u002F79424\" alt=\"wigolo on Trendshift\" width=\"250\" height=\"55\"\u002F>\u003C\u002Fa>\n\n[Quickstart](#quickstart) · [Tools](#tools) · [Why wigolo](#why-its-different) · [Benchmark](#benchmark) · [Docs](docs\u002FREADME.md) · [Examples](examples\u002FREADME.md) · [Feedback](#beta--feedback) · [FAQ](#faq)\n\n\u003C\u002Fdiv>\n\n---\n\nwigolo gives an AI agent one durable surface for everything web-related — **search, fetch, crawl, extract, cache, find-similar, research,** and autonomous gather loops. It runs wherever your agent runs: as an MCP server next to your coding agent, as a REST\u002FMCP endpoint on the box where your self-hosted agents live, or embedded through an SDK inside your own app. The core tools need no API keys, nothing it touches leaves `~\u002F.wigolo\u002F`, and there's no bill that grows with how much your agent thinks.\n\n\u003Cdiv align=\"center\">\n\n\u003Cimg alt=\"wigolo demo — Claude Code answering a live web question through wigolo, no API keys\" src=\"assets\u002Fwigolo-demo.gif\" width=\"800\">\n\n\u003C\u002Fdiv>\n\n## Quickstart\n\nRequires **Node ≥ 20** and ~1.5 GB of free disk. macOS, Linux, and Windows.\n\nOne command wires the local engine into your agent. `init` is **unattended by default** — no prompts, safe in scripts and CI — and does the **complete setup**: it downloads the browser engine and on-device models, runs a health check, and prints a per-component summary, so any setup problem surfaces right here, not silently on your agent's first call:\n\n```bash\nnpx wigolo init --agents=\u003Cyour-agent>\n```\n\n- **`\u003Cyour-agent>`** — one or more of `claude-code` · `cursor` · `codex` · `gemini-cli` · `vscode` · `windsurf` · `zed` · `antigravity` (comma-separated). wigolo writes the MCP config and instructions for you.\n- **Any other MCP client?** Omit `--agents` and register `npx -y wigolo` yourself — the [installation guide](docs\u002Finstallation.md) has the exact config block for every client, plus Docker, Homebrew, and single-file-binary channels.\n- **Prefer prompts?** `--interactive` is a plain-text flow; `--wizard` is the full terminal TUI.\n- **Skip the downloads?** `--no-warmup` defers everything to first use. A failed component download never fails setup — init reports what's not ready with the exact fix and still wires your agent.\n\nThat's the whole setup — **search, fetch, crawl, extract, cache, and find-similar work with no API key.** Check it's healthy anytime:\n\n```bash\nnpx wigolo doctor\n```\n\nNot for you? `npx wigolo config --uninstall --yes` removes everything, cleanly. You can also paste the [installation guide](docs\u002Finstallation.md) at any AI assistant and let it do the setup — it's written to be self-contained.\n\n### Recommended — a free key makes `research` & `agent` shine\n\nSearch, fetch, crawl, extract, cache, and find-similar are **fully keyless**. But `research`, `agent`, and `search format=answer` use an LLM to *write* the synthesized, cited answer — without one they hand back a raw brief and evidence for your agent to assemble, which is a much thinner experience. **A free Gemini key is all it takes**, and it's the single biggest quality upgrade you can make:\n\n```bash\nexport WIGOLO_LLM_PROVIDER=gemini\nexport GEMINI_API_KEY=\u003Cfree-key>      # grab one at aistudio.google.com\u002Fapikey — the free tier is plenty\n```\n\nAny provider works (`anthropic` · `openai` · `groq`), or stay fully local and keyless with `WIGOLO_LLM_PROVIDER=ollama` (or any OpenAI-compatible URL). Set it in your shell or your agent's MCP `env` block. Providers, models, and the keyless local-model ladder: [configuration guide](docs\u002Fconfiguration.md).\n\n## What your agent gets back\n\nNot snippets — evidence. Every search result carries a verbatim excerpt pinned to its exact position in the source, a citation ID the agent can quote, and a score it can inspect (abridged real shape):\n\n```jsonc\n{\n  \"results\": [{\n    \"title\": \"Logical replication - PostgreSQL docs\",\n    \"url\": \"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Flogical-replication.html\",\n    \"excerpt\": \"Logical replication is a method of replicating data objects…\",\n    \"citation_id\": \"src-1\",\n    \"source_span\": { \"start\": 1042, \"end\": 1305 },          \u002F\u002F byte-exact provenance\n    \"evidence_score\": { \"final\": 0.86, \"semantic\": 0.91, \"lexical\": 0.78, \"engine_consensus\": 3 }\n  }],\n  \"citations\": [{ \"id\": \"src-1\", \"url\": \"…\" }],\n  \"freshness_signal\": { \"published\": \"2026-05-12\", \"confidence\": \"high\" }\n}\n```\n\nWeak results get flagged as junk by wigolo's own scorer, failed engines are reported, stale cache is labeled — the agent always knows what it's standing on. Full response contracts per tool: [tools reference](docs\u002Ftools.md).\n\n## Tools\n\n| Tool | What it does |\n|------|--------------|\n| 🔎 `search` | Multi-engine web search (18 direct adapters) with rank fusion, ML reranking, and an explainable per-result score. Pass a query **array** for parallel breadth. |\n| 📄 `fetch` | Load one URL through a tiered router that auto-escalates from plain HTTP to a headless browser engine on anti-bot challenges or SPA shells. Clean markdown + metadata + links. |\n| 🕸️ `crawl` | Multi-page crawl — BFS, DFS, sitemap, or map-only. Per-domain rate limits, robots.txt respect, boilerplate dedup. |\n| 🧩 `extract` | Structured data from a page: tables, metadata, JSON-LD, brand identity, named schemas (Article \u002F Recipe \u002F Product \u002F …), or any custom JSON Schema. |\n| 💾 `cache` | Query everything already seen — keyword or hybrid semantic. Plus stats, clear, and change detection. |\n| 🧲 `find_similar` | Pages similar to a URL or a concept, via 3-way fusion of keyword + semantic + live web. |\n| 🧠 `research` | Decompose a question → fan out sub-queries → fetch sources → synthesize a cited report (or a structured brief the host LLM writes from). |\n| 🤖 `agent` | Autonomous gather loop: plan → search → fetch → extract → synthesize, with a step log, time budget, and optional output schema. |\n| 🔁 `diff` + ⏱️ `watch` | See exactly what changed on a page since last visit; re-check on demand and deliver changes to a webhook. |\n\nEvery tool also runs from the terminal (`wigolo search \"…\" --json`), from an interactive shell with NDJSON piping (`wigolo shell`), over REST, and through the SDKs — [CLI reference](docs\u002Fcli.md).\n\n### What that actually lets you do\n\nEach tool goes well past its one-liner. A sampler — every line links to the guide and, where there's one, a runnable example:\n\n- **Search that fans out** — pass a query **array** for parallel breadth, scope to `include_domains`, bound by `time_range`\u002Frecency, exact-phrase match, choose a depth tier, even image results. → [guide](docs\u002Ftools.md#search) · [example](examples\u002Fone-shot-cli)\n- **Fetch almost anything** — JS-rendered SPAs, PDFs, a single heading `section`, authenticated pages (via a browser profile or remote browser), or drive the page with `actions` (click \u002F type \u002F scroll \u002F screenshot). → [guide](docs\u002Ftools.md#fetch)\n- **Crawl a whole site** — sitemap, BFS, DFS, or map-only; robots.txt-respecting, per-domain rate-limited, boilerplate-deduped. → [guide](docs\u002Ftools.md#crawl)\n- **Extract structure** — tables, JSON-LD, metadata, brand assets, named schemas (Article \u002F Recipe \u002F Product \u002F …), or your own JSON Schema. → [guide](docs\u002Ftools.md#extract)\n- **A memory that compounds** — every page is cached; re-query by keyword or meaning, instantly and offline; detect what changed since last visit. → [guide](docs\u002Ftools.md#cache) · [example](examples\u002Fwatch-changelog-webhook)\n- **Research & autonomous gather** — decompose a question into a cited brief, or turn `agent` loose to plan → fetch → extract → synthesize against a JSON Schema and a time budget. → [guide](docs\u002Ftools.md#research) · [example](examples\u002Fsdk-python-agent)\n- **Watch & diff** — monitor a URL, get a change report, deliver it to a webhook. → [guide](docs\u002Ftools.md#watch) · [example](examples\u002Fwatch-changelog-webhook)\n- **Drive it your way** — one-shot CLI, an NDJSON shell for pipelines, REST, SDKs, or as skills your agent installs. → [CLI & shell](docs\u002Fcli.md) · [example](examples\u002Fshell-ndjson-pipeline)\n- **Extend it** — add a search engine or a site extractor as a plugin in ~100 lines. → [plugins](docs\u002Fplugins.md) · [example](examples\u002Fplugin-search-engine)\n- **Tune & inspect** — `wigolo tune` shows what it learned per domain (which fetch tier, challenge clearances, backoff); `doctor` \u002F `verify` health-check every component. → [CLI](docs\u002Fcli.md) · [troubleshooting](docs\u002Ftroubleshooting.md)\n\n## Why it's different\n\nwigolo isn't the free stand-in you settle for until the budget clears — it's built to hold the same line as the paid services in this lane, and it brings receipts. What actually separates it:\n\n- **Built for agents, not humans.** One MCP call fans out many queries across many engines in parallel — something a serial host tool-loop can't replicate — with transparent per-result scoring and budget-aware output.\n- **Honest output.** Stale cache, failed fetches, degraded backends, and truncation are surfaced in the result, never disguised as empty-but-successful data. When a bot-protected page can't be read, you get a labeled `blocked_by_challenge` failure — never a challenge shell dressed up as content.\n- **$0 per query, free to re-query.** Default search talks to public engines through direct adapters; the reranker and embeddings run on-device. Every response is cached, so asking again is instant and costs nothing.\n- **Private by default.** Cache, embeddings, models, and config live under `~\u002F.wigolo\u002F`. Nothing reaches a third party unless you explicitly opt into an LLM for synthesis.\n\nwigolo is a focused web layer for your agents — not a hosted SaaS, a vector database other apps query, or a scale-scraping platform. Within that lane it goes toe-to-toe with the paid services on result quality — and the meter, the key, and the data-egress simply aren't there.\n\nHere's what one real result looks like, dissected — including the failed engine and the weak result, because those are part of the answer too:\n\n\u003Cdiv align=\"center\">\n\n\u003Cpicture>\n\u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets\u002Fpromo\u002Fanatomy-dark.svg\">\n\u003Cimg alt=\"Anatomy of a wigolo result: explainable score decomposition, live engine telemetry, surfaced degradation, self-flagged junk — one real query, captured live\" src=\"assets\u002Fpromo\u002Fanatomy.svg\" width=\"880\">\n\u003C\u002Fpicture>\n\n\u003C\u002Fdiv>\n\n## Benchmark\n\n> **All four tools converged on the same core answer — and only one of them handed back verbatim, byte-pinned evidence while doing it.**\n\nOne cold query, run live inside a single **Claude Fable 5** session and fanned out to four web tools on equal footing — built-in **WebSearch**, **wigolo**, **Tavily**, and **Exa** — then reported by the agent itself under one rule: judge on the evidence alone, no favoritism. All four converged on the same answer and the same top source — parity demonstrated, not asserted. wigolo alone returned verbatim excerpts pinned to byte-offset source spans, an explainable score decomposition, and live per-engine telemetry — and when two of its results were weak, its own scorer flagged them as junk on-screen. The cloud tools earn their line too: Exa rendered the official docs' comparison matrix in full. One honest query, not a leaderboard — run your own and you'll see the same shape.\n\n\u003Cdiv align=\"center\">\n\n\u003Cimg alt=\"wigolo vs built-in WebSearch, Tavily, and Exa on one real query, driven by Claude Fable 5\" src=\"assets\u002Fwigolo-vs.gif\" width=\"900\">\n\n\u003C\u002Fdiv>\n\n### Same fight, different physics\n\n| | wigolo | Firecrawl | Exa | Tavily |\n|---|:---:|:---:|:---:|:---:|\n| Multi-engine web search | ✅ | ✅ | ✅ | ✅ |\n| Fetch & structured extraction | ✅ | ✅ | ✅ | ✅ |\n| Whole-site crawl & map | ✅ | ✅ | — | ✅ |\n| Verbatim excerpts pinned to byte-offset source spans | ✅ | — | — | — |\n| Explainable per-result score decomposition | ✅ | — | — | — |\n| Persistent local memory — re-query instantly, offline | ✅ | — | — | — |\n| Query data stays on your machine | ✅ | — | — | — |\n| API key \u002F account | none | required | required | required |\n| Cost per query | $0 | metered | metered | metered |\n\n\u003Csub>Feature standing as of July 2026 — check each vendor's docs for current state.\u003C\u002Fsub>\n\nThat last row is the one that compounds — agents don't ask once, they ask in bursts:\n\n\u003Cdiv align=\"center\">\n\n\u003Cpicture>\n\u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets\u002Fpromo\u002Fmeter-dark.svg\">\n\u003Cimg alt=\"The meter: a metered cloud API's cost climbs with every query while wigolo stays flat at zero dollars — illustrative pricing\" src=\"assets\u002Fpromo\u002Fmeter.svg\" width=\"880\">\n\u003C\u002Fpicture>\n\n\u003C\u002Fdiv>\n\n## Beyond your editor\n\nThe same ten tools serve every kind of agent, over whichever surface fits — MCP for coding agents, REST for everything else, SDKs to embed, framework wrappers to drop in.\n\n### REST API — `wigolo serve`\n\nOne process exposes a plain-JSON REST API next to the MCP transport. No MCP client needed — just curl:\n\n```bash\nwigolo serve                          # 127.0.0.1:3333 — loopback is open; off-loopback requires a token\n\ncurl -sX POST http:\u002F\u002F127.0.0.1:3333\u002Fv1\u002Fsearch \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"query\":\"local-first software\",\"max_results\":5}'\n```\n\n`POST \u002Fv1\u002F{tool}` covers all ten tools, `GET \u002Fopenapi.json` is the OpenAPI 3.1 contract, and `\u002Fmcp` + `\u002Fsse` serve remote MCP clients from the same port. Bind past loopback and a bearer token is required — the server fails closed rather than opening wide by accident. Point n8n, a Hermes-style assistant, or any self-hosted agent at it. → [REST API](docs\u002Frest-api.md)\n\n### SDKs — TypeScript & Python\n\nThin, typed clients with an embedded local mode that finds or starts the daemon for you — no separate `serve` step.\n\n**TypeScript** — `npm install wigolo-sdk` (zero-dep; Node \u002F Bun \u002F Deno \u002F edge):\n\n```ts\nimport { createLocalClient } from 'wigolo-sdk\u002Flocal';\n\nconst { client, close } = await createLocalClient();   \u002F\u002F reuse a running daemon, or spawn one\nconst res = await client.search({ query: 'local-first web search', max_results: 5 });\nconsole.log(res.results.map((r) => r.title));\nawait close();                                          \u002F\u002F stops the daemon only if this call spawned it\n```\n\n**Python** — `pip install wigolo` (standard library only; sync + async):\n\n```python\nfrom wigolo import local_client\n\nwith local_client() as client:                          # reuse a healthy daemon, or spawn one\n    res = client.search(query=\"local-first web search\", max_results=5)\n    for r in res[\"results\"]:\n        print(r[\"title\"], r[\"url\"])\n```\n\n→ [SDKs & embedded mode](docs\u002Fsdks.md)\n\n### Framework integrations\n\nDrop wigolo's tools into the framework you already use — the full ten-tool surface, including the cache \u002F find_similar \u002F research \u002F agent that most framework web-tools don't ship:\n\n| Framework | Package | What you get |\n|-----------|---------|--------------|\n| **LangChain** | `wigolo-langchain` | each tool as a `BaseTool`, plus a `BaseRetriever` over search \u002F find_similar for RAG |\n| **CrewAI** | `wigolo-crewai` | `wigolo_tools()` → hand the set to any crew |\n| **LlamaIndex** | `wigolo-llamaindex` | a `BaseReader` that loads fetched \u002F crawled \u002F searched pages as documents |\n| **Vercel AI SDK** | `wigolo-vercel-ai-sdk` | tool factories for `generateText` \u002F `streamText`, edge-friendly |\n\n→ [Framework integrations](docs\u002Fsdks.md)\n\n### Docker\n\n```bash\n# stdio MCP — wire it into any MCP client as command: docker\ndocker run -i --rm -v wigolo-data:\u002Fdata ghcr.io\u002Fknockoutez\u002Fwigolo\n\n# HTTP server for remote \u002F multi-client use\ndocker run -p 3333:3333 -v wigolo-data:\u002Fdata \\\n  -e WIGOLO_API_TOKEN=a-long-random-secret \\\n  ghcr.io\u002Fknockoutez\u002Fwigolo serve --host 0.0.0.0\n```\n\nThe slim image lazy-loads models into the volume; `:full` preinstalls the browser engine. Also on Docker Hub as `towhid69420\u002Fwigolo`. → [installation & all channels](docs\u002Finstallation.md)\n\n### Agent skills\n\nAn 11-pack skill catalog teaches your coding agent to drive each tool well — installed by `init`, managed with `wigolo skills add|list|remove`. → [skills](docs\u002Fskills.md)\n\nOne honest note for self-hosters: some challenge-protected sites score IP reputation, so a datacenter IP won't clear walls a home connection would. wigolo labels those failures instead of faking them, and the [self-hosting guide](docs\u002Fself-hosting.md) covers the opt-in proxy answer.\n\n## Star history\n\n\u003Cdiv align=\"center\">\n\n\u003Ca href=\"https:\u002F\u002Fstar-history.com\u002F#KnockOutEZ\u002Fwigolo&Date\">\n\u003Cimg alt=\"wigolo GitHub star history\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=KnockOutEZ\u002Fwigolo&type=Date\" width=\"720\">\n\u003C\u002Fa>\n\n\u003Csub>Live chart — it updates itself. If it's still climbing when you read this, \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\">add a ⭐\u003C\u002Fa>.\u003C\u002Fsub>\n\n\u003C\u002Fdiv>\n\n## Architecture\n\nA single Node process speaking MCP (JSON-RPC over stdio). Everything heavy is local and lazy-loaded, so a zero-key install pays nothing for the parts it isn't using.\n\n```mermaid\nflowchart TD\n    A[\"🤖 AI agent\u003Cbr\u002F>any MCP client · REST · SDK\"]\n    A -->|MCP over stdio| B[\"\u003Cb>wigolo\u003C\u002Fb>\u003Cbr\u002F>10 tools · dynamic instructions\u003Cbr\u002F>in-process browser pool + cache + models\"]\n\n    B --> C{\"Tool layer\"}\n    C --> T1[\"search · fetch · crawl · extract\"]\n    C --> T2[\"cache · find_similar · research · agent\"]\n\n    T1 --> F[\"⚙️ Fetch router\u003Cbr\u002F>tiered escalation, learned per domain\"]\n    T1 --> S[\"⚙️ Search\u003Cbr\u002F>18 engines → rank fusion → ML rerank\u003Cbr\u002F>\u003Ci>explainable evidence score\u003C\u002Fi>\"]\n    T2 --> DB[(\"🗄️ Local cache\u003Cbr\u002F>keyword + vector index\")]\n    T2 --> ML[\"🧠 On-device ML\u003Cbr\u002F>embeddings + reranker\"]\n\n    F -.->|optional| LLM[\"☁️ LLM\u003Cbr\u002F>synthesis only · opt-in\"]\n    S -.->|optional| SX[\"🔀 Aggregator backend\u003Cbr\u002F>opt-in legacy \u002F hybrid\"]\n\n    F --> WEB[\"🌍 Public web\"]\n    S --> WEB\n\n    style B fill:#7c3aed,stroke:#5b21b6,color:#fff\n    style WEB fill:#0ea5e9,stroke:#0369a1,color:#fff\n    style DB fill:#1e293b,stroke:#334155,color:#fff\n    style LLM stroke-dasharray: 5 5\n    style SX stroke-dasharray: 5 5\n```\n\n- **Code beats model.** Deterministic work — canonicalization, rank fusion, dedup, schema matching — never touches an LLM. The model is reserved for judgment, opt-in, and capped per request; LLM-filled fields are checked against the source and nulled if absent.\n- **Routing on observable signals.** The fetch ladder escalates to a real browser on what it *sees* — SPA markers, challenge bodies, thin content — not domain guesses. It learns per domain, unlearns when a site stops needing it, and `wigolo tune list` shows you exactly what it learned.\n- **Reads pages the way a browser does — and says so when it can't.** Tiered fetching waits out interstitial challenges and reuses clearances per domain, politely: robots.txt respected, per-domain rate limits, research-grade volumes. When a wall stays up, the failure is labeled, never disguised.\n\n## Configuration\n\nA clean install works out of the box. Three settings meaningfully raise output quality:\n\n```bash\n# 1. Synthesis — the biggest lever (research \u002F agent \u002F search-answer write real prose)\nexport WIGOLO_LLM_PROVIDER=gemini                   # or anthropic \u002F openai \u002F groq \u002F ollama (keyless)\nexport GEMINI_API_KEY=\u003Cyour-key>\n\n# 2. Wider retrieval funnel\nexport WIGOLO_SEARCH=hybrid                         # core engines + aggregator fallback\nexport WIGOLO_GITHUB_TOKEN=...                      # GitHub code search 10 → 30 req\u002Fmin\n\n# 3. Land more fetches, stay warm\nexport WIGOLO_TLS_TIER=auto                         # per-domain learned fetch hardening\nexport WIGOLO_EAGER_WARMUP=1                        # pay the ~1s model load up front\n```\n\n**Per-call habits that pay off:** query **arrays** (`[\"a\",\"b\",\"c\"]`) for parallel breadth · `search_depth: \"deep\"` for queries that matter · `include_domains` as a hard filter for docs lookups.\n\nThe full reference — every environment variable, config-file key, search backend, cache TTL, and serve limit — lives in the [configuration guide](docs\u002Fconfiguration.md).\n\n## Docs & examples\n\n**[docs\u002F](docs\u002FREADME.md)** — the complete manual:\n[getting started](docs\u002Fgetting-started.md) · [installation & channels](docs\u002Finstallation.md) · [configuration](docs\u002Fconfiguration.md) · [tools reference](docs\u002Ftools.md) · [CLI & shell](docs\u002Fcli.md) · [REST API](docs\u002Frest-api.md) · [SDKs & integrations](docs\u002Fsdks.md) · [self-hosting](docs\u002Fself-hosting.md) · [agent skills](docs\u002Fskills.md) · [plugins](docs\u002Fplugins.md) · [troubleshooting & FAQ](docs\u002Ftroubleshooting.md) · [privacy & security](docs\u002Fprivacy-security.md)\n\n**[examples\u002F](examples\u002FREADME.md)** — runnable, each with a README (and most with a terminal recording): one-shot CLI, NDJSON shell pipelines, REST via curl, TypeScript & Python SDKs, Vercel AI SDK tools, pointing self-hosted n8n at a remote wigolo, watch-with-webhook, and writing your own search-engine plugin.\n\nDocs are also rendered on the site: **[knockoutez.github.io\u002Fwigolo\u002Fdocs](https:\u002F\u002Fknockoutez.github.io\u002Fwigolo\u002Fdocs\u002F)**.\n\n## Beta & feedback\n\nwigolo is in **public beta**. Everything documented here works and is held to a 7,600-test suite — beta is about the polish bar, not stability. It stays beta until enough people have used it, kicked it, and starred it that calling it v1 means something.\n\nThat makes your feedback the whole game right now. Every report is read, usually the same day:\n\n- 🐛 **[Report a bug](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Fissues\u002Fnew?template=bug_report.yml)** — broke, misbehaved, surprised you\n- 💡 **[Request a feature](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Fissues\u002Fnew?template=feature_request.yml)** — something it should do\n- 💬 **[Ask anything](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Fdiscussions)** — questions, setups, show & tell\n\nAnd if wigolo earns a place in your setup, the ways to keep it alive: a ⭐ **star** (it's how open source gets found), a **[☕ coffee](https:\u002F\u002Fbuymeacoffee.com\u002Fknockoutez)** (there's no paid tier and never will be), or just **[an email](mailto:ktowhid20@gmail.com)** — it goes straight to the one developer who wrote the code.\n\n## Troubleshooting\n\n`wigolo doctor` names any broken component and the exact env var or command that fixes it; `wigolo doctor --fix` repairs the common cases. A component failing during `init` **doesn't** break wigolo — `init` still exits 0, and core search \u002F fetch \u002F crawl \u002F extract \u002F cache work with no models and no browser.\n\nQuick hits:\n\n- **Slow or failed downloads** — re-run `wigolo warmup --all` (or `--browser` \u002F `--embeddings` \u002F `--reranker`); they resume and retry.\n- **Browser won't launch on Linux** — `wigolo warmup --browser` installs the OS libraries (or prints the exact command).\n- **Native build error \u002F unusual Node** — use an LTS: **Node 20, 22, or 24**.\n- **Behind a proxy** — `USE_PROXY=true` + `PROXY_URL`; add `NODE_EXTRA_CA_CERTS` for TLS-inspecting proxies.\n\nFull guide — per-symptom fixes, a \"what still works when X fails\" map, platform notes (incl. linux-arm64), and offline installs: **[docs\u002Ftroubleshooting.md](docs\u002Ftroubleshooting.md)**.\n\n## FAQ\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Free? What's the catch?\u003C\u002Fb>\u003C\u002Fsummary>\n\nNo catch by design. The expensive parts — ranking, embeddings, the browser engine — run on *your* hardware, so there's no per-query cost to recover and no reason for a meter. Sustained by donations; the AGPL license legally prevents a bait-and-switch into a closed hosted product.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Is the quality really on par with the paid services?\u003C\u002Fb>\u003C\u002Fsummary>\n\nRun one query and judge — the benchmark section above is a live 4-way run, not a chart. Everyday agent queries land at parity; the paid tools still win some deep-extraction edge cases, and crawling is where wigolo is strongest. Every result shows its scoring, so you don't have to take anyone's word for it.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Won't public search engines block or rot?\u003C\u002Fb>\u003C\u002Fsummary>\n\nIt's engineered for exactly that: 18 engines fused with rank fusion (any one failing barely moves results), a tiered fetch ladder with per-domain learning, and an optional aggregator fallback. Degraded backends are *reported in the output*, never hidden — and the local cache means everything already seen keeps working regardless.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Is this kind of scraping OK?\u003C\u002Fb>\u003C\u002Fsummary>\n\nwigolo reads the public web the way a browser does — robots.txt respected by default, per-domain rate limits, research-grade volumes for one agent on one machine. It's deliberately the polite end of the spectrum, not a harvesting platform.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>AGPL — can I use this at work?\u003C\u002Fb>\u003C\u002Fsummary>\n\nYes, freely, company-wide. The license only bites if you *modify wigolo and run it as a network service* — then you must publish those modifications. Using it as a local dev tool carries zero obligation. Commercial-licensing questions: reach out.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Why 1.5 GB of disk?\u003C\u002Fb>\u003C\u002Fsummary>\n\nThat's the on-device brain: a full browser engine plus the ranking and embedding models the cloud services run on their side and bill you for. Disk is cheap; meters aren't.\n\n\u003C\u002Fdetails>\n\n## Available on\n\n- **npm** — [`wigolo`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fwigolo) *(primary channel — the Quickstart above)*\n- **PyPI** — [`wigolo`](https:\u002F\u002Fpypi.org\u002Fproject\u002Fwigolo\u002F) *(Python SDK)*\n- **Docker** — [`ghcr.io\u002Fknockoutez\u002Fwigolo`](https:\u002F\u002Fgithub.com\u002FKnockOutEZ\u002Fwigolo\u002Fpkgs\u002Fcontainer\u002Fwigolo) · [`towhid69420\u002Fwigolo`](https:\u002F\u002Fhub.docker.com\u002Fr\u002Ftowhid69420\u002Fwigolo)\n- **Official MCP Registry** — `io.github.KnockOutEZ\u002Fwigolo`\n- **Directories** — [Glama](https:\u002F\u002Fglama.ai\u002Fmcp\u002Fservers\u002FKnockOutEZ\u002Fwigolo) · [Smithery](https:\u002F\u002Fsmithery.ai\u002Fserver\u002Fktowhid20\u002Fwigolo) · [mcp.so](https:\u002F\u002Fmcp.so\u002Fserver\u002Fwigolo\u002FKnockOutEZ) · [LobeHub](https:\u002F\u002Flobehub.com\u002Fmcp\u002Fknockoutez-wigolo)\n\nHomebrew, `curl | sh`, and the single-file binary are covered in the [installation guide](docs\u002Finstallation.md) — one channel per machine; they all share `~\u002F.wigolo`.\n\n## Contributing\n\nBug reports, feature requests, and PRs are all welcome — see **[CONTRIBUTING.md](CONTRIBUTING.md)**. Keep tool handlers thin, add tests, run the suite before opening a PR. The friendliest entry point: wigolo has a plugin system for custom search engines and extractors — [add a search engine in ~100 lines](docs\u002Fplugins.md), template in [`examples\u002Fplugin-search-engine`](examples\u002Fplugin-search-engine).\n\n## License\n\n**[GNU AGPL-3.0-only](LICENSE).** Free to use, modify, and self-host — including inside a company. The one obligation: if you run a **modified** version as a network service, you must publish your modified source under the same license. That keeps wigolo open while preventing a closed, hosted fork. See **[SECURITY.md](SECURITY.md)** to report a vulnerability and **[TRADEMARK.md](TRADEMARK.md)** for use of the name. For commercial-licensing questions, reach out.\n\n\u003Cdiv align=\"center\">\n\u003Cbr>\n\nwigolo is free and meant to stay that way — maintained, not paywalled.\nIf it saves you a metered search bill, a ⭐, a sharp issue, or a **[☕ coffee](https:\u002F\u002Fbuymeacoffee.com\u002Fknockoutez)** helps keep it sustainable.\n\n\u003Csub>Built and maintained by \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FKnockOutEZ\">@KnockOutEZ\u003C\u002Fa> · \u003Ca href=\"mailto:ktowhid20@gmail.com\">ktowhid20@gmail.com\u003C\u002Fa>\u003C\u002Fsub>\n\n\u003C\u002Fdiv>\n",2,"2026-07-19 02:30:06","trending"]