Skip to main content
Glama

Argus

Python 3.11+ PyPI Version PyPI Downloads License: MIT CI MCP Registry Docker

Retrieval platform for AI agents. Argus routes search across 14 providers, recovers dead URLs, captures important site content, builds local docs-plus-research packs, and persists everything with traceable local artifacts.

Features at a glance:

  • Topology-aware acquisition — Argus knows if it's on a residential IP or datacenter, routing search and extraction automatically to avoid blocks and minimize network hops.

  • 14 providers, one API — free-first tier routing, budget-exhausted providers skipped automatically

  • Zero-key start — pip install argus-search gives you DuckDuckGo + Yahoo immediately, no accounts needed

  • SearXNG self-host = 70+ engines — Google, Bing, Yahoo, Startpage, Ecosia, Qwant and more via one Docker container

  • 12-step content extraction — returns full page text with quality gates, not just links

  • Opinionated retrieval workflows — recover dead articles, capture important pages from a site, and build local docs-plus-research packs

  • Argus-owned corpus storage — runtime data goes to a writable user data directory, not your repo checkout

  • Multi-turn sessions — pass session_id for conversational context across searches

  • Score attribution — optionally show which providers contributed to each fused RRF score

  • Usage dashboard — inspect provider budgets, recent query volume, and machine-level usage at /dashboard

  • 4 search modes — discovery, research, recovery, grounding

  • Dead URL recovery — /recover-url with Wayback Machine and archive fallbacks

  • 4 integration paths — HTTP API, CLI, MCP server, Python SDK

Built for AI agent builders, RAG pipelines, and ops teams who need reliable search, capture, and local evidence without stitching APIs together.

Status: beta. The retrieval workflows and corpus model are production-oriented, but still maturing.

Status: see the public status page. Authorized maintainers can use the private argus-ops README for the latest dated reports.

Current production checkpoint — September 7, 2026: The authenticated HTTP API and MCP adapter are operational, and sampled free search works through SearXNG, Yahoo, and GitHub. DuckDuckGo is intermittent and fails closed after acquisition-policy blocks. Production readiness is ready=true, degraded; paid providers are not currently admitted until their non-secret credential-version and account-scope bindings are recorded. Browser capability and recovery metadata evidence remain open. See the current status matrix before relying on a provider.

Contents

Related MCP server: Agent Search MCP

Quickstart

Mode 1: Local CLI (zero config)

pip install argus-search && argus search -q "python web frameworks"

That's it. DuckDuckGo handles the search — no accounts, no keys, no containers. You get unlimited free search from your laptop right now. Add API keys whenever you want more providers, or don't.

argus extract -u "https://example.com/article"       # extract clean text from any URL
argus recover-article -u "https://example.com/dead-post"
argus capture-site -u "https://docs.example.com"
argus build-research-pack -t "example sdk" --official-url "https://docs.example.com"

Works on any machine with Python 3.11+ — laptop, Mac Mini, Raspberry Pi, cloud VM. Nothing to host.

For MCP (Claude Code, Codex, OpenCode, Cursor, VS Code):

pipx install argus-search[mcp]
export ARGUS_MCP_STANDALONE=true  # explicit development-only local broker
argus mcp init --global --client all

That writes native config for Claude Code, Codex CLI, OpenCode, and Cursor. Restart the client after configuration. For manual stdio setup:

{"mcpServers": {"argus": {"command": "argus", "args": ["mcp", "serve"], "env": {"ARGUS_MCP_STANDALONE": "true"}}}}

Or install from the MCP Registry:

{
  "mcpServers": {
    "argus": {
      "registryType": "pypi",
      "identifier": "argus-search",
      "runtimeHint": "uvx",
      "env": {"ARGUS_MCP_STANDALONE": "true"}
    }
  }
}

Standalone development needs no server or keys, but it must be explicitly enabled. Production MCP always delegates to an authenticated HTTP authority.

See MCP Client Setup for exact config files, verification commands, remote HTTP setup, and troubleshooting.

Mode 2: Full Stack Server

Got a Raspberry Pi running Pi-hole? A Mac Mini on your desk? An old laptop? That's enough to run the full stack — SearXNG (your own private search engine, disabled by default) plus local JS-rendering content extraction.

# Optional: tell Argus it has residential egress to optimize routing
export ARGUS_EGRESS_TYPE=residential
ARGUS_SEARXNG_ENABLED=true docker compose up -d    # SearXNG + Argus

What you have

What you get

Any machine with Python 3.11+

DuckDuckGo + API providers (no server)

Home server / old laptop (4GB+)

Everything — SearXNG, all providers, Crawl4AI, Obscura

Mac Mini M1+ (8GB+)

Full stack with headroom

Free cloud VM (1GB)

SearXNG + search providers (use residential workers for extraction)

SearXNG takes 512MB of RAM and gives you a private Google-style search engine (disabled by default — set ARGUS_SEARXNG_ENABLED=true) that nobody can rate-limit, block, or charge for. It runs alongside Pi-hole on hardware millions of people already own.

Where Argus Writes Data

Argus code and Argus runtime data are different things.

  • Code lives wherever you install or clone Argus.

  • Runtime corpus data lives in a writable user data directory resolved by platformdirs, or in ARGUS_DATA_ROOT if you override it.

Inspect the exact paths on your machine:

argus paths

By default Argus writes:

  • official docs cache under the resolved docs/cache/

  • research packs under docs/research/

  • workflow run state under workflows/runs/

  • versioned workflow snapshots under snapshots/

This means Argus does not require a sibling ../docs-cache checkout. If you have an older docs-cache tree, import it once with:

argus corpus import-docs-cache -s /path/to/docs-cache

Opinionated Workflows

These workflows build local artifacts, not just transient JSON responses.

Recover A Dead Article

argus recover-article -u "https://example.com/old-post" -t "Example Post"

Argus searches for recovery candidates, extracts the best result, saves the recovered sources locally, and writes a citation-backed report plus manifest.

Capture The Important Parts Of A Site

argus capture-site -u "https://docs.example.com"

Argus stays on-domain, uses sitemap-assisted discovery plus heuristic link scoring, saves the important pages it finds, and writes a detailed summary with references.

Build A Docs + Research Pack

argus build-research-pack -t "example sdk"
argus build-research-pack -t "example sdk" --official-url "https://docs.example.com"

Argus captures official docs into its local docs cache, adds non-official supporting sources from search, and writes a combined research pack with traceable artifacts.

Development

Repo development is pinned to Python 3.12. The package runtime floor is Python 3.11, the production image runs Python 3.12.3, and Python 3.13 is the compatibility CI lane. Required CI passes all three; contributors should use the uv workflow below so local verification matches the canonical lane and does not accidentally use an older system interpreter.

uv sync --python 3.12 --extra dev --extra mcp
uv run pytest tests/ -v --tb=short

The repo includes .python-version with 3.12 so uv, pyenv, and similar tools pick the right interpreter by default. More contributor guidance lives in CONTRIBUTING.md.

Providers

Provider

Credit type

Free capacity

Setup

DuckDuckGo

Free (scraped)

Unlimited

None

Yahoo

Free (scraped)

Unlimited

None — fragile, auto-skipped if broken

SearXNG

Free (self-hosted, off by default)

Unlimited — 70+ engines¹

Docker

GitHub

Free (API)

Unlimited

None (token for higher rate limit)

WolframAlpha

Free (API key)

2,000 queries/month

free key

Brave Search

Monthly recurring

2,000 queries/month

dashboard

Tavily

Monthly recurring

1,000 queries/month

signup

Exa

Monthly recurring

1,000 queries/month

signup

Linkup

Monthly recurring

1,000 queries/month

signup

Parallel AI

Monthly recurring

$5 credit with card on file, up to 5,000 searches/month

signup

Serper

One-time signup

2,500 credits

signup

You.com

One-time signup

$20 credit

platform

Valyu

One-time signup

$10 credit

platform

¹ SearXNG aggregates Google, Bing, Yahoo, Startpage, Ecosia, Qwant, Wikipedia, and 60+ more — all behind a single self-hosted endpoint. Run docker compose up -d on any machine with 512MB of free RAM.

² WolframAlpha returns computed answers (math, unit conversions, factual lookups), not web search results. It only activates in grounding and research modes. Queries it can't compute (general web searches) return empty — no error, no health penalty.

7,000+ free queries/month from recurring free-tier providers with API keys (WolframAlpha 2k + Brave 2k + Tavily 1k + Exa 1k + Linkup 1k), or up to 12,000+ when Parallel's monthly credit is available to an eligible account with a card on file. DuckDuckGo, Yahoo, and GitHub have no monthly cap. SearXNG is disabled by default (enable in .env). Routing priority: Tier 0 (free: SearXNG*, DuckDuckGo, Yahoo, GitHub, WolframAlpha) → Tier 1 (monthly recurring: Brave, Tavily, Exa, Linkup, Parallel) → Tier 3 (one-time: Serper, You.com, Valyu, SearchAPI). Budget-exhausted providers are skipped automatically.

These are package-level provider tiers and advertised quotas, not proof of current production availability. The production authority fails closed for a credentialed provider until its registration fingerprint, account scope, budget, and approved test evidence are present. A protected key value alone does not prove that the current key works; see docs/STATUS.md for the live classification.

HTTP API

All endpoints prefixed with /api. OpenAPI docs at http://localhost:8000/docs.

Local loopback calls can use the API without auth. Remote HTTP callers must send ARGUS_API_KEY as either Authorization: Bearer ... or X-API-Key: .... Privileged routes under /api/admin/* require ARGUS_ADMIN_API_KEY (or fall back to ARGUS_API_KEY if no separate admin key is configured).

# Search
curl -X POST http://localhost:8000/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "python web frameworks", "mode": "discovery", "max_results": 5}'

# Search with score attribution
curl -X POST http://localhost:8000/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "python web frameworks", "include_attribution": true}'

# Multi-turn search (conversational refinement)
curl -X POST http://localhost:8000/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "what about async?", "session_id": "my-session"}'

# Extract content from a working URL
curl -X POST http://localhost:8000/api/extract \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/article"}'

# Recover a dead or moved URL
curl -X POST http://localhost:8000/api/recover-url \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/old-page", "title": "Example Article"}'

# Network-free process liveness (container health target)
curl http://localhost:8000/api/live

# Public minimal startup and cached readiness
curl http://localhost:8000/api/startup
curl http://localhost:8000/api/ready

# Authenticated operator status, health compatibility, and budgets
curl -H "Authorization: Bearer $ARGUS_ADMIN_API_KEY" \
  http://localhost:8000/api/admin/status
curl -H "Authorization: Bearer $ARGUS_ADMIN_API_KEY" \
  http://localhost:8000/api/admin/budgets
curl -H "Authorization: Bearer $ARGUS_ADMIN_API_KEY" \
  http://localhost:8000/api/admin/maya-outbox/status
curl -H "Authorization: Bearer $ARGUS_ADMIN_API_KEY" \
  http://localhost:8000/api/admin/maya-outbox/dead-letters
# After correcting the cause of a permanent rejection:
curl -X POST -H "Authorization: Bearer $ARGUS_ADMIN_API_KEY" \
  http://localhost:8000/api/admin/maya-outbox/DELIVERY_ID/recover

/api/health remains a 200 liveness compatibility route. It intentionally does not check PostgreSQL, providers, Maya, or the browser, so a dependency outage cannot cause container restart storms. See production operations for the canonical topology and operator procedures, and operational status for endpoint semantics, readiness classification, observation expiry, and safe telemetry.

Search modes

Mode

Use for

Example

discovery

Related pages, canonical sources

"Find the official docs for X"

research

Broad exploratory retrieval

"Latest approaches to Y?"

recovery

Finding moved/dead content

"This URL is 404"

grounding

Fact-checking with live sources

"Verify this claim about Z"

Tier-based routing always applies first. Within each tier, the mode selects provider order.

Response format

{
  "query": "python web frameworks",
  "mode": "discovery",
  "results": [
    {
      "url": "https://fastapi.tiangolo.com",
      "title": "FastAPI",
      "snippet": "Modern Python web framework",
      "provider": "duckduckgo",
      "score": 0.0164,
      "score_attribution": {"duckduckgo": 0.0164},
      "egress": "unknown",
      "machine": null
    }
  ],
  "total_results": 1,
  "cached": false,
  "traces": [
    {"provider": "duckduckgo", "status": "success", "results_count": 5, "latency_ms": 312}
  ]
}

Each result includes url, title, snippet, domain, provider, and score. The traces array shows which providers were called and their outcomes.

When include_attribution is true, each result also includes score_attribution: a provider-to-score map that decomposes the result's Reciprocal Rank Fusion score. RRF is additive, so each provider's attribution is exactly its own rank contribution, and the values sum to score. Attribution is off by default and cached separately from non-attributed searches.

Budgets

{
  "budgets": {
    "brave": {"remaining": 1847, "monthly_usage": 153, "usage_count": 153, "exhausted": false},
    "duckduckgo": {"remaining": 0, "monthly_usage": 0, "usage_count": 42, "exhausted": false}
  },
  "token_balances": {"jina": 9833638}
}

Each provider tracks usage. Tier 1 (monthly) uses a 30-day rolling window; tier 3 (one-time) uses a lifetime counter that never resets. When a provider hits its budget, Argus skips it and moves to the next. Free providers (DuckDuckGo, GitHub) have no limit. SearXNG is free but disabled by default. Set ARGUS_*_MONTHLY_BUDGET_USD to enforce custom limits per provider.

Dashboard

Run the HTTP server and open /dashboard:

argus serve
# http://127.0.0.1:8000/dashboard

The dashboard shows provider budget burn, over-pace and exhausted providers, query volume for the last 30 days, usage by machine, and recent provider activity. Budget cards refresh automatically.

Set ARGUS_ADMIN_API_KEY to require dashboard login. If no admin key is set, the dashboard is open to anyone who can reach the server, which is suitable only for trusted local use.

For subpath deployment behind a reverse proxy, set ARGUS_ROOT_PATH to the external path prefix:

ARGUS_ROOT_PATH=/argus argus serve

That makes dashboard redirects, links, and HTMX fragment URLs work when the proxy serves Argus at a path such as https://khamel.com/argus/.

For direct public HTTPS, the repo includes a Caddy profile:

ARGUS_DOMAIN=argus.example.com ACME_EMAIL=you@example.com \
  docker compose --profile proxy up -d

For an existing Authentik/nginx deployment, keep authentication at the proxy layer and set ARGUS_ROOT_PATH to the public prefix.

Integration

CLI

argus search -q "python web framework"              # zero-config, uses DuckDuckGo
argus search -q "python web framework" --mode research -n 20
argus search -q "python web framework" --free        # free providers only (no paid API calls)
argus search -q "python web framework" --attribution # show per-provider score attribution
argus search -q "fastapi" --session my-session       # multi-turn context
argus extract -u "https://example.com/article"       # extract clean text
argus extract -u "https://example.com/article" -d nytimes.com  # auth extraction
argus recover-url -u "https://dead.link" -t "Title"
argus doctor                                         # full setup diagnostics
argus health                                         # provider status
argus budgets                                        # budget + token balances
argus mcp check                                      # validate MCP setup
argus set-balance -s jina -b 9833638                 # track token balance
argus test-provider -p brave                         # smoke-test a provider
argus serve                                          # start API server
argus mcp serve                                      # start MCP server
argus mcp init                                       # add MCP config to project

All commands support --json for structured output.

Pass session_id to any search call. Argus stores each query and extracted URL through the same SQLAlchemy repository used by the retrieval ledger (ARGUS_DB_URL, PostgreSQL in production and SQLite for direct local use). Reusing the same session_id gives the broker context from prior queries — follow-up searches are automatically refined using earlier conversation context. Sessions persist across restarts. Omit session_id for stateless, one-shot searches.

Legacy sessions from the former budget SQLite database can be reconciled without mutating the target first:

argus ledger reconcile-sessions \
  --source sqlite:///argus_budgets.db \
  --target "$ARGUS_DB_URL"
# Review source/imported/skipped/conflicting, then repeat with --apply.

The import is idempotent: an identical existing session is skipped and a different session with the same ID is reported as conflicting.

MCP

MCP is a stateless execution adapter over the authenticated HTTP API. It does not construct providers or a broker and does not own browser, database, budget, session, health, or outbox state. Configure the adapter process with:

export ARGUS_AUTHORITY_URL=http://argus-api:8000
export ARGUS_AUTHORITY_TOKEN=replace-with-a-scoped-caller-token

The deployed production endpoint supports both the verified MCP 2025-11-25 compatibility contract and the MCP 2026-07-28 stateless transport revision. The newer path is one-shot and does not require an initialize handshake or Mcp-Session-Id; durable policy, budgets, sessions, and evidence remain owned by the HTTP authority. See docs/research/2026-08-11-mcp-stateless-production-authority.md for the source-backed boundary and required no-spend probes.

Option A — Local adapter (stdio)

Install the adapter on the same machine as your MCP client:

{
  "mcpServers": {
    "argus": {
      "command": "argus",
      "args": ["mcp", "serve"]
    }
  }
}

Use the full path if argus isn't on PATH: "/home/you/.local/bin/argus". The adapter inherits ARGUS_AUTHORITY_URL and ARGUS_AUTHORITY_TOKEN from the client process. To run a local broker instead, development environments must explicitly set ARGUS_MCP_STANDALONE=true; production rejects it.

Works with Claude Code, Codex CLI, OpenCode, Cursor, and any stdio-based MCP client. Use argus mcp init --global --client all to write native client configs for the current machine.

Detailed client setup and verification commands live in docs/mcp-clients.md.

Option B — Remote MCP adapter (clients over Tailscale)

Run Argus on one machine, connect every client over the network. No local install on clients.

On the adapter host:

export ARGUS_API_KEY=replace-with-a-long-random-secret
export ARGUS_AUTHORITY_URL=http://argus-api:8000
export ARGUS_AUTHORITY_TOKEN="$ARGUS_API_KEY"
argus mcp serve --transport streamable-http --host YOUR_TAILSCALE_IP --port 8001

Remote MCP credentials must also be valid scoped credentials at the HTTP authority because the adapter forwards each authenticated bearer token unchanged. For stdio, ARGUS_AUTHORITY_TOKEN is the caller credential.

To keep the HTTP API and remote MCP service running after reboot on a systemd host:

cat >mcp.env <<'EOF'
ARGUS_AUTHORITY_URL=http://argus-api:8000
ARGUS_AUTHORITY_TOKEN=replace-with-scoped-caller-token
ARGUS_API_KEY=replace-with-the-same-scoped-caller-token
EOF
chmod 600 mcp.env
ARGUS_MCP_ENV_FILE="$PWD/mcp.env" scripts/install-systemd.sh
systemctl status argus argus-mcp --no-pager

The installer validates the minimal adapter environment, installs it as root-only /etc/argus/mcp.env, then installs and starts both units. The MCP unit never loads the authority's .env, provider vaults, database settings, browser paths, or writable data volumes.

On each client:

Client

Config

Claude Code

{"mcpServers":{"argus":{"type":"http","url":"http://<server>:<port>/mcp","headers":{"Authorization":"Bearer <ARGUS_API_KEY>"}}}} in ~/.claude.json (global) or .mcp.json (project)

OpenCode

{"mcp":{"argus":{"type":"remote","url":"http://<server>:<port>/mcp","enabled":true,"headers":{"Authorization":"Bearer <ARGUS_API_KEY>"}}}} in ~/.config/opencode/config.json (global) or .opencode/opencode.json (project)

Cursor

Same as Claude Code — reads .mcp.json

Codex CLI

[mcp_servers.argus] section in ~/.codex/config.toml with url and bearer_token_env_var = "ARGUS_API_KEY" — export that variable in the shell that launches Codex; argus mcp init never writes the token to disk

Gemini CLI

gemini mcp add argus http://<server>:<port>/mcp -t http -H "Authorization: Bearer <ARGUS_API_KEY>"

Antigravity

{"mcpServers":{"argus":{"serverUrl":"http://<server>:<port>/mcp","headers":{"Authorization":"Bearer <ARGUS_API_KEY>"}}}}

With Tailscale, <server> is your machine's Tailscale IP (e.g. 100.x.x.x). One server, every machine on your mesh gets search.

One-command provisioning:

# Load secrets, then push config to any machine:
eval $(secrets decrypt argus | grep -E 'ARGUS_REMOTE_URL|ARGUS_API_KEY' | sed 's/^/export /')

curl -s https://raw.githubusercontent.com/Khamel83/argus/main/scripts/provision-mcp-client.sh | bash -s local              # this machine; uses local stdio if argus is installed
curl -s https://raw.githubusercontent.com/Khamel83/argus/main/scripts/provision-mcp-client.sh | bash -s user@100.x.x.x    # remote machine

The script writes Claude/Cursor, Codex, and OpenCode configs on the target. Local stdio does not require an MCP listener key, but the adapter still requires its scoped ARGUS_AUTHORITY_TOKEN. Remote MCP mode requires ARGUS_REMOTE_URL and ARGUS_API_KEY. Requires Python 3.

argus mcp init also generates configs automatically:

argus mcp init --global              # local stdio adapter for Claude Code + OpenCode + Cursor
argus mcp init --client codex        # local stdio for Codex (writes ~/.codex/config.toml)
argus mcp init --client opencode     # local stdio for OpenCode
ARGUS_REMOTE_URL=http://argus.local:8271 ARGUS_API_KEY=... argus mcp init --global --client all
argus mcp init --client gemini       # prints gemini mcp add command
argus mcp init --global --client all # everything above

Release Status

Pushing main does not publish PyPI. Package and MCP Registry publication happens through the GitHub publish workflow on release creation or manual dispatch. See docs/releasing.md for version sync, preflight checks, and publish verification.

Transports: stdio (default local adapter), sse (legacy remote), and streamable-http (modern remote, "type":"http" in config). Remote MCP transports require ARGUS_API_KEY; every transport delegates execution to ARGUS_AUTHORITY_URL.

Available tools:

  • HTTP-backed stdio and remote MCP: search_web, extract_content, recover_url, expand_links, search_health, search_budgets, recover_dead_article, capture_site, and build_research_pack

  • Explicit standalone development additionally exposes local-only test_provider, cookie_health, valyu_answer, path/file tools, and resources. These are intentionally absent from production adapters.

search_web accepts free_only=true to restrict results to free (tier-0) providers only, and include_attribution=true to include per-provider score attribution in the Markdown response.

Using Argus from MCP vs HTTP

Two transports, one rule: agents use MCP, everything else uses HTTP.

  • MCP (argus mcp serve) — a stateless authenticated adapter for AI harnesses that speak MCP natively. Core tools delegate to the HTTP authority: search_web, extract_content, recover_url, expand_links, and workflow starts. MCP restarts cannot fork accounting, sessions, health, or outbox state.

  • HTTP (POST /api/search, POST /api/extract, POST /api/workflows/...) — for scripts, cron jobs, and service integrations (including Maya). Send a scoped caller credential in Authorization; body "caller" values are diagnostic labels and cannot override the authenticated identity.

The cross-service transport and role contract for the wider fleet (Maya / Hermes / Argus) is canonical in Maya's architecture documentation.

Python

Direct broker and extraction imports are a standalone development convenience. Production Python callers use the authenticated HTTP API so all execution and durable accounting remain in one authority.

from argus.broker.router import create_broker
from argus.models import SearchQuery, SearchMode
from argus.extraction import extract_url

broker = create_broker()

response = await broker.search(
    SearchQuery(query="python web frameworks", mode=SearchMode.DISCOVERY, max_results=10),
    compute_attribution=True,
)
for r in response.results:
    print(f"{r.title}: {r.url} (score: {r.score:.3f})")
    print(r.score_attribution)

content = await extract_url(response.results[0].url)
print(content.title)
print(content.text)

Content Extraction

Argus tries up to twelve methods to extract content from any URL: auth extraction for paywalls, then local extractors (trafilatura, Crawl4AI, Obscura, Playwright, residential IP), then external APIs (Jina, Valyu Contents, Firecrawl, You.com, Wayback, archive.is). Each attempt is quality-checked for completeness and garbage output. See docs/providers.md for the full extractor comparison.

Completeness assessment runs automatically after every successful extraction. Argus scores five signals — trailing ellipsis, feed truncation markers ("Read more", WordPress RSS footers), mid-sentence endings, abrupt final paragraphs, and suspicious round word counts — and returns is_complete, completeness_confidence, and truncation_type alongside the text. When confidence is ≥ 85%, Argus continues trying the next extractor rather than returning a partial result; this means a trafilatura fetch that ends with "..." will automatically fall through to Playwright, Jina, Wayback, etc. Callers that already have text (e.g. RSS feed items) can use POST /api/assess-content to check completeness without triggering extraction.

Obscura (optional) is a lightweight Rust headless browser (~70MB binary, 30MB RAM) with built-in stealth mode — it sets navigator.webdriver=undefined, randomizes canvas/GPU/audio fingerprints per session, and blocks 3,520 tracker domains. This directly addresses bot detection on JS-heavy and anti-scraping sites that block standard Playwright/Chrome. No API key, no rate limit — fully local.

Two ways to use it:

Mode

Setup

What you get

CLI extraction step

Install binary on $PATH

Argus auto-detects it; stealth browser as fallback step before Playwright

CDP backend for Playwright

Run obscura serve --stealth --port 9222, set ARGUS_OBSCURA_CDP_URL=ws://127.0.0.1:9222

Playwright uses Obscura as its browser engine — stealth + 30MB vs 200MB + DOM-to-Markdown output

Install the binary: github.com/h4ckf0r0day/obscura/releases

Extract gets the full text of a working URL and tells you whether that text is complete. Recover-URL finds alternatives when a URL is dead, paywalled, or radically changed.

Architecture

Caller (CLI/HTTP/MCP/Python) → SearchBroker → tier-sorted providers → RRF ranking → response
                                     ↕ SessionStore (optional)
                            Extractor (on demand) → 12-step fallback chain with quality gates

Module

Responsibility

argus/broker/

Tier-based routing, ranking, dedup, caching, health, budgets

argus/providers/

Provider adapters (one per search API)

argus/extraction/

12-step URL extraction fallback chain with quality gates

argus/sessions/

Multi-turn session store and query refinement

argus/api/

Authenticated production execution authority

argus/cli/

HTTP caller in production; direct execution in development

argus/mcp/

Stateless MCP-to-HTTP adapter

argus/persistence/

Shared PostgreSQL authority state; SQLite standalone development

argus/operations/

Cached readiness, typed dependency observations, process identity, bounded metrics

Add new providers or extractors with a single adapter file. See CONTRIBUTING.md for the interface.

How a Query Works

query arrives → cache? → build provider queue → execute sequentially → RRF fuse → dedup → respond
  1. Cache check. SearchCache hashes the normalized query, mode, and whether attribution was requested (SHA256). Hit returns immediately with a TTL of 168 hours (7 days).

  2. Provider queue. resolve_routing() takes the mode-specific preference list and stable-sorts by tier: tier 0 (free) first, tier 1 (monthly) next, tier 3 (one-time) last. Example for discovery mode:

    searxng → duckduckgo → yahoo → github → brave → exa → tavily → linkup → parallel → serper → you → valyu
  3. Sequential execution with gates. Each provider is checked in order. Four gates must pass before an API call:

    • Config — is the provider enabled and configured (API key present)?

    • Health — has it failed 5+ consecutive times (triggers 60-minute cooldown)?

    • Budget — for tier 1+: is the budget exhausted? For tier 1 (monthly), pacing checks if the 7-day usage rate would drain the remaining budget in under a week — empty days bank headroom. For tier 3 (one-time), a lifetime counter gates access — exhaustion is the sole check.

    • Execute — the actual HTTP call. Successes reset failure counters; failures increment them.

  4. RRF fusion. Results from all queried providers are merged using Reciprocal Rank Fusion (k=60). Each result's score is the sum of 1/(k + rank) across every provider that returned it. Results appearing in multiple providers rank higher.

  5. Dedup and truncate. URLs are normalized (stripped www., tracking params like utm_*, trailing slashes) and deduplicated. The merged list is truncated to max_results (default 10).

  6. Cache and persist. The authority writes the final response to its in-memory cache and configured SQL repository (PostgreSQL in production, SQLite for standalone development). Search results and extractions include provenance metadata (egress, machine, source_type) for downstream audit. Existing databases are upgraded additively at startup.

Configuration

All config via environment variables. See .env.example for the full list. Limited API-key providers are opt-in: set both the API key and ARGUS_<PROVIDER>_ENABLED=true. Missing keys degrade gracefully — providers are skipped, not errors.

When running from the repo, Argus now auto-loads .env and .env.local (without overriding already-exported environment variables). Disable this behavior with ARGUS_AUTOLOAD_DOTENV=false.

Variable

Default

Description

ARGUS_WORKER_BIND

127.0.0.1:8273

Legacy development worker bind; requires explicit ARGUS_ENV=development

ARGUS_EGRESS_SHARED_SECRET

(empty)

Required bearer secret for every legacy worker execution request, including loopback

ARGUS_NODE_ROLE

primary

Production authority is primary; adapters are caller; direct/worker execution is development-only

ARGUS_AUTHORITY_URL

—

HTTP API base URL required by production CLI and MCP adapters

ARGUS_AUTHORITY_TOKEN

—

Scoped caller token for production CLI and MCP adapters

ARGUS_MCP_STANDALONE

false

Explicit development-only local MCP execution

ARGUS_EGRESS_TYPE

unknown

residential, datacenter, or unknown

ARGUS_RESIDENTIAL_POLICY

fallback

off, fallback, prefer_on_datacenter, prefer_for_domains, or always

ARGUS_SEARXNG_ENABLED

false

Set true when you have a SearXNG Docker container

ARGUS_SEARXNG_BASE_URL

http://127.0.0.1:8080

SearXNG endpoint

ARGUS_SEARXNG_RESIDENTIAL_BASE_URL

—

Remote residential SearXNG endpoint (e.g. over Tailscale)

ARGUS_<PROVIDER>_ENABLED

false for limited API-key providers

Opt in to providers that consume limited credits or quotas

ARGUS_BRAVE_API_KEY

—

Brave Search API key

ARGUS_SERPER_API_KEY

—

Serper API key

ARGUS_TAVILY_API_KEY

—

Tavily API key

ARGUS_EXA_API_KEY

—

Exa API key

ARGUS_LINKUP_API_KEY

—

Linkup API key

ARGUS_PARALLEL_API_KEY

—

Parallel AI API key

ARGUS_YOU_API_KEY

—

You.com API key

ARGUS_VALYU_API_KEY

—

Valyu API key (search, contents, answer)

ARGUS_FIRECRAWL_API_KEY

—

Firecrawl API key (content extraction)

ARGUS_GITHUB_API_KEY

—

GitHub token (higher rate limit)

ARGUS_DATA_ROOT

platformdirs user data dir

Override the Argus runtime corpus root

ARGUS_*_MONTHLY_BUDGET_USD

provider-specific

Query-count budget for most providers; USD budget for Valyu

ARGUS_CRAWL4AI_ENABLED

false

Enable Crawl4AI extraction step

ARGUS_YOU_CONTENTS_ENABLED

false

Enable You.com Contents API extraction

ARGUS_OBSCURA_CDP_URL

—

Obscura CDP endpoint (e.g. ws://127.0.0.1:9222) — makes Playwright use Obscura as its browser engine

ARGUS_OBSCURA_TIMEOUT_SECONDS

20

Timeout for Obscura CLI subprocess calls

ARGUS_AUTH_BROWSER_DOMAINS

—

Temporary, off by default (#148). Comma-separated paywall domains whose cookie-backed authenticated_content HTTPS browser requests may run without a browser-network attestation. Applies only when no attestation is present; same-origin guards still apply

ARGUS_CACHE_TTL_HOURS

168

Result cache TTL

ARGUS_BIND_HOST

127.0.0.1

Host used by argus serve unless --host is passed

ARGUS_PORT

8000

Port used by argus serve unless --port is passed

ARGUS_AUTOLOAD_DOTENV

true

Auto-load .env / .env.local from cwd and repo root for CLI/API/MCP processes

ARGUS_API_KEY

—

Required for non-local HTTP API and remote MCP callers

ARGUS_ADMIN_API_KEY

—

Enables dashboard login and admin API authentication

ARGUS_ACCEPTED_OPERATION_AUTHORITY

legacy

Atomic authority selection. evidence activates the registered planner, readiness, evidence repository, extraction finalizer, and HTTP presenters as one unit

ARGUS_ALLOWED_HOSTS

—

Exact comma-separated HTTP Host allowlist; required for a remote production listener

ARGUS_ALLOWED_ORIGINS

—

Exact comma-separated browser Origin allowlist. Set explicitly, including an empty value, for remote production

ARGUS_RETRIEVAL_SESSION_SECRET

—

Stable random secret of at least 32 characters used to bind v2 retrieval sessions to authenticated principals

ARGUS_ORGANIZATION_POLICY_VERSION

1

Stable organization-policy identity included in accepted execution cohorts

ARGUS_ROOT_PATH

—

Public subpath prefix for dashboard links and redirects, e.g. /argus

ARGUS_MAYA_CAPTURE_URL

—

Maya's dedicated Argus retrieval-capture endpoint; delivery stays disabled when unset

ARGUS_MAYA_CAPTURE_TOKEN

—

Dedicated shared secret for Maya capture delivery; never reuse the generic Maya ingest token

ARGUS_MAYA_OUTBOX_BATCH_SIZE

20

Maximum durable captures claimed by one delivery pass (bounded to 100)

ARGUS_MAYA_ACKNOWLEDGED_RETENTION_DAYS

7

Days to retain acknowledged capture bodies before preserving audit metadata only

/api/v2/* is additive and returns a canonical version-2 envelope. It remains fail-closed with unready while the evidence authority is disabled. Unsafe Host, Origin, credential, media-type, and body-size combinations are rejected before provider, extractor, session, or persistence work. Version-1 routes retain their established response shapes.

When Not To Use Argus

Argus is best when you need search, capture, provenance, and local artifacts together.

Avoid it when:

  • you only need one search API and do not need fallback or budget controls

  • you only need a one-off page scrape with no persistent corpus or report output

  • you need an end-user search UI rather than backend retrieval infrastructure

  • you need fully deterministic summarization with no heuristic or LLM-assisted steps

FAQ

How is this different from calling Tavily/Serper directly? Argus calls them for you — plus 13 other providers. You get one ranked, deduplicated result set instead of managing multiple API keys and stitching results together. Free providers are tried first, so you only burn credits when needed.

Can I run only one provider? Yes. Set only the API key for the provider you want. All others are silently skipped. For zero-config, just install and go — DuckDuckGo + Yahoo handle search with no keys.

Do I need Docker? No. pip install argus-search works immediately on any machine with Python 3.11+. Docker is only needed for SearXNG (set ARGUS_SEARXNG_ENABLED=true in .env) or Crawl4AI (local JS rendering).

Which Python version should contributors use? Use Python 3.12 for repo development and verification: uv sync --python 3.12 --extra dev --extra mcp then uv run pytest tests/ -v --tb=short. The published package still supports Python 3.11+.

What is the safest way to deploy Argus on a network? Use Tailscale or another private network, bind explicitly to the trusted interface, set ARGUS_API_KEY, and reserve /api/admin/* for ARGUS_ADMIN_API_KEY. Treat direct internet exposure as an advanced mode behind a reverse proxy.

License

MIT — see CHANGELOG.md for release history.

Available Tools

15 tools
build_research_packD
NameRequiredDescriptionDefault
topicYes
callerNomcp
free_onlyNo
official_urlNo
response_formatNomarkdown
research_targetsNo
max_research_pagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

capture_siteD
NameRequiredDescriptionDefault
urlYes
callerNomcp
hard_page_limitNo
soft_page_limitNo

Output Schema

NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_contentC

Extract content through the authenticated HTTP authority.

NameRequiredDescriptionDefault
urlYes
modeNodefault
callerNomcp
domainNo
free_onlyNo
content_typeNoarticle

Output Schema

NameRequiredDescription
resultYes

TDQS

C2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It only hints that authentication is required via 'authenticated HTTP authority' and says nothing about permissions, rate limits, whether the operation is read-only, what gets extracted, or how failures are handled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no verbosity, so it is concise. However, it is under-specified and jargon-heavy rather than structured to help an agent act.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, but the definition remains seriously incomplete for a six-parameter extraction tool with no annotations and zero schema parameter descriptions. An agent lacks enough context to select or configure it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and there are six parameters, including mode, caller, domain, free_only, and content_type. The description provides no explanation of any parameter's meaning, accepted values, or effect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description restates the tool name with the opaque phrase 'through the authenticated HTTP authority' and does not clarify what kind of content is extracted, from where, or how this differs from siblings such as extract_content_v2 or capture_site. It is close to a tautology rather than a meaningful statement of purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus search_web, capture_site, extract_content_v2, or other siblings. No prerequisites, exclusions, or alternative-selection criteria are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_content_v2D

Extract content through the HTTP-v2 evidence authority.

NameRequiredDescriptionDefault
urlYes
modeNodefault
callerNomcp
domainNo
free_onlyNo
content_typeNoarticle

Output Schema

NameRequiredDescription
errorYes
resultYes
outcomeYes
request_idYes
contract_versionYes

TDQS

D1.5/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full disclosure burden, and it says nothing about whether this performs network fetches, whether it hits live pages or an archive, what 'evidence authority' means operationally, or any rate limits or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is short, but brevity here is under-specification rather than efficiency. The single sentence is front-loaded with the verb but spends its remaining words on jargon that conveys no actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter tool with zero annotation coverage and zero schema documentation, an output schema only relieves the need to describe return values. Everything else an agent needs before calling it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description adds no parameter meaning whatsoever. The non-obvious parameters mode (default/archive_ingest), caller, domain, free_only, and content_type are left entirely unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Extract content" names a verb and resource, but "through the HTTP-v2 evidence authority" is opaque internal jargon that explains nothing. Nothing distinguishes this from the sibling extract_content or from search_web/recover_url, so an agent cannot tell what makes v2 different.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no alternates named, and no exclusions. With extract_content, recover_url_v2, expand_links_v2, and recover_dead_article as siblings, the absence of routing guidance is a real gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workflow_statusC

Read safe research-pack status from the authenticated authority.

NameRequiredDescriptionDefault
run_idYes
response_formatNomarkdown

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. 'Read safe' and 'authenticated authority' hint at read-only access and authentication, but do not specify permissions, side effects, or operational constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. Its terseness is efficient, though it leaves substantial gaps in meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no annotations, two undocumented parameters, and only an output schema, the description is too thin. It omits what status is returned, how run_id is used, and when to select this tool over related siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description does not mention run_id or response_format. The required run_id and response_format default remain undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a read operation for 'research-pack status,' which gives a general purpose. However, it does not clarify whether this is workflow status or research-pack status, and it does not distinguish the tool from siblings such as read_workflow_artifact or build_research_pack.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no alternative sibling is named. The agent must infer usage from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_workflow_artifactC

Read a bounded report or manifest slice from the authority.

NameRequiredDescriptionDefault
offsetNo
run_idYes
artifactNoreport
max_bytesNo
response_formatNomarkdown

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'Bounded' hints at truncation and 'Read' implies read-only, but permissions, what happens at the byte limit, error behavior (missing run/artifact), and pagination semantics are all undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. It is efficiently written, though its brevity is part of the under-specification problem rather than a virtue at this complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema covers return values, but with five undocumented parameters, no annotations, and an ambiguous 'authority' concept, the one-sentence description is far too thin for an agent to invoke this tool confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across five parameters. The phrase 'bounded report or manifest slice' loosely gestures at max_bytes, offset, and artifact, but does not explain run_id, valid artifact names, response_format options, or offset units, leaving most parameter meaning to inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Read' and the resource ('report or manifest slice') are stated, but 'from the authority' is undefined jargon and there is no differentiation from the sibling tools, none of which appear to read artifacts. An agent gets the gist but not a precise scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool, when not to, or what alternative to pick. The only implied context is that it relates to a workflow run (run_id), which doesn't help an agent choose it over get_workflow_status or the research-pack tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recover_dead_articleD
NameRequiredDescriptionDefault
urlYes
titleNo
callerNomcp
domainNo

Output Schema

NameRequiredDescription
resultYes

TDQS

D1/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recover_urlC

Recover a dead or moved URL through HTTP.

NameRequiredDescriptionDefault
urlYes
titleNo
callerNomcp
domainNo

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It says recovery happens 'through HTTP', but does not mention authentication, rate limits, redirect-following behavior, what 'recover' concretely means, or what happens on failure. For a network-facing recovery tool with no annotations, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler, which is concise and easy to scan. It is appropriately sized for a headline purpose statement, though the terseness leaves room for useful detail that could have been added without bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has four parameters, zero schema descriptions, no annotations, and an output schema. The description covers only the basic idea of recovering a URL and omits any explanation of the three optional parameters, behavioral details, or sibling differentiation. Given the complexity and lack of structured documentation, it is not complete enough for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across four parameters, and the description only mentions the URL as the object of recovery. It adds no meaning for the optional title, caller, or domain parameters, nor does it explain the expected URL format. The description does not compensate for the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'Recover' a 'URL'. It specifies the condition 'dead or moved' and the mechanism 'through HTTP', so the agent can understand the basic operation. However, it does not differentiate this tool from siblings such as recover_url_v2 or recover_dead_article, which is a missed opportunity for a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'dead or moved URL' implies the usage context, so the agent can infer this tool is for reviving broken links. But there is no explicit guidance on when to use this versus recover_url_v2 or recover_dead_article, nor any exclusions or prerequisites. Usage is only implied, not clarified.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recover_url_v2D

Recover a URL through the HTTP-v2 evidence authority.

NameRequiredDescriptionDefault
urlYes
titleNo
callerNomcp
domainNo

Output Schema

NameRequiredDescription
errorYes
resultYes
outcomeYes
request_idYes
contract_versionYes

TDQS

D1.5/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does not say whether this is a read or write, whether it mutates any state, what permissions or rate limits apply, or what "evidence authority" actually does; the only clue is the vague word "recover".

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single short sentence, so it is not bloated, but it is under-specified rather than concise: the one sentence is mostly opaque terminology and conveys almost no actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with four undocumented parameters, no annotations, and several near-duplicate siblings, the description is far from complete enough to invoke correctly. The output schema helps with return values, but nothing explains the operation itself or the alternatives.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across four parameters (url, title, caller, domain), and the description explains none of them. There is no hint about the format of url, the purpose of caller/domain, or how title is used, so the description adds nothing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a verb ("Recover") and resource ("URL"), but "recover" is left undefined and "HTTP-v2 evidence authority" is unexplained jargon. It gives no basis for distinguishing this from the sibling recover_url or recover_dead_article, so an agent cannot tell which tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool, when not to, or which sibling (recover_url, recover_dead_article, expand_links_v2) is the alternative. A nearly identical non-v2 sibling exists and is never mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_budgetsB

Read durable provider budgets from the HTTP authority.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden. It indicates a read operation but omits whether authentication is required, whether results are cached, rate limits, or any side effects. 'Durable' hints at persistence but is not elaborated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The single sentence is front-loaded and wastes no words. However, its extreme brevity may leave the agent under-informed, trading conciseness for completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While an output schema exists (covering return values), the description does not explain what 'provider budgets' are, why they matter, or when an agent should invoke this tool. Without annotations or usage context, the definition is incomplete for confident tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema already fully covers input semantics. The description does not need to add parameter details; the baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read') and resource ('durable provider budgets') plus the source ('HTTP authority'), making the basic purpose clear. Siblings are all web-research oriented, so no direct overlap exists, but the term 'provider budgets' remains somewhat jargon and could be clearer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool, what prerequisites exist, or what alternatives to consider. The single sentence offers no context about appropriate scenarios or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_healthA

Read provider health from the HTTP authority.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the behavioral load; 'Read' does imply a non-destructive, side-effect-free operation. An output schema exists, so return values need not be described here. However, nothing is said about what 'health' means (rate limit, quota, auth state, reachability) or whether the call itself is rate-limited or cached.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler, which is appropriate for a zero-argument utility tool. Its only weakness is that brevity shades into vagueness ('HTTP authority' is never unpacked), rather than any wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema documenting the response shape, the description is close to sufficient — an agent knows how to call it and what to expect. What is missing is scope/interpretation: whether it reports health for one provider or all of them, and what the caller should do with the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema defines zero parameters, so there is nothing parameter-related for the description to compensate for; the documented baseline of 4 applies. The description does not wrongly suggest that any scope parameter exists.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

It states a specific verb ('Read') and resource ('provider health'), which is enough to distinguish it from every sibling (search_web, recover_url, extract_content, etc. — none deal with health). The phrase 'from the HTTP authority' is opaque and leaves the source/scope of the health data ambiguous, which keeps it below a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer it should call this to check whether the underlying provider is healthy, and no sibling overlaps with that role. There is no explicit when/when-not guidance, no mention of prerequisites (auth, credentials), and no statement of whether it should be called before/after the search tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_webC

Search through the authenticated Argus HTTP authority.

NameRequiredDescriptionDefault
modeNodiscovery
queryYes
callerNomcp
free_onlyNo
session_idNo
max_resultsNo
include_attributionNo

Output Schema

NameRequiredDescription
resultYes

TDQS

C2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden, and it discloses almost nothing. The single useful signal is the word 'authenticated', implying credentials are required, but there is no mention of rate limits, result set size, mode semantics, or what 'free_only' gates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence is technically tight, but this is under-specification rather than conciseness. Brevity earns no credit when the result leaves a 7-parameter tool effectively undocumented.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema means return values need not be explained, but that is the only burden lifted. With no annotations, seven undocumented parameters, and no disambiguation from search_web_v2, the definition is nowhere near complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes 7 parameters at 0% schema description coverage, and the description adds no meaning to any of them. 'mode', 'caller', 'free_only', and 'include_attribution' are completely undefined in both structured and natural-language form.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description has a verb ('Search') and a resource ('the authenticated Argus HTTP authority'), so it is not a pure tautology. But 'Argus HTTP authority' is opaque jargon, and it never distinguishes this tool from the sibling 'search_web_v2', which an agent would naturally confuse it with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool, when not to, or which sibling to prefer. The presence of 'search_web_v2' in the sibling list makes the absence of routing guidance a real problem, not a minor omission.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_web_v2D

Search through the HTTP-v2 evidence authority.

NameRequiredDescriptionDefault
modeNodiscovery
queryYes
callerNomcp
free_onlyNo
session_idNo
max_resultsNo
include_attributionNo

Output Schema

NameRequiredDescription
errorYes
resultYes
outcomeYes
request_idYes
contract_versionYes

TDQS

D1.5/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden, but it discloses nothing about read-only behavior, cost or rate limits, authentication or session requirements, whether results are cached, or how the modes affect behavior. The phrase 'evidence authority' is too vague to compensate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence with no wasted words, but it is under-specified rather than concise. It fails to front-load any useful operational context for a seven-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a complex search tool with seven parameters, an enum mode, no annotations, and no parameter descriptions. Although an output schema exists and need not be explained, the description does not provide nearly enough context for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across seven parameters, and the description explains none of them. The meanings of 'mode', 'caller', 'free_only', 'session_id', 'max_results', and 'include_attribution' are left entirely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'Search' is present, but the resource is described only as 'the HTTP-v2 evidence authority', which is internal jargon that does not tell an agent what is being searched. It does not distinguish this tool from the sibling 'search_web' or explain what the 'v2' authority means in practice.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool instead of 'search_web' or any other sibling. No conditions, exclusions, or alternatives are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 16 tool updatesv1.6.5
    • Removedargus_paths
    • Changedbuild_research_pack5 fields changed
      • addedInput schema / $defs
        Added value: +{
        +  "ResearchRequirement": {
        +    "additionalProperties": false,
        +    "description": "One mandatory, publicly rendered claim class and research query.",
        +    "properties": {
        +      "claim_class": {
        +        "enum": [
        +          "capabilities",
        +          "pricing_eligibility",
        +          "privacy_data_handling",
        +          "protected_execution",
        +          "provenance_governance"
        +        ],
        +        "title": "Claim Class",
        +        "type": "string"
        +      },
        +      "query": {
        +        "maxLength": 500,
        +        "minLength": 1,
        +        "title": "Query",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "claim_class",
        +      "query"
        +    ],
        +    "title": "ResearchRequirement",
        +    "type": "object"
        +  },
        +  "ResearchTarget": {
        +    "additionalProperties": false,
        +    "description": "One named target with disjoint public source prefixes.",
        +    "properties": {
        +      "name": {
        +        "maxLength": 80,
        +        "minLength": 1,
        +        "title": "Name",
        +        "type": "string"
        +      },
        +      "requirements": {
        +        "items": {
        +          "$ref": "#/$defs/ResearchRequirement"
        +        },
        +        "maxItems": 3,
        +        "minItems": 1,
        +        "title": "Requirements",
        +        "type": "array"
        +      },
        +      "source_prefixes": {
        +        "items": {
        +          "format": "uri",
        +          "minLength": 1,
        +          "type": "string"
        +        },
        +        "maxItems": 4,
        +        "minItems": 1,
        +        "title": "Source Prefixes",
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "source_prefixes",
        +      "requirements"
        +    ],
        +    "title": "ResearchTarget",
        +    "type": "object"
        +  }
        +}
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
      • addedInput schema / properties / free_only
        Added value: +{
        +  "default": false,
        +  "title": "Free Only",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / research_targets
        Added value: +{
        +  "default": null,
        +  "items": {
        +    "$ref": "#/$defs/ResearchTarget"
        +  },
        +  "title": "Research Targets",
        +  "type": "array"
        +}
      • addedInput schema / properties / response_format
        Added value: +{
        +  "default": "markdown",
        +  "title": "Response Format",
        +  "type": "string"
        +}
    • Changedcapture_site1 field changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
    • Removedcookie_health
    • Changedexpand_links1 field changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
    • Addedexpand_links_v2
    • Changedextract_content4 fields changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
      • addedInput schema / properties / content_type
        Added value: +{
        +  "default": "article",
        +  "title": "Content Type",
        +  "type": "string"
        +}
      • addedInput schema / properties / free_only
        Added value: +{
        +  "default": false,
        +  "title": "Free Only",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "default",
        +  "title": "Mode",
        +  "type": "string"
        +}
    • Addedextract_content_v2
    • Addedget_workflow_status
    • Addedread_workflow_artifact
    • Changedrecover_dead_article1 field changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
    • Changedrecover_url1 field changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
    • Addedrecover_url_v2
    • Addedsearch_web_v2
    • Removedtest_provider
    • Removedvalyu_answer
  2. 1 tool updatev1.6.2
    • Changedsearch_web3 fields changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "default": "mcp",
        +  "title": "Caller",
        +  "type": "string"
        +}
      • addedInput schema / properties / free_only
        Added value: +{
        +  "default": false,
        +  "title": "Free Only",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / include_attribution
        Added value: +{
        +  "default": false,
        +  "title": "Include Attribution",
        +  "type": "boolean"
        +}
  3. 7 tool updatesv1.5.0
    • Addedargus_paths
    • Addedbuild_research_pack
    • Addedcapture_site
    • Addedcookie_health
    • Changedextract_content1 field changed
      • addedInput schema / properties / domain
        Added value: +{
        +  "default": null,
        +  "title": "Domain",
        +  "type": "string"
        +}
    • Addedrecover_dead_article
    • Addedvalyu_answer
  4. 7 tool updatesv0.1.0
    • First observedexpand_links
    • First observedextract_content
    • First observedrecover_url
    • First observedsearch_budgets
    • First observedsearch_health
    • First observedsearch_web
    • First observedtest_provider

TDQS

C2/5.0

Scored across 15 tools

Disambiguation2/5

Four tool pairs are near-duplicates distinguished only by references to a 'HTTP' vs 'HTTP-v2 evidence' authority (search_web/search_web_v2, recover_url/recover_url_v2, expand_links/expand_links_v2, extract_content/extract_content_v2), giving an agent no clear basis for choosing. Additionally, recover_url and recover_dead_article overlap, and capture_site/build_research_pack have no descriptions at all, leaving their boundaries undefined.

Naming Consistency4/5

Names consistently follow snake_case verb_noun (search_web, expand_links, get_workflow_status, read_workflow_artifact). The only deviation is the _v2 suffix convention, which is at least applied uniformly but signals duplication rather than a distinct capability.

Tool Count3/5

15 tools sits at the upper edge of a comfortable set, and roughly half of it is duplicated v1/v2 surface, so the effective unique capability count is closer to 11. The count feels inflated for the actual scope of a web-research pipeline.

Completeness3/5

The surface covers a plausible research lifecycle — search, recover, expand, extract, capture, build a research pack, and poll/read workflow output plus health and budgets. However there are no cancellation/cleanup operations for workflows or packs, and two tools (capture_site, build_research_pack) lack descriptions, making their role and coverage impossible to verify.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Web search for AI agents across 6 engines (Serper, Brave, Exa, Tavily, Firecrawl, Perplexity) through one search tool. Routes each query to the cheapest engine that clears a quality bar and caches repeats. Hosted, streamable-HTTP, BYOK supported.
    1
    1
    MIT
  • A
    license
    A
    quality
    F
    maintenance
    Free multi-source web search server for AI agents, with confidence scoring and token optimization.
    3
    118 npm
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Free, open-source web search gateway and MCP server for LLMs, AI agents, and RAG. It provides no-key web, code, academic, and community search with deduplication, ranking fusion, and citation-ready results.
    3
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to perform reliable web searches through multiple vendors with automatic failover, keyless-first access, TTL caching, and concurrent request coalescing.
    1
    MIT