Skip to main content

gossamer — High-Performance LLM Web Researcher

A hybrid LLM web researcher combining a Rust parsing core (PyO3) with Oxide extractors for documents and a Python orchestration layer for caching, rate limiting, budgets, tool routing, and multi-provider search.

Python PyPI Rust License Tests

Docs: Quick reference · Architecture · Changelog


Architecture

LLM Agent / User
       │  MCP (mcp_server.py) · CLI (cli.py) · skills (bundled)
       ▼
WebResearcherToolbox (agent_tools.py) — facade, no logic
       │  TOOL_REGISTRY (config.py): one source of truth
       ▼
Collaborators (Python: HTTP, keys, rate limits, orchestration)
fetch · search · crawl · document · discovery · 38 domain adapters
       │  JSON strings down, JSON strings up
       ▼
_core (Rust): all response parsers, HTML metadata (in-core meta_oxide
crate), SSRF/robots, budgets, guard, citations, tokens, scoring

Python decides, Rust parses. Details: Architecture.


Features

  • Zero API Keys: DuckDuckGo plus 20+ keyless domain adapters (OpenAlex, Eurostat, Bundesbank, HUDOC, …)
  • Multi-Provider Search: Google, Bing, Exa alongside DuckDuckGo with failover or merged results
  • Domain Providers: research_by_category classifies queries (incl. German/EU terms like Leitzins, BVerfG, HICP) into scholarly / legal / patent / financial / geo — keyless-first
  • Patent Providers: EPO OPS, KIPRIS, PatentsView, Lens (all key-gated, fail fast with the exact variable name; Lens aggregates WO/EP/DE/CN/US, trial is non-commercial/academic) + keyless Google Patents number lookup
  • Documents: PDF/DOCX/XLSX/PPTX plus TXT/MD/CSV/JSON/XML/feeds; tables render as markdown by default; store=True, include_images=True saves PDF figures
  • Crawl: bounded relevance-ranked BFS (BM25 idfs + thesaurus + anchor context); documents collected, never fetched
  • Citations: BibTeX / CSL-JSON / APA / MLA from search results, no extra network calls
  • HTML Metadata: 13 formats via the in-core meta_oxide crate — no separate install, no PyPI blocker
  • Guard (optional, off): JailGuard ONNX detector — annotate / redact / block
  • Production-Ready: TTL + size-cap caching, per-domain rate limits, robots/SSRF compliance, retries, observability

Quick Start

Prerequisites

  • Rust 1.82+ (rustup), Python 3.10+, maturin

Build & Install

git clone https://github.com/opticsWolf/gossamer && cd gossamer
pip install -r requirements.txt
maturin develop --release
# Optional: headless-browser rendering for JS-heavy pages
# (`use_smart="browser"`). Windows/macOS only — no Linux wheels exist,
# so this stays an extra (never a hard dependency) and static fetch
# remains the default.
pip install -e ".[browser]"

Basic Usage

from gossamer import ToolboxConfig, WebResearcherToolbox

tools = WebResearcherToolbox(ToolboxConfig(
    cache_dir="./cache",
    max_tokens=4000,
    model_name="gpt-4o",
))

results = tools.web_search("latest AI research papers", max_results=5, search_only=True)
content = tools.inspect_html_page("https://arxiv.org/abs/1234.5678")
pdf = tools.extract_document("https://example.com/paper.pdf")
with_figs = tools.extract_document("https://example.com/paper.pdf",
                                    store=True, include_images=True)
report = tools.research_by_category("EZB Leitzins", max_results=5)

Async Usage

results = await tools.search_web_async("rust programming")

What "async" means here (thread pool). The *_async wrappers offload the shared blocking implementation to Python's default thread-pool executor (loop.run_in_executor(None, …)), keeping the event loop responsive — but the underlying network I/O is still synchronous. Use them inside asyncio apps to avoid blocking the loop; call the sync methods otherwise. Full model: Architecture.

Tools (twelve MCP tools, everywhere)

MCP tools, CLI commands (gossamer …), and execute_tool(name, args) are the same surface, param-for-param: web_search, inspect_html_page, batch_inspect_pages, download_file, locate_pdf, extract_document, discover_resources, crawl, manage_cache, research_by_category, export_citations, check_sources. download_file saves an opaque remote file without requiring extraction; caller-supplied fallback_urls are tried sequentially with normal robots/SSRF checks, and resume=true continues a partial file with Range/If-Range (restart when the server ignores Range). Use extract_document when you also want parsed text. locate_pdf resolves a DOI to OpenAlex OA PDF/landing-page candidates (plus Unpaywall v2 when GOSSAMER_UNPAYWALL_EMAIL is configured) without downloading them. The CLI adds gossamer categories (routing table) and gossamer skills list|show|install (bundled skill management) — neither is an MCP tool. Parameters: Quick reference.

tools.get_llm_definitions()  # OpenAI-compatible function definitions
tools.execute_tool("inspect_html_page", {"url": "https://example.com"})

Domain Providers (research_by_category)

Category Providers (first = default)
scholarly OpenAlex (default), Crossref, arXiv, Zenodo, Semantic Scholar (opt-in; key recommended for rate limits)
legal CourtListener, eCFR, Federal Register, Open Legal Data, HUDOC (ECtHR), GovInfo
patent EPO OPS, KIPRIS, PatentsView, Lens 🔑 + keyless Google Patents lookup
financial Yahoo, Frankfurter (FX), Eurostat, Bundesbank, BIS, CoinGecko, AlphaVantage 🔑
geo Open-Meteo, Overpass
general DuckDuckGo (Google/Bing/Exa 🔑 opt-in)

Euro terms route automatically (EZB, Leitzins, HICP, EGMR, BVerfG, DSGVO, …). For precise OpenAlex queries, gossamer research QUERY --provider openalex --filter 'type:article' --select 'id,title,doi' --title 'gradient index' --author 'Smith' passes provider-native controls; those options are rejected for other providers. --title/--author map to the verified title.search/raw_author_name.search filters and combine with --filter. Explicit scholarly multi-search is opt-in via gossamer research QUERY --providers openalex arxiv; it merges by DOI/arXiv ID, preserves each source record, and never fans out by default.

Paper collection: research → check --mode status → optional locate-pdf DOI → download URL -o FILE --expect-format pdf → extract FILE → cite DOI (or cite FILE.pdf [--from-pdf] for a DOI detected from the file). Supplied mirror URLs are checked independently; gossamer respects robots/SSRF policy and does not bypass bot walls. The skill has the full recipe — it ships inside the wheel, and gossamer skills install copies it into your agent's discovery directory.


Configuration

Env wins over file, always. Keys: GOSSAMER_* env > legacy STITCH_* > keystore ($GOSSAMER_KEYSTORE > gossamer.json:keystore > ~/.gossamer/keys.json) > gossamer.json "keys". Config file: explicit > $GOSSAMER_CONFIG > ./gossamer.json > ~/.gossamer/config.json.

python -m gossamer.keystore --init          # 0600 template, fill it in
python -m gossamer.keystore --init-config   # gossamer.json template
python -m gossamer.keystore --check         # validate, never prints secrets
{ "max_tokens": 4000, "model_name": "gpt-4o", "fetch_mode": "auto" }

OpenAlex works without a key for casual use. Set GOSSAMER_OPENALEX_KEY (in the keystore or environment) for the higher daily budget. If you want to identify your client by email, set GOSSAMER_OPENALEX_EMAIL; it is sent as mailto and in the request headers. No placeholder email is sent when unset. Semantic Scholar is also callable without a key, but keyless requests share a pool and may receive 429s; set GOSSAMER_SEMANTICSCHOLAR_API_KEY for its individual one-request-per-second allowance.


Harness Integration (pi, Codex, Claude Code)

Same stdio server everywhere (python -m gossamer.mcp_server); keys stay in the keystore, never in client configs. Shallowest first: direct CLI (gossamer search|research|inspect|download|locate-pdf|extract|…, 1:1 with MCP) → MCP (directTools) → gossamer/skills/gossamer/SKILL.md (bundled in the wheel and served as the skills://gossamer MCP resource; gossamer skills list|show|install manages it).

pi (mcp.json, then reload):

{ "mcpServers": { "gossamer": {
  "command": "D:/User/Documents/Python/gossamer/.venv/Scripts/python.exe",
  "args": ["-m", "gossamer.mcp_server"],
  "env": { "GOSSAMER_CACHE_DIR": "D:/User/Documents/Python/gossamer/.gossamer_cache",
            "GOSSAMER_LOG_LEVEL": "WARNING" },
  "directTools": true } } }

Codex (~/.codex/config.toml):

[mcp_servers.gossamer]
command = "D:/User/Documents/Python/gossamer/.venv/Scripts/python.exe"
args = ["-m", "gossamer.mcp_server"]
startup_timeout_sec = 30

Claude Code:

claude mcp add gossamer -- D:/User/Documents/Python/gossamer/.venv/Scripts/python.exe -m gossamer.mcp_server

Keep crawls modest (max_pages ≤ 15) — long runs outlast harness timeouts.


Running Tests

Hermetic by default (no network, SSRF on):

.venv/Scripts/python.exe -m pytest -q -n auto --ignore=tests/test_live_smoke.py
GOSSAMER_LIVE=1 pytest tests/test_live_smoke.py   # opt-in endpoint-drift check

Subset markers (-m area_search|area_fetch|area_crawl|…) are assigned by filename in tests/conftest.py. Details: Architecture.

License

Dual-licensed under MIT OR Apache-2.0 — zero copyleft, zero JVM.

Metadata

Release files for gossamer-web 0.9.35

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gossamer-web 0.9.35
File Size Uploaded Provenance Actions
gossamer_web-0.9.35.tar.gz 1.3 MB With provenance Details for gossamer_web-0.9.35.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for gossamer-web 0.9.35
File Interpreter ABI Platform Actions
gossamer_web-0.9.35-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details for gossamer_web-0.9.35-cp38-abi3-win_amd64.whl
gossamer_web-0.9.35-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details for gossamer_web-0.9.35-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
gossamer_web-0.9.35-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details for gossamer_web-0.9.35-cp38-abi3-macosx_11_0_arm64.whl

Total release size: 24.8 MB

Release files / gossamer_web-0.9.35.tar.gz

Download URL gossamer_web-0.9.35.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
f3ed08dcb5b88ab9b7febe9f70d8f48f7157ee9ea5545cb81068bff27fc50c84
BLAKE2b-256 checksum
How to use checksums
f2e4f6b5b06c23507bd2a11f6c20c27250da60b21b3ff459c79de05dd16479c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / gossamer_web-0.9.35-cp38-abi3-win_amd64.whl

Download URL gossamer_web-0.9.35-cp38-abi3-win_amd64.whl
Size 8.0 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
44ec88714175f2d79929189da2c8009bc8ee4f8c7df08e1ffe4f48838ec2f494
BLAKE2b-256 checksum
How to use checksums
3f32d96c6ed06b589c5b70aaf0723a7a42743d039f28291e1b9cb942f0ecb3b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / gossamer_web-0.9.35-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL gossamer_web-0.9.35-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 7.9 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
85390c5334ae629493bc5039670ef7525f9ee6667022a5aa377f06ef14a165b1
BLAKE2b-256 checksum
How to use checksums
f3bc38f72571597b7ae3a62f4d009bc22f550ecb567f9992e78223a13cf1f589
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / gossamer_web-0.9.35-cp38-abi3-macosx_11_0_arm64.whl

Download URL gossamer_web-0.9.35-cp38-abi3-macosx_11_0_arm64.whl
Size 7.6 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
38ff5c54ed9627061db208c13c857a258d9d68a83112c8071e81ea2eb56fd01c
BLAKE2b-256 checksum
How to use checksums
073ae98ceda89cdc72de7173f87f158a4d5002fee3bd41b34aad45630ec23443
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for gossamer-web 0.9.35

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 4 files in this release have been uploaded with provenance metadata.

Select from 4 files

Attestation for gossamer_web-0.9.35.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page