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.
Docs: Quick reference · Architecture · Changelog
Architecture
LLM Agent / User
│ MCP (mcp_server.py) · CLI (cli.py) · skills/SKILL.md
▼
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 · 37 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_categoryclassifies 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=Truesaves 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_oxidecrate — 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
*_asyncwrappers 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 insideasyncioapps to avoid blocking the loop; call the sync methods otherwise. Full model: Architecture.
Tools (ten 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, extract_document,
discover_resources, crawl, manage_cache, research_by_category,
export_citations, check_sources. The CLI adds gossamer categories
(routing table; not 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, Crossref, arXiv, Zenodo |
| 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, …).
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" }
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|extract|…, 1:1 with MCP) → MCP
(directTools) → skills/gossamer/SKILL.md.
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gossamer_web-0.9.6.tar.gz.
File metadata
- Download URL: gossamer_web-0.9.6.tar.gz
- Upload date:
- Size: 745.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17d7c9b5528957b7ce5d15c214750a0d74b1e53a2f63904495f95c86c195f356
|
|
| MD5 |
1ecd4abc9f34992017b4123cdb6326f6
|
|
| BLAKE2b-256 |
40287086ea265681229a50fd10de3d981e4f04a7239fdd041cb385c99ec06a8a
|
Provenance
The following attestation bundles were made for gossamer_web-0.9.6.tar.gz:
Publisher:
release.yml on opticsWolf/gossamer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gossamer_web-0.9.6.tar.gz -
Subject digest:
17d7c9b5528957b7ce5d15c214750a0d74b1e53a2f63904495f95c86c195f356 - Sigstore transparency entry: 2805439774
- Sigstore integration time:
-
Permalink:
opticsWolf/gossamer@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Branch / Tag:
refs/tags/v0.9.6 - Owner: https://github.com/opticsWolf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Trigger Event:
push
-
Statement type:
File details
Details for the file gossamer_web-0.9.6-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: gossamer_web-0.9.6-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 8.0 MB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c0214cd1bf33be2a095dc8ac4b4f549da29e20d5a027c2e7fefb09f4d0ba5e2
|
|
| MD5 |
cf2398d692c1c4585936452f4dd86a53
|
|
| BLAKE2b-256 |
fb40ad802ef22c63cea702781020c26874358b3f0ecd4af40a5552edc50a9836
|
Provenance
The following attestation bundles were made for gossamer_web-0.9.6-cp38-abi3-win_amd64.whl:
Publisher:
release.yml on opticsWolf/gossamer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gossamer_web-0.9.6-cp38-abi3-win_amd64.whl -
Subject digest:
0c0214cd1bf33be2a095dc8ac4b4f549da29e20d5a027c2e7fefb09f4d0ba5e2 - Sigstore transparency entry: 2805439798
- Sigstore integration time:
-
Permalink:
opticsWolf/gossamer@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Branch / Tag:
refs/tags/v0.9.6 - Owner: https://github.com/opticsWolf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Trigger Event:
push
-
Statement type:
File details
Details for the file gossamer_web-0.9.6-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: gossamer_web-0.9.6-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e698cdf866852da8db239d01fc4ba954b37dcc5306add63e623d4fd9dd58b3b
|
|
| MD5 |
c2b59069b13742076dbde8c0097287cf
|
|
| BLAKE2b-256 |
e7cd11c7df72f6a6825137127295d0ad022b5da757cf6fbf4ddad8b3e1c88719
|
Provenance
The following attestation bundles were made for gossamer_web-0.9.6-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on opticsWolf/gossamer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gossamer_web-0.9.6-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
2e698cdf866852da8db239d01fc4ba954b37dcc5306add63e623d4fd9dd58b3b - Sigstore transparency entry: 2805439789
- Sigstore integration time:
-
Permalink:
opticsWolf/gossamer@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Branch / Tag:
refs/tags/v0.9.6 - Owner: https://github.com/opticsWolf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Trigger Event:
push
-
Statement type:
File details
Details for the file gossamer_web-0.9.6-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: gossamer_web-0.9.6-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.6 MB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfa6aedae85b1aeab55d6fdc6865dfdfdce9ff9a6344d50c0ffb5d14e9ddacdc
|
|
| MD5 |
8d7b7b0039350e60aa35b6e1e193ddda
|
|
| BLAKE2b-256 |
2834909fe2dc5ce006a76e65f60cd5774e9fec7bf98ce2afa5dfd4f0fea618e8
|
Provenance
The following attestation bundles were made for gossamer_web-0.9.6-cp38-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on opticsWolf/gossamer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gossamer_web-0.9.6-cp38-abi3-macosx_11_0_arm64.whl -
Subject digest:
bfa6aedae85b1aeab55d6fdc6865dfdfdce9ff9a6344d50c0ffb5d14e9ddacdc - Sigstore transparency entry: 2805439814
- Sigstore integration time:
-
Permalink:
opticsWolf/gossamer@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Branch / Tag:
refs/tags/v0.9.6 - Owner: https://github.com/opticsWolf
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1854f16ec22da13b0380fd7ca7fee371b5976ded -
Trigger Event:
push
-
Statement type: