{"_id":"@agent-sh/harness-websearch","_rev":"2-38f0140972fa47b81084e3d6a4d07aa8","name":"@agent-sh/harness-websearch","dist-tags":{"latest":"0.7.0"},"versions":{"0.3.0":{"name":"@agent-sh/harness-websearch","version":"0.3.0","keywords":["ai","agent","llm","tool-use","websearch","search","searxng","metasearch","bedrock","openai"],"author":{"name":"Avi Fenesh"},"license":"MIT","_id":"@agent-sh/harness-websearch@0.3.0","maintainers":[{"name":"avifenesh","email":"aviarchi1994@gmail.com"}],"homepage":"https://github.com/avifenesh/tools/tree/main/packages/websearch#readme","bugs":{"url":"https://github.com/avifenesh/tools/issues"},"dist":{"shasum":"60b724503058cafd4f11dc7615655b8d1daf26c3","tarball":"https://registry.npmjs.org/@agent-sh/harness-websearch/-/harness-websearch-0.3.0.tgz","fileCount":9,"integrity":"sha512-CH7+QGPBwh8C3gTLlk9+OX+N6pKAozKSwKlsYJQGbtHI+BgKJb18MBhlD9W5nl4oh5DlH8B5dvRKXHyl2zmIGQ==","signatures":[{"sig":"MEQCIAQEWQJ++pn0PeTi3qNzWIBVIeNHb7h5vFGW8D1DXXj2AiB4qVpKG9+Os4zBQgUbKIHwr1fCPTFcLC5sf/6wiCFvFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":195530},"main":"./dist/index.cjs","type":"module","_from":"file:agent-sh-harness-websearch-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"test":"vitest run","build":"tsup","clean":"rm -rf dist .turbo","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"avifenesh","email":"aviarchi1994@gmail.com"},"_resolved":"/tmp/62baf8c918f0b8b8a18a68084aad4af2/agent-sh-harness-websearch-0.3.0.tgz","_integrity":"sha512-CH7+QGPBwh8C3gTLlk9+OX+N6pKAozKSwKlsYJQGbtHI+BgKJb18MBhlD9W5nl4oh5DlH8B5dvRKXHyl2zmIGQ==","repository":{"url":"git+https://github.com/avifenesh/tools.git","type":"git","directory":"packages/websearch"},"_npmVersion":"10.8.2","description":"WebSearch tool for AI agent harnesses — self-hosted SearXNG metasearch with SSRF defense, declarative query controls, result-count cap, and a discriminated result surface","directories":{},"_nodeVersion":"20.20.2","dependencies":{"undici":"^7.0.0","valibot":"^1.2.0","@agent-sh/harness-core":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.4","typescript":"^5.6.3","@types/node":"^22.9.0"},"_npmOperationalInternal":{"tmp":"tmp/harness-websearch_0.3.0_1780132947101_0.4770719949735973","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@agent-sh/harness-websearch","version":"0.7.0","description":"WebSearch tool for AI agent harnesses — zero-config keyless web search (Mojeek/Marginalia/Wikipedia fallback chain) with optional Brave/Tavily/SearXNG backends, SSRF defense, declarative query controls, result-count cap, and a discriminated result surface","keywords":["ai","agent","llm","tool-use","websearch","search","searxng","metasearch","bedrock","openai"],"license":"MIT","author":{"name":"Avi Fenesh"},"homepage":"https://github.com/avifenesh/tools/tree/main/packages/websearch#readme","bugs":{"url":"https://github.com/avifenesh/tools/issues"},"repository":{"type":"git","url":"git+https://github.com/avifenesh/tools.git","directory":"packages/websearch"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"publishConfig":{"access":"public"},"engines":{"node":">=20"},"dependencies":{"undici":"^7.0.0","valibot":"^1.2.0","@agent-sh/harness-core":"0.2.0"},"devDependencies":{"@types/node":"^22.9.0","tsup":"^8.3.5","typescript":"^5.6.3","vitest":"^3.2.6"},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","clean":"rm -rf dist .turbo"},"_id":"@agent-sh/harness-websearch@0.7.0","_integrity":"sha512-j2sFwRNxCfZ50nbya/cnxHoGD52DQTqJhM/sTq5lD/H/ZAJZYxU4yPucHt/BhX/1vkmHaDDJeaKB6+bBz+RJfg==","_resolved":"/tmp/6971a23bad28a07d20332967c6caee47/agent-sh-harness-websearch-0.7.0.tgz","_from":"file:agent-sh-harness-websearch-0.7.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-j2sFwRNxCfZ50nbya/cnxHoGD52DQTqJhM/sTq5lD/H/ZAJZYxU4yPucHt/BhX/1vkmHaDDJeaKB6+bBz+RJfg==","shasum":"7a5d19fd7a9e67f33915e27ce020c490e69ba35c","tarball":"https://registry.npmjs.org/@agent-sh/harness-websearch/-/harness-websearch-0.7.0.tgz","fileCount":9,"unpackedSize":492114,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCPV5NOfWf5hX5rKmMMKI49YFou60ID7ZA6LUC2i21zOwIgQUYHZeC7drt8QQSmNonslW+ytvnmEaOONojQQiHC2mk="}]},"_npmUser":{"name":"avifenesh","email":"aviarchi1994@gmail.com"},"directories":{},"maintainers":[{"name":"avifenesh","email":"aviarchi1994@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/harness-websearch_0.7.0_1781445993378_0.9193250887263886"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-30T09:22:26.933Z","modified":"2026-06-14T14:06:33.676Z","0.3.0":"2026-05-30T09:22:27.260Z","0.7.0":"2026-06-14T14:06:33.534Z"},"bugs":{"url":"https://github.com/avifenesh/tools/issues"},"author":{"name":"Avi Fenesh"},"license":"MIT","homepage":"https://github.com/avifenesh/tools/tree/main/packages/websearch#readme","keywords":["ai","agent","llm","tool-use","websearch","search","searxng","metasearch","bedrock","openai"],"repository":{"type":"git","url":"git+https://github.com/avifenesh/tools.git","directory":"packages/websearch"},"description":"WebSearch tool for AI agent harnesses — zero-config keyless web search (Mojeek/Marginalia/Wikipedia fallback chain) with optional Brave/Tavily/SearXNG backends, SSRF defense, declarative query controls, result-count cap, and a discriminated result surface","maintainers":[{"name":"avifenesh","email":"aviarchi1994@gmail.com"}],"readme":"# @agent-sh/harness-websearch\n\nWeb search for AI agent harnesses — **works with no API key and no setup**. With nothing configured it queries a bundled keyless fallback chain (Mojeek → Marginalia → Wikipedia) and returns the first backend that has results. Optionally upgrade to Brave/Tavily (API key) or a self-hosted SearXNG for higher coverage — same tool, same output. Tool-layer SSRF defense, declarative provider-neutral query controls, a result-count cap, engine provenance, and a discriminated result surface.\n\nPart of the [`@agent-sh/harness-*`](https://github.com/avifenesh/tools) monorepo — see the top-level README for architectural context and the full tool surface. WebSearch finds URLs; [`webfetch`](../webfetch) reads them. They compose.\n\n## Install\n\n```sh\nnpm install @agent-sh/harness-websearch\n```\n\nRequires Node ≥ 20.\n\n## Usage\n\nZero-config — keyless, just works:\n\n```ts\nimport { websearch } from \"@agent-sh/harness-websearch\";\n\nconst session = {\n  permissions: { roots: [], sensitivePatterns: [], unsafeAllowSearchWithoutHook: true },\n};\n\nconst r = await websearch({ query: \"rust async runtime benchmarks\", count: 5 }, session);\n// r.meta.engine tells you which backend served the results (e.g. \"mojeek\").\n```\n\nUpgrade to a reliable keyed provider, or a self-hosted SearXNG:\n\n```ts\n// Brave (recommended; free tier at api-dashboard.search.brave.com):\nconst braveSession = { ...session, braveApiKey: process.env.BRAVE_API_KEY };\n\n// Self-hosted SearXNG (loopback opt-in since it's usually on localhost):\nconst searxngSession = { ...session, searxngUrl: \"http://127.0.0.1:8888\", allowLoopback: true };\n\n// An explicit backend is exclusive by default; opt into the keyless tail as a backstop:\nconst withFallback = { ...braveSession, fallbackToKeyless: true };\n```\n\nNotes:\n- `disableMojeek: true` drops the Mojeek scrape engine (its robots.txt disallows `/search`; the documented Marginalia/Wikipedia APIs remain).\n- `snippetCap` tunes the per-result snippet length (default 240 chars; clamped 80–600) to trade detail for tokens.\n- When the leading backend returns fewer than `count`, the tool **gathers and merges** results across the chain (de-duplicating the same page by normalized URL) until the quota is met; a backend that already satisfies `count` short-circuits. Merged results are ranked by **Reciprocal Rank Fusion + engine weights** (a page multiple engines agree on is boosted; a niche/encyclopedic backstop won't outrank broad web), name the contributing engines in the header, and tag each result with its `source`.\n- Output is compact ranked text: a `WEB \"query\" · engine (class) · N results` header then numbered entries; the engine's coverage class (`general web` / `indie/small-web index` / `encyclopedic`) and per-result `age` (when the backend provides it) are shown so the model can judge source quality and freshness. Parse `meta`/`results`, not the `output` string.\n- Zero hits is a normal `kind: \"empty\"` result, not an error.\n\n## Contract\n\nThe full contract — input shape, output discriminated-union, error codes, permission model, and acceptance tests — lives in [`agent-knowledge/design/websearch.md`](https://github.com/avifenesh/tools/blob/main/agent-knowledge/design/websearch.md). Changes to this package must stay in sync with that spec.\n\n## License\n\nMIT © Avi Fenesh\n","readmeFilename":"README.md"}