Skip to main content
Glama

Python 3.9+ PyPI Latest Release License: MIT Downloads Glama quality Documentation MCP Toplist

PyScrappy is an AI-native web scraping toolkit that turns websites into structured, LLM-ready data. Use it as a Python library or expose it as an MCP server for AI agents.

📖 Documentation: pyscrappy.vercel.app

Key features

  • Generic scraper — give it any URL, get back structured text, links, images, tables, and metadata

  • LLM-ready output.to_markdown() turns any result into clean Markdown; also .to_json() and .to_dataframe()

  • MCP server — expose the scrapers as tools for AI agents (Claude, Cursor, local LLMs, …)

  • JS rendering — optional Playwright backend for JavaScript-heavy sites

  • Custom selectors — pass CSS selectors to extract exactly what you need

  • Chainable Selector — navigate HTML directly with CSS/XPath, find_all, find_by_text, and find_similar (Scrapy/BeautifulSoup-style)

  • Adaptive (self-healing) selectors — remember an element and relocate it by similarity when a site changes its markup, so scrapers don't silently break

  • Concurrent scrapingscrape_many / scrape_all run scrapes in parallel

  • Sitemap crawling — enumerate and scrape a whole site from its sitemap.xml (index + gzip aware)

  • Proxy & scraping-API support — route through a proxy or ScraperAPI/ScrapeOps for blocked sites

  • TLS-fingerprint impersonationimpersonate="chrome" gets past anti-bot filters that block plain clients (optional curl_cffi backend)

  • Command-line extractpyscrappy extract <url> out.md scrapes a URL straight to a file, no code

  • Retry & rate-limiting — built-in exponential backoff and per-domain rate limiting

  • Type-safe — full type hints, py.typed marker

  • 20+ built-in scrapers — Wikipedia, IMDB, stocks, news, GitHub, Amazon/IKEA, YouTube, and more

Related MCP server: mcp-firecrawl

Installation

pip install pyscrappy

Optional extras:

# Browser support (for JS-rendered pages)
pip install 'pyscrappy[browser]'
playwright install chromium

# DataFrame support
pip install 'pyscrappy[dataframe]'

# MCP server (use PyScrappy's scrapers as AI-agent tools)
pip install 'pyscrappy[mcp]'

# Stealth (TLS-fingerprint impersonation to bypass anti-bot filters)
pip install 'pyscrappy[stealth]'

# Parquet / Excel export (ScrapeResult.to_parquet() / .to_excel())
pip install 'pyscrappy[parquet]'
pip install 'pyscrappy[excel]'

# Everything
pip install 'pyscrappy[all]'

For AI agents

PyScrappy ships an MCP server that exposes its scrapers as tools, so an agent (Claude, Cursor, an OpenAI agent, a local LLM) can pull structured web data from any URL and hand it straight to the model:

AI agent  ──MCP tool call──▶  PyScrappy  ──fetch + extract──▶  Any website
   ▲                                                                │
   └──────────────  clean Markdown / JSON  ◀───────────────────────┘
pip install 'pyscrappy[mcp]'
claude mcp add pyscrappy pyscrappy-mcp

Then just ask: "use pyscrappy to summarize the latest headlines from bbc.com." See MCP server for the full setup and tool list.

Local models (Ollama), no MCP host needed

Ollama can't talk MCP on its own, so normally you'd run a host (Goose, Cline, …) in between. PyScrappy skips that with a built-in agent that talks to Ollama directly and lets a local model call the scrapers as tools:

pip install 'pyscrappy[mcp]'                 # needs Python 3.10+
pyscrappy chat --model qwen2.5 "what's the current AAPL quote?"

It exposes the same 22 tools as the MCP server. The only requirement is a model that supports tool calling (Llama 3.1, Qwen 2.5, Mistral, …); how well it picks the right tool is up to the model. Point it at a remote Ollama with --host, and pass -v to see each tool call.

MCP server (use PyScrappy from an AI agent)

PyScrappy ships an optional Model Context Protocol server, so an AI agent (e.g. Claude) can call PyScrappy's scrapers as tools and get structured web data back.

pip install 'pyscrappy[mcp]'

The MCP extra installs the standalone fastmcp package and requires Python 3.10 or newer. On Python 3.9 the core scraping library still works, but the MCP server is unavailable.

This installs the pyscrappy-mcp command. It uses stdio by default for local MCP clients; Streamable HTTP and legacy SSE are available for remote deployments:

pyscrappy-mcp          # stdio (default)
pyscrappy-mcp --http   # Streamable HTTP
pyscrappy-mcp --sse    # legacy SSE

You can also run the stdio server with python -m pyscrappy.mcp.

Register with Claude Code

claude mcp add pyscrappy pyscrappy-mcp

Register with Claude Desktop

Add to your claude_desktop_config.json and restart the app:

{
  "mcpServers": {
    "pyscrappy": {
      "command": "pyscrappy-mcp"
    }
  }
}

Tip: Claude Desktop does not inherit your shell PATH. If pyscrappy-mcp is not found, use the absolute path to the command (e.g. the one printed by which pyscrappy-mcp).

Available tools

The server exposes 20+ tools. The most common ones are scrape_url (any URL → text, links, images, tables, metadata), scrape_wikipedia, scrape_stock, scrape_news, and search_github — plus many more covering image/YouTube/LinkedIn/Hacker News/book search, weather, crypto, currency, dictionary, Amazon/Newegg/IKEA/SoundCloud, IMDB, and Zomato/Uber Eats.

To see the full, live list, ask the agent to call the list_available_scrapers tool, or from a shell:

python -c "from pyscrappy import list_scrapers; print(', '.join(sorted(list_scrapers())))"

The lookup_movie tool needs a free OMDb API key. Pass it to the server through your MCP client config, e.g. for Claude Desktop:

{
  "mcpServers": {
    "pyscrappy": {
      "command": "pyscrappy-mcp",
      "env": { "OMDB_API_KEY": "your-key" }
    }
  }
}

Once registered, just ask the agent naturally, e.g. "use pyscrappy to get the latest headlines from bbc.co.uk and the AAPL stock quote."

Built-in scrapers

PyScrappy ships 24 built-in scrapers, and every one that works without a proxy is also exposed as an MCP tool.

A few of them:

  • GenericScraper — scrape any URL with auto-extraction (text, links, images, tables, metadata)

  • Data / researchWikipediaScraper, StockScraper (Yahoo Finance), NewsScraper (RSS/Atom), GitHubScraper, HackerNewsScraper, plus weather, crypto, currency, dictionary, image, LinkedIn-jobs, and book search

  • E-commerceAmazonScraper, NeweggScraper, IKEAScraper

  • Social / media / foodYouTubeScraper, SoundCloud, Zomato, Uber Eats (Instagram / Twitter / Spotify also ship, but are blocked and need a proxy)

…and many more. To see the full, live list:

python -c "from pyscrappy import list_scrapers; print(', '.join(sorted(list_scrapers())))"

IMDBScraper (lookup_movie) is the one exception that needs a key — a free OMDb OMDB_API_KEY (see the MCP config above for how to pass it).

Plugins

PyScrappy is extensible: you can add your own scrapers, and third parties can ship them as standalone pyscrappy-<name> packages. A registered scraper works everywhere a built-in does, including the MCP server and the pyscrappy chat agent, with no change to PyScrappy core.

In your own code — register with the decorator:

from pyscrappy import BaseScraper, register_scraper, get_scraper
from pyscrappy.core.models import ScrapeResult, ScrapeMetadata

@register_scraper("reddit")
class RedditScraper(BaseScraper):
    def scrape(self, subreddit: str, **kwargs) -> ScrapeResult:
        data = self.fetch_and_parse(f"https://old.reddit.com/r/{subreddit}/.json")
        # ... build a list of dicts ...
        return ScrapeResult(data=[...], metadata=ScrapeMetadata(scraper="reddit"))

get_scraper("reddit")().scrape(subreddit="python")

As a distributable package — advertise an entry point in your pyproject.toml, and PyScrappy discovers it once your package is installed:

[project.entry-points."pyscrappy.scrapers"]
reddit = "pyscrappy_reddit:RedditScraper"

After pip install pyscrappy-reddit, the scraper shows up in list_scrapers(), and an AI agent can call it via the scrape_with MCP tool — no core change required.

First-class MCP tools (optional). Add an mcp_tools mapping and your scraper becomes a dedicated, typed MCP tool instead of only being reachable through the generic scrape_with — its schema is derived from the method signature, so agents get proper named arguments:

@register_scraper("reddit")
class RedditScraper(BaseScraper):
    mcp_tools = {"search_reddit": "scrape"}   # tool name -> method

    def scrape(self, subreddit: str, sort: str = "hot") -> ScrapeResult:
        ...

See the plugin template for a complete, copyable starting point, and the plugin guide for the full walkthrough.

Quick start

Scrape any URL → clean, LLM-ready Markdown

from pyscrappy import scrape

result = scrape("https://en.wikipedia.org/wiki/Web_scraping")

print(result.to_markdown())   # feed straight to an LLM
# ...or result.to_json() / result.to_dataframe()

# Write to a file — format inferred from the extension:
result.save("out.json")       # .json .csv .md .ndjson .yaml .parquet .xlsx
# (.parquet needs pyscrappy[parquet]; .xlsx needs pyscrappy[excel])

Prefer raw fields? Every result is a ScrapeResult with .data (a list of dicts):

print(result.data[0]["metadata"]["title"])
print(result.data[0]["text"]["word_count"])

Custom CSS selectors

from pyscrappy import GenericScraper

with GenericScraper() as gs:
    result = gs.scrape(
        url="https://news.ycombinator.com",
        selectors={"title": ".titleline a", "score": ".score"},
    )
    for item in result.data:
        print(item["title"], item.get("score", ""))

Navigate HTML with Selector

When you want to traverse markup directly (Scrapy/BeautifulSoup-style) rather than get back structured dicts, use Selector:

from pyscrappy import Selector

page = Selector(html)                             # or navigate any HTML string
page.css(".title::text").getall()                 # CSS with ::text / ::attr(name)
page.xpath("//a/@href").getall()                   # XPath (elements, text(), @attr)
page.find_all("h2", class_="title")                # BeautifulSoup-style search
page.find_by_text("Add to cart", tag="button")     # search by text content

first = page.css(".product")[0]
first.css(".price::text").get()                    # chainable
first.find_similar()                               # sibling elements shaped like this one

css() / xpath() return a SelectorList with .get() / .getall() / .text(). find_similar() locates elements with the same tag and overlapping classes, handy for pulling every card/row once you've found one.

Adaptive (self-healing) selectors

A hard-coded CSS selector silently breaks the day a site changes its markup. Adaptive selectors survive that: save a fingerprint of the element the first time, and if the selector later matches nothing, relocate it by structural and textual similarity instead of returning empty.

from pyscrappy import Selector

# First run: match normally and remember this element under an id.
page = Selector(html_v1, url="https://shop.example.com")
price = page.css(".price", auto_save=True, adaptive_id="price").get()

# Later, after a redesign renamed ".price" — heal instead of breaking.
# `expect` is an optional contract: the relocated element must satisfy it,
# so a good structural score can't smuggle in the wrong field.
page = Selector(html_v2, url="https://shop.example.com")
result = page.css(
    ".price",
    adaptive=True,
    adaptive_id="price",
    expect=lambda s: s.text().startswith("$"),
)
print(result.get(), "→ confidence:", result.adaptive_confidence)

How the relocation decides — and where it's stronger than a naive similarity match:

  • Weighted signals, not a flat average. A stable id / data-* hook counts far more than a sibling-tag list, so weak signals can't outvote strong ones.

  • Anchor-relative. It remembers the nearest stable ancestor (an id'd / data-* container) and depth, so it survives layout reshuffles that move absolute positions.

  • Volatility-aware text. Prices, dates, and counts are down-weighted, so healing stays reliable on exactly the fields that change most between scrapes.

  • Confidence-scored. SelectorList.adaptive_confidence (0-100) tells you how sure the relocation was; threshold= sets the minimum to accept.

  • Contract-enforced (opt-in). Pass expect=<callable> to require the healed element to satisfy an invariant (e.g. "text looks like a price"). A heal that clears the threshold but fails the contract is rejected, so structural similarity alone never redefines what a field means.

A heal is a change to what a selector resolves to, so every accepted heal is recorded. The store keeps an append-only audit log (adaptive.heal.ndjson beside the fingerprint store) with the confidence, the runner-up gap, and the before/after fingerprint, readable via store.heal_log() — so drift stays observable instead of being silently absorbed. For an at-a-glance summary, store.heal_report() aggregates the log into one row per selector (heal count, latest/lowest/average confidence, when it last healed), sorted most-healed first — so the selectors that have drifted the most, and the shakiest relocations (lowest confidence), surface at the top for a human to review.

Fingerprints persist in a small JSON store (~/.pyscrappy/adaptive.json by default, or $PYSCRAPPY_HOME), namespaced by site so the same adaptive_id on two sites never collides. Adaptive is entirely opt-in: without adaptive=True, a broken selector still just returns empty, exactly as before.

Site-specific scrapers

Every built-in scraper follows the same pattern — instantiate, scrape(...), read result.data (or .to_dataframe() / .to_markdown()):

from pyscrappy import WikipediaScraper

with WikipediaScraper() as ws:
    result = ws.scrape(query="Python (programming language)", mode="summary")
    print(result.data[0]["text"])

Each scraper has its own arguments (Wikipedia, stocks, IMDB, news, YouTube, Amazon/Newegg/IKEA, Uber Eats, and more — see the full list). For per-scraper arguments and examples, see the documentation.

From the command line

Scrape a URL straight to a file without writing any code — the output format is inferred from the file extension:

pyscrappy extract https://example.com out.md      # clean Markdown
pyscrappy extract https://example.com out.json    # structured JSON
pyscrappy extract https://example.com out.txt     # extracted page text
pyscrappy extract https://example.com out.html    # raw fetched HTML

# Narrow to elements matching a CSS selector, or render JS first:
pyscrappy extract https://example.com items.txt --css-selector ".product"
pyscrappy extract https://example.com page.md --render-js

Configuration

from pyscrappy import ScraperConfig, GenericScraper

config = ScraperConfig(
    timeout=20.0,            # request timeout in seconds
    max_retries=3,           # retry failed requests
    retry_jitter=True,       # spread exponential retries to avoid lockstep traffic
    rate_limit=2.0,          # seconds between requests per domain
    proxy="http://...",      # proxy URL, or a list to rotate through
    scraper_api=None,        # route via a scraping-API service (see below)
    headless=True,           # browser runs headless
    render_js="auto",        # auto-detect if JS rendering is needed
    cache_ttl=0,             # response cache TTL in seconds (0 = disabled)
    cache_dir=None,          # also persist the cache to disk (survives restarts)
    cache_dir_max_size=512,  # max live entries kept on disk before oldest are pruned
    impersonate=None,        # e.g. "chrome" to spoof a browser's TLS fingerprint (see below)
)

with GenericScraper(config) as gs:
    result = gs.scrape(url="https://example.com")

Proxies and blocked sites

Some sites (e.g. eBay, Instagram, Twitter/X, Spotify) block direct automated requests. PyScrappy supports two ways to get through them.

A proxy (or a rotating list) — applies to both the HTTP and browser backends:

from pyscrappy import ScraperConfig, AmazonScraper

# Single proxy
config = ScraperConfig(proxy="http://user:pass@host:port")

# Rotating list (one picked per request)
config = ScraperConfig(proxy=["http://p1:8080", "http://p2:8080"])

A scraping-API service (ScraperAPI, ScrapeOps, ScrapingBee) — routes requests through the service, which handles proxies and anti-bot challenges for you:

config = ScraperConfig(scraper_api={
    "provider": "scraperapi",   # or "scrapeops", "scrapingbee"
    "api_key": "YOUR_KEY",
    "render_js": True,           # optional
})

# Now any scraper works through the service, unchanged:
with AmazonScraper(config) as scraper:
    result = scraper.scrape(query="laptop")

This is the reliable way to use the scrapers marked "needs proxy" above.

TLS-fingerprint impersonation — many anti-bot systems block a plain HTTP client by its TLS/JA3 fingerprint before serving any content. Set impersonate to mimic a real browser's fingerprint and get past that class of block without a headless browser:

from pyscrappy import ScraperConfig, GenericScraper

# needs the optional extra:  pip install 'pyscrappy[stealth]'
config = ScraperConfig(impersonate="chrome")   # or "chrome124", "safari", "firefox"

with GenericScraper(config) as gs:
    result = gs.scrape("https://example.com")

Impersonation works on both the sync and async paths (async uses curl_cffi's AsyncSession), so you can combine stealth with high-throughput async scraping. All the usual retry, rate-limiting, caching, and robots handling still apply.

import asyncio
from pyscrappy import scrape_async, ScraperConfig

async def main():
    cfg = ScraperConfig(impersonate="chrome")
    return await scrape_async("https://example.com", config=cfg)

asyncio.run(main())

Concurrent scraping

Scraping is I/O-bound, so running several scrapes at once parallelizes the network waits. scrape_many runs one scraper over many inputs; scrape_all runs a mix of scrapers together. Both preserve input order.

from pyscrappy import scrape_many, scrape_all, AmazonScraper, WikipediaScraper, NewsScraper

# One scraper, many queries, concurrently:
results = scrape_many(AmazonScraper, [{"query": "laptop"}, {"query": "phone"}])

# Different scrapers at once:
results = scrape_all([
    lambda: WikipediaScraper().scrape(query="Python"),
    lambda: NewsScraper().scrape(feed_url="https://rss.nytimes.com/services/xml/rss/nyt/World.xml"),
])

Sitemap crawling

Pagination follows next-page links; a sitemap enumerates a whole site's URLs directly. GenericScraper can read /sitemap.xml (discovered from robots.txt Sitemap: directives, or the conventional path), follow a <sitemapindex> into its child sitemaps, and scrape every listed page.

from pyscrappy import GenericScraper

with GenericScraper() as gs:
    # Just enumerate the URLs:
    urls = gs.sitemap_urls("https://example.com")            # -> list[str]

    # Or fetch + extract each, concurrently, into one result:
    result = gs.scrape_sitemap("https://example.com", max_urls=100)
    print(len(result.data), "pages scraped")

Handles <urlset> leaves and <sitemapindex> files (recursing one level), gzip-compressed sitemaps (.xml.gz), and de-duplicates URLs. Fetches go through the usual rate-limiting, caching, proxy, and stealth machinery, and the fan-out reuses scrape_all. max_urls caps the crawl (a sitemap can list tens of thousands of URLs, so it's required for scrape_sitemap).

Response caching

Set cache_ttl to a positive number of seconds to cache successful GET responses. Repeated requests for the same URL (and query params) within the TTL are served from cache, skipping both the network and the rate limiter. Caching is disabled by default (cache_ttl=0).

from pyscrappy import WikipediaScraper
from pyscrappy import ScraperConfig

config = ScraperConfig(cache_ttl=300)   # cache for 5 minutes

with WikipediaScraper(config) as ws:
    ws.scrape(query="Python")   # fetched over the network
    ws.scrape(query="Python")   # served from cache

The cache is in memory and shared across scraper instances in the same process (so it also speeds up repeated calls through the MCP server), and is cleared when the process exits. Call HttpClient.clear_cache() to empty it manually.

It is LRU-bounded: at most cache_max_size live entries (default 512), with the least-recently-used entry evicted once the cap is reached. So a long-running process (e.g. the MCP server) that fetches many distinct URLs stays bounded rather than growing until restart. Raise or lower the cap as needed:

config = ScraperConfig(cache_ttl=300, cache_max_size=2000)

Persistent (on-disk) cache. Set cache_dir to also persist responses to disk, so cache hits survive across process restarts and separate runs — useful for re-running a scrape or a CLI job without re-fetching. The in-memory cache still fronts it for speed; a disk hit is promoted back into memory.

config = ScraperConfig(cache_ttl=3600, cache_dir="~/.cache/pyscrappy")

The on-disk cache is bounded too: each write prunes expired entries and trims the oldest past cache_dir_max_size (default 512), so a cache_dir doesn't grow one file per distinct URL forever.

clear_cache() empties the in-memory cache; the on-disk cache persists by design — delete its cache_dir to clear it.

Observability hooks

For long crawls, pass lightweight callbacks to watch requests live (progress bars, metrics) without turning on logging:

config = ScraperConfig(
    on_request=lambda url: print("GET", url),               # before a network fetch
    on_retry=lambda url, attempt, delay, err: print("retry", attempt, url),
    on_cache_hit=lambda url: print("cached", url),          # served from cache
)
  • on_request(url) fires once before a URL is fetched (not on a cache hit).

  • on_retry(url, attempt, delay, error) fires before each backoff sleep.

  • on_cache_hit(url) fires when a request is served from cache.

All three are best-effort: a callback that raises is logged at debug and never breaks the scrape. They fire on both the sync and async paths.

Dependencies

Required: httpx, beautifulsoup4, lxml

Optional: playwright (JS rendering), pandas (DataFrames), fastmcp (MCP server, Python 3.10+)

License

MIT

Contributing

All contributions welcome. See Issues.

This package is for educational and research purposes.

Available Tools

24 tools
convert_currencyA

Fetch live exchange rates and convert an amount from one currency to others.

Returns a dict with the base currency, the amount converted, and a mapping of each target currency code to its converted value and unit exchange rate (e.g. {"base": "USD", "amount": 100, "results": {"EUR": {"rate": 0.92, "value": 92.0}}}).

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoTarget currency codes as a comma-separated string; omit or leave empty to return rates for all available currencies. Example: "EUR,GBP". Default: None (all rates).
baseNoBase currency code as a 3-letter ISO 4217 string. Example: "USD". Default: "USD".USD
amountNoAmount of the base currency to convert, as a number (int or float). Example: 100. Default: 1.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description carries the burden of disclosing behavior. It sufficiently explains the return format with a concrete example and notes that rates are live. It does not mention error behavior (e.g., invalid currency codes), but for a simple read-only conversion tool, the provided context is adequate.

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

Conciseness5/5

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

The description is concise and well-structured: the first sentence states the purpose, and the second provides a concrete return format example. Every sentence adds value, with no wasted words.

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

Completeness5/5

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

The tool is simple, the input schema fully documents all parameters, and an output schema exists. The description also illustrates the return structure, making the tool contextually complete for an agent to use effectively.

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

Parameters3/5

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

Schema description coverage is 100%, with each parameter already including a description, defaults, and examples. The tool description adds no additional parameter semantics beyond what the schema provides, so the baseline of 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool fetches live exchange rates and converts amounts, which is a specific verb+resource combination. It distinguishes the tool from sibling tools, as no other sibling handles currency conversion.

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 implied by the description: it is for fetching live exchange rates and converting amounts. However, there is no explicit guidance about when to prefer this over alternatives or when not to use it, though no obvious alternative exists among siblings.

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

define_wordA

Look up an English word and return its dictionary entry: definitions, part(s) of speech, and example sentences.

Fetches from an online dictionary data source, so a network connection is required. Read-only with no side effects. If the word is not found (misspelled or not in the dictionary), returns an empty result or a not-found response rather than raising.

Returns a structured entry for the word, typically containing the word itself, one or more part-of-speech groupings, and for each a list of definitions with optional example sentences.

ParametersJSON Schema
NameRequiredDescriptionDefault
wordYesThe English word to define, as a string. Example: "serendipity". No default (required). Single words only; not phrases or non-English terms.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states network requirements, read-only semantics with no side effects, and not-found behavior (returns empty/not-found rather than raising). Additionally, it outlines the return structure, providing comprehensive transparency for a simple tool.

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

Conciseness5/5

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

The description is concise and well-structured: the first sentence states the core purpose, followed by a second paragraph adding essential behavioral context (network, read-only, error handling) and a third describing the return format. Every sentence earns its place without unnecessary verbosity.

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

Completeness5/5

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

Given the tool's low complexity (one parameter) and the presence of an output schema, the description is complete. It covers the tool's network dependency, safety profile, error behavior, and output structure. This is sufficient for an agent to select and invoke the tool correctly without ambiguity.

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

Parameters3/5

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

The input schema has 100% coverage for the single parameter 'word', with a detailed description including examples and constraints. The main description does not add additional parameter meaning, but the baseline is 3 due to high schema coverage, and the description does not contradict or fail to compensate.

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

Purpose5/5

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

The description clearly states the tool's function: 'Look up an English word and return its dictionary entry.' It specifies the resource (English words) and the output (definitions, parts of speech, example sentences), which distinguishes it from sibling tools that focus on scraping or searching other domains.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool (when needing a dictionary definition) and implicitly differentiates from siblings by focusing on word lookups. It does not explicitly list alternatives or exclusions, but the parameter description adds guidance (single words only, not phrases or non-English terms), which helps usage decisions.

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

get_cryptoA

Fetch live cryptocurrency market data and return a list of coin records, each with fields: id, symbol, name, current price (in vs_currency), market cap, and 24h price change (percent).

Fetches from a live crypto market data API over the network, so results reflect current prices and require internet access; no local state is read or written. When query is omitted, returns the top coins ranked by market cap. If no coins match the query, returns an empty list rather than raising.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryNoString of comma-separated coin ids. Example: "bitcoin, ethereum". Default None (returns top coins by market cap).
max_resultsNoInteger maximum number of coins to return. Example: 10. Default 20.
vs_currencyNoString fiat or quote currency code for prices, lowercase. Example: "usd". Allowed: any currency supported by the data source, e.g. "usd", "eur", "gbp", "jpy". Default "usd".usd

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description takes on full responsibility for behavioral disclosure. It states network dependency, confirms no local read/write, and specifies non-error behavior for empty results. These are meaningful, beyond-schema insights that help an agent anticipate side effects and edge cases.

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

Conciseness5/5

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

The description is compact and well-structured. The first sentence states the core purpose and return format; the second sentence adds essential behavioral and edge-case information. Every sentence earns its place, with no redundancy or fluff.

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

Completeness5/5

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

Despite having no annotations, the combination of a complete schema, an output schema (indicated by context), and a description that covers purpose, network behavior, result format, and edge cases makes this fully adequate for an agent to select and invoke the tool correctly. No significant gaps remain.

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

Parameters3/5

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

Schema description coverage is 100%: all three parameters (query, max_results, vs_currency) have detailed, self-explanatory descriptions including defaults and examples. The tool description repeats some of this (e.g., query omitted returns top coins) but adds minimal new parameter-level semantics. Baseline 3 is appropriate.

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

Purpose5/5

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

The description begins with a specific verb and resource: 'Fetch live cryptocurrency market data' and then enumerates the exact fields returned (id, symbol, name, current price, market cap, 24h change). This clearly differentiates it from sibling tools like scrape_stock or convert_currency, which serve different financial data needs.

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

Usage Guidelines4/5

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

It provides clear usage context: results are live, need internet access, and no local state is affected. It also explains the behavior when query is omitted (top coins) and when no matches are found (empty list, not an error). It does not explicitly name alternatives or exclusions, but the use case is unambiguous enough for an agent to decide when to invoke it.

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

get_ubereats_menuA

Fetch an Uber Eats restaurant's live menu from its store URL and return the menu items with their names, descriptions, and prices.

Scrapes the restaurant page over the network at call time, so results reflect current listings and require internet access. Prices and availability depend on the store's configured location and hours. Returns a structured list of menu items (typically grouped by section/category); if the URL is invalid, the restaurant is unavailable, or the menu is empty, an empty result (no items) is returned rather than an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
store_urlYesURL string of the Uber Eats store page, taken from a search_ubereats result's "url" field. Example: "https://www.ubereats.com/store/some-restaurant/abc123". No default (required).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden and succeeds: it reveals that the tool scrapes live network data at call time, requires internet access, depends on store location/hours, and returns an empty result rather than an error for invalid/unavailable/empty menus. These are crucial behavioral traits that go beyond the schema.

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

Conciseness5/5

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

The description is three dense sentences, each earning its place: the first states purpose and output, the second explains live scraping behavior, and the third covers edge cases. It is front-loaded with the primary action and contains no filler.

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

Completeness5/5

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

Given the tool's simple single-parameter interface, the presence of an output schema, and no annotations, the description covers all necessary context: what it returns, how it behaves at runtime, and failure modes. It is complete enough for an agent to select and invoke the tool correctly.

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

Parameters3/5

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

The parameter store_url is fully documented in the schema, including its source (search_ubereats result) and an example. Since schema description coverage is 100%, the baseline is 3, and the main description adds no additional parameter-level semantics beyond what the schema already provides.

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

Purpose5/5

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

The description opens with a specific verb ('Fetch') and resource ('an Uber Eats restaurant's live menu from its store URL'), immediately distinguishing it from generic scrapers like scrape_url and from search_ubereats. It also specifies the key output fields (names, descriptions, prices), leaving no ambiguity about what the tool does.

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 description implies the tool is for store URLs (especially from search_ubereats, as noted in the schema) but does not explicitly state when to use it over sibling tools like scrape_with or scrape_url. It gives context about needing a valid store URL and network access but stops short of clear when-to-use/when-not-to-use guidance.

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

get_weatherA

Fetch the current weather conditions for a named place and return a dict with keys: temperature (number, degrees Celsius), humidity (number, percent), wind_speed (number, wind speed), condition (str, e.g. "Clear", "Rain"), and location (str, the resolved place name).

Makes a live network call to an external weather provider on each invocation, so results reflect real-time conditions and require internet access. If the location cannot be resolved or the provider returns no match, the tool returns an empty result (or an error field) rather than raising.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYesString naming the place to look up; a city name, optionally with a region or country to disambiguate. Example: "Tokyo, Japan". No default; this parameter is required.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description fully carries the behavioral burden. It discloses that each call makes a live network request, returns a specific structured dict, and handles unresolved locations by returning an empty result or error field instead of raising. This exceeds the transparency expected for a simple tool.

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

Conciseness5/5

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

The description is two sentences: the first front-loads the purpose and return format, the second adds behavioral notes. Every sentence earns its place, with no filler or redundancy. The structure is clean and scannable.

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

Completeness5/5

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

For a one-parameter tool with an output schema, the description is remarkably complete. It specifies the exact return keys with types, explains side effects (network call, internet), and documents error behavior. The presence of an output schema does not reduce the need for description, and this description goes beyond minimum requirements.

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

Parameters3/5

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

Schema description coverage is 100% for the only parameter 'location', which includes a detailed description and example. The description's reference to a 'named place' adds no new semantic value beyond what the schema already provides. Based on the high coverage rule, a baseline of 3 is appropriate.

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

Purpose5/5

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

The description uses a specific verb ('Fetch') and clear resource ('current weather conditions for a named place'), and explicitly defines the return dict with key types, making it distinguishable from sibling tools like scrape_url or get_crypto. It is not a tautology and provides substantive detail.

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

Usage Guidelines4/5

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

The description implies when to use the tool (when real-time weather is needed) and provides important context (live network call, requires internet, returns empty on unresolved location). While it does not explicitly name alternatives or exclusion criteria, the clear context and absence of a weather-like sibling make the usage unambiguous.

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

list_available_scrapersA

List every scraper registered with this server and return their names for use with scrape_with.

Reads the server's in-process scraper registry, which includes built-in scrapers plus any installed third-party pyscrappy-* plugin packages that self-register on import. No network or browser access is performed and no state is changed. If no scrapers are registered, returns an empty list.

Returns: list[str]: Scraper name identifiers (for example ["amazon", "flipkart", "youtube"]), each usable as the scraper argument to scrape_with. Empty list when none are registered.

Usage Guidelines: Call this first to discover valid scraper names, then pass a returned name to scrape_with; use it to confirm a plugin registered correctly after installing a pyscrappy-* package.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description fully discloses behavior: it reads the in-process registry, covers built-ins and self-registering third-party plugins, performs no network/browser access, changes no state, and returns an empty list when none are registered. This is exemplary transparency for a read-only discovery tool.

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

Conciseness5/5

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

The description is well-structured and front-loaded with the core purpose, followed by implementation detail, safety guarantees, return format, and usage guidance. Every sentence contributes meaningful information without redundancy.

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

Completeness5/5

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

Given zero parameters and no annotations, the description covers all necessary context: what the tool does, how it works, side effects (none), return value, examples, and workflow integration with scrape_with. It is fully self-sufficient for an agent to select and invoke the tool correctly.

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 there is nothing for the description to explain beyond the schema. The description instead adds value by clarifying return semantics (list of strings, example values, empty-list behavior), which is appropriate and supports a baseline-above score.

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

Purpose5/5

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

The description opens with 'List every scraper registered with this server and return their names for use with scrape_with,' which uses a specific verb and resource, clearly distinguishing this discovery tool from scraping/sibling tools. The scope ('registered with this server') and the complementary reference to scrape_with make the purpose unambiguous.

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

Usage Guidelines5/5

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

The 'Usage Guidelines' section explicitly instructs calling this tool first, passing returned names to scrape_with, and using it to confirm plugin registration. This provides clear when-to-use guidance and a direct workflow with its primary sibling tool.

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

lookup_movieA

Look up movie and TV data from IMDB via the OMDb API and return a JSON-serializable dict; a title search returns {"results": [...]} with each item holding title, year, imdb_id, and type, while an IMDB-id lookup returns a single record with full details (plot, ratings, cast, runtime, genre).

Reads over the network from the OMDb HTTP API; no browser is needed and nothing is written or cached. Requires a free OMDb API key in the OMDB_API_KEY environment variable (get one at https://www.omdbapi.com/apikey.aspx); if it is missing the tool returns {"error": ...} explaining how to set it. When the query matches nothing, it returns an empty results list rather than raising.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesString. A title to search for (e.g. "inception"), or an IMDB id starting with "tt" for a direct single-record lookup (e.g. "tt1375666"). Required, no default.
max_pagesNoInteger. Number of search-result pages to fetch at 10 results per page; only applies to title searches and is ignored for IMDB-id lookups (e.g. 3). Default 1.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description discloses network reads, no browser/write/cache, OMDb API key requirement, error response when key is missing, and empty-result behavior on no match.

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

Conciseness5/5

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

Two dense sentences front-load the purpose and then add essential operational detail; no filler.

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

Completeness5/5

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

The description covers return shapes for both lookup modes, authentication, network behavior, and edge cases, making it complete for the tool's complexity and existing output schema.

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?

Schema coverage is 100% with clear parameter descriptions; the description further explains that 'query' can be a title or tt-id and that 'max_pages' only applies to title searches, adding semantics beyond the schema.

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

Purpose5/5

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

The description opens with a specific verb ('look up') and resource (movie and TV data from IMDB via OMDb API), and explains both title-search and IMDB-id lookup modes, distinguishing it from scraping siblings.

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

Usage Guidelines4/5

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

It clearly defines the context (movie/TV lookups) and explains the two query types, but does not explicitly name alternative tools or state when not to use it.

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

scrape_newsA

Fetch news articles from an RSS/Atom feed, a news site (feed auto-discovered), or a single article, and return a list of article dicts (typically: title, url, published date, author, summary, and full text where available).

Provide exactly one of feed_url, site_url, or article_url. Fetches live content over the network at call time; results are not cached. article_url returns one article; feed_url and site_url return up to max_articles. Returns an empty list if the feed/site yields no articles or if a feed cannot be discovered or parsed.

ParametersJSON Schema
NameRequiredDescriptionDefault
feed_urlNoString, direct URL to an RSS/Atom feed. Example: "https://example.com/rss.xml". Default: None.
site_urlNoString, news site homepage URL whose feed is auto-discovered. Example: "https://example.com". Default: None.
article_urlNoString, single article URL to extract full text from. Example: "https://example.com/2026/news-story". Default: None.
max_articlesNoInteger, max articles to return for feed_url or site_url; ignored for article_url. Example: 20. Default: 50.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the transparency burden. It discloses that content is fetched live over the network, results are not cached, and an empty list is returned on no results or feed parse failure. This covers key behavioral traits, though it does not mention potential timeouts, rate limits, or detailed error handling.

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

Conciseness5/5

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

The description is concise, with no redundant information. It front-loads the core function in the first sentence, then adds critical usage constraints and behavioral notes in a compact second paragraph. Every sentence earns its place.

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?

Given the tool's moderate complexity and the presence of an output schema, the description adequately covers return shape, parameter relationships, and edge cases like empty results and feed discovery failure. It is complete enough for an agent to select and invoke the tool, though it omits minor aspects like network error handling or auth requirements.

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

Parameters5/5

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

Although the schema already describes each parameter with examples, the description adds crucial semantics: the mutual exclusivity of feed_url, site_url, and article_url, and the differing return counts (one vs. up to max_articles). This goes beyond the schema and significantly aids correct invocation.

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

Purpose5/5

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

The description clearly states the tool's function: fetching news articles from RSS/Atom feeds, news sites with auto-discovery, or single articles, and returning article dicts. It uses specific verbs and resources, and the mention of news articles distinguishes it from generic scrapers like scrape_url.

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

Usage Guidelines4/5

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

The description provides clear usage context: 'Provide exactly one of feed_url, site_url, or article_url' and explains that article_url returns one article while feed_url/site_url return up to max_articles. However, it does not explicitly mention when to prefer this tool over sibling tools or any exclusions, so it stops short of full alternative guidance.

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

scrape_stockA

Fetch stock market data from Yahoo Finance and return it as a dict.

The returned shape depends on mode:

  • "quote": {"symbol", "currency", "exchange", "price", "previous_close", "volume", "day_high", "day_low", "fifty_two_week_high", "fifty_two_week_low"}.

  • "history": {"symbol", "period", "rows": [{"date", "open", "high", "low", "close", "volume"}, ...]}.

  • "profile": {"symbol", "name", "currency", "exchange", "market", "timezone", "instrument_type"}.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoString selecting what to fetch; one of "quote", "history", "profile". Example: "quote". Default: "quote".quote
periodNoString history window, used only when mode="history" and ignored otherwise; one of "1d", "5d", "1mo", "3mo", "6mo", "1y", "2y", "5y", "10y", "ytd", "max". Example: "1y". Default: "1mo".1mo
symbolYesTicker symbol as a string. Example: "AAPL". No default (required).
intervalNoCandle size for history bars, used only when mode="history"; one of "1d", "1wk", "1mo". Example: "1wk". Default: "1d".1d

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It thoroughly discloses return shapes for each mode, which is the primary behavioral aspect. It doesn't mention rate limits or error handling, but the read-only nature is implied by 'fetch' and the output specification is detailed.

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

Conciseness5/5

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

The description is well-structured and front-loaded with the main action. It efficiently uses a list format to convey return keys, and every sentence serves a purpose without redundancy.

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

Completeness5/5

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

Given the output schema exists and the description explicitly defines the return dict for all three modes, the description is comprehensive. Parameter schema is also thorough, so no critical gaps remain.

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

Parameters3/5

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

The input schema already has 100% coverage with detailed descriptions for each parameter. The description adds value by explaining how mode affects the output shape, but this is a logical inference rather than new parameter semantics. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the verb 'fetch' and the resource 'stock market data from Yahoo Finance', and specifies the return type as a dict. It also distinguishes this tool from siblings like scrape_url and get_crypto by focusing on stocks from a specific source.

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

Usage Guidelines4/5

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

The description provides clear context: it is for fetching stock data from Yahoo Finance. It doesn't explicitly mention alternatives or when not to use it, but the domain is specific enough for an agent to infer appropriate use.

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

scrape_urlA

Scrape any HTTP(S) URL and return a ScrapeToolResult whose data holds one object per page containing extracted text (with word_count), links, images, tables, and page metadata.

Fetches the page over the network and parses the HTML; no data is stored or mutated. By default it makes a plain static HTTP request, so pages built client-side with JavaScript come back nearly empty. When that is detected, the returned errors list gets a hint to retry with render_js=true; set render_js=true to render with a headless browser instead (requires the pyscrappy[browser] extra). On empty or failed results, data is [], count is 0, and errors describes the problem rather than raising.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesString, the page URL to scrape including scheme, e.g. "https://example.com/products". Required, no default.
max_pagesNoInteger, follow "next"-style pagination up to this many pages, e.g. 3. Default 1 (scrape only the given URL).
render_jsNoBoolean, render JavaScript with a headless browser backend, e.g. True. Default False; allowed values True or False, and True needs the pyscrappy[browser] extra installed.
selectorsNoOptional dict mapping output field name to CSS selector to extract specific values into each data item, e.g. {"title": "h1", "price": ".amount"}. Default None (returns only the standard text/links/images/tables/metadata).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and delivers: it discloses network fetching, that no data is stored or mutated, the plain-HTTP limitation with JS pages, the render_js=true retry path, and that failures return empty data/errors instead of raising. This is exemplary.

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

Conciseness5/5

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

The description is well-structured: the first sentence front-loads the purpose and result shape, followed by useful behavioral details. Every sentence earns its place, and there is no redundancy.

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

Completeness5/5

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

Given an output schema exists and annotations are absent, the description covers result structure, failure handling, JS-rendering behavior, and installation note. It is complete enough for an agent to select and invoke the tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds some context about render_js and error behavior, but it does not substantially enrich parameter meaning beyond what the schema provides; baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states it scrapes any HTTP(S) URL and returns a ScrapeToolResult with extracted text, links, images, tables, and metadata. The 'any URL' framing distinguishes it from specialized sibling scrapers like scrape_wikipedia or scrape_stock.

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

Usage Guidelines4/5

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

The description gives clear context: it works for any HTTP(S) URL and provides a specific retry instruction when JavaScript-rendered pages return empty. It does not explicitly name alternatives or exclusions, but the general-purpose wording makes the use case obvious.

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

scrape_wikipediaA

Fetch a Wikipedia article by title or search term and return its text content.

Makes a live network request to Wikipedia, resolving the query to the best-matching article and extracting its body. The shape of the returned text depends on mode: "full" returns the entire article as one string; "paragraphs" returns the article split into a list of paragraph strings; "headers" returns a list of the article's section heading strings (its table of contents). If no article matches the query, an empty result is returned (empty string for "full", empty list for "paragraphs" or "headers").

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoString, one of "full", "paragraphs", or "headers". Selects the return shape as described above. Example: "paragraphs". No default (required).full
queryYesString. Article title or search term. Example: "Model Context Protocol". No default (required).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.4/5.0
Behavior4/5

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

Since annotations are absent, the description carries the full burden. It discloses that a live network request is made, explains how query resolution works, and details the return shape for each mode plus the empty-result behavior. It does not mention rate limits or error handling, but the key behaviors are clearly covered.

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 concise but not overly terse. The first sentence immediately states the purpose, and the second paragraph adds behavioral detail in a structured way. Every sentence contributes value, though the content could be slightly tightened.

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?

The description covers the core behavior, return shapes, and empty results, which is appropriate given that an output schema exists. It does not describe error handling or network failure scenarios, but for a scraper with clear modes, this is sufficient.

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

Parameters5/5

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

The description adds substantial meaning beyond the schema: it defines what 'full', 'paragraphs', and 'headers' return, and explains the empty-result behavior per mode. The schema itself only lists the mode as 'one of...' without these details, so the description elevates semantic clarity.

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

Purpose5/5

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

The description opens with a specific verb (Fetch), a specific resource (Wikipedia article), and the action's outcome (return its text content). It clearly distinguishes from sibling tools like scrape_url or scrape_news by being exclusively about Wikipedia.

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

Usage Guidelines4/5

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

The description clearly implies this tool is for Wikipedia content retrieval, which differentiates it from generic URL scrapers and other domain-specific scrapers. However, it does not explicitly list when not to use it or mention alternative tools, so it misses the highest bar.

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

scrape_withA

Run any registered scraper (built-in or plugin) by name and return that scraper's raw scrape() output.

This is the generic dispatch entry point for scrapers that lack a dedicated tool, notably third-party plugins. It looks up the scraper in the registry, calls its scrape() method with the given args, and returns whatever that scraper returns (typically a dict or list of records; exact shape is scraper-specific). Side effects and requirements (network requests, browser/headless rendering, auth) depend entirely on the target scraper. If name is not a registered scraper, it raises an error rather than returning empty; if the scraper runs but finds nothing, it returns that scraper's empty result (e.g. an empty list).

ParametersJSON Schema
NameRequiredDescriptionDefault
argsNoDict of keyword arguments forwarded to the named scraper's scrape() method; required keys depend on that scraper. Example: {"query": "Alan Turing", "lang": "en"}. No default (required).
nameYesString, the scraper's registered name from list_available_scrapers. Example: "wikipedia". No default (required).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries full burden and does so thoroughly: it reveals that args are forwarded to scrape(), return shape is scraper-specific, side effects (network, auth, browser rendering) vary by target, unknown names throw an error, and empty results return the scraper's empty structure. This comprehensively sets expectations.

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

Conciseness5/5

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

The description is front-loaded with the core action and uses four additional sentences that each earn their place: dispatch logic, return shape, side-effect caveat, and error/empty behavior. No filler or repetition.

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

Completeness5/5

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

For a generic dispatcher with 2 params and an output schema, the description is complete. It explains the dispatch mechanism, return variability, side effects, failures, and empty results—without needing to describe return values in detail since an output schema exists.

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

Parameters3/5

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

Schema coverage is 100%, so baseline is 3. The description adds no significant meaning beyond the schema: 'name' is the registry name, 'args' are forwarded to scrape(). The schema already states both, so the description provides minimal added value.

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

Purpose5/5

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

The description opens with a specific verb+resource: 'Run any registered scraper... by name and return that scraper's raw scrape() output.' It clearly distinguishes this generic dispatcher from the sibling-specific scrapers and list_available_scrapers by framing it as the entry point for scrapers lacking a dedicated tool.

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

Usage Guidelines5/5

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

Explicitly states when to use: 'This is the generic dispatch entry point for scrapers that lack a dedicated tool, notably third-party plugins.' This implies the when-not-to-use (use dedicated tools when available) and describes the alternative conceptual category, giving clear context.

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

scrape_zomatoA

Search Zomato for restaurants in a city and return a list of restaurant records.

Scrapes Zomato's public restaurant listings over the network for the given city, optionally filtered by a cuisine or name term. Each result is a dict with fields such as name, cuisine, rating, price_for_two, address, and url; the exact keys depend on what Zomato exposes for each listing. Returns a list of these dicts ordered as Zomato ranks them, capped at max_results. Returns an empty list if the city is unknown or no restaurants match the query. Requires outbound network access; results reflect live Zomato data at call time and may vary between calls.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityYesString city name to search within. Example: "Bangalore". Required, no default.
queryNoOptional string cuisine or restaurant search term to filter results. Example: "biryani". Defaults to None (returns all restaurants for the city).
max_resultsNoInteger maximum number of restaurants to return. Example: 20. Defaults to 50.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It explicitly states network access ('Requires outbound network access'), live data variability ('results reflect live Zomato data at call time and may vary between calls'), and edge-case behavior ('Returns an empty list if the city is unknown'). It does not mention rate limits or potential blocking, but the disclosed behavior is substantial and helpful for an agent.

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

Conciseness5/5

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

The description is concise, front-loaded with the core purpose, and every sentence adds value. It covers purpose, method, filters, output format, ordering, caps, edge cases, and network dependency without unnecessary fluff. It is well-structured and easy to parse.

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

Completeness5/5

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

The description provides a complete picture for a scraped-list tool: it states what it does, how it works (network scraping), what output to expect (dict list with example fields, ordering), how to control result count (max_results), and failure modes (unknown city, no matches). Given 3 parameters and no output schema shown, this is sufficiently thorough for an agent to invoke correctly.

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?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful context beyond the schema: query is described as 'a cuisine or name term' and max_results is described as capping the list. It also clarifies the output structure (list of dicts with example fields), which indirectly informs parameter meaning. This exceeds baseline.

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

Purpose5/5

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

The description clearly states the tool's function: 'Search Zomato for restaurants in a city and return a list of restaurant records.' It uses a specific verb (search/scrape) with a specific resource (Zomato restaurants) and highlights distinct features like city-based search and optional filters. This distinguishes it from sibling tools such as scrape_url or search_ubereats.

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 description implies usage context ('Search Zomato for restaurants in a city') but does not explicitly mention when to use this tool versus alternatives or provide exclusion criteria. It lacks statements like 'for restaurant listings from Zomato, use this' or 'not for other food delivery services.' No alternatives are referenced, so guidance is only implied.

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

search_amazonA

Scrape Amazon search results for a query and return a list of matching products, each with its title, price, rating, and image URL.

This performs a live network scrape of Amazon's public search results pages (no login, no API key). It has no side effects beyond outgoing HTTP requests. Results reflect Amazon's current listings and may vary by region, availability, and anti-bot throttling. Returns a list of dicts, one per product, each shaped as {"title": str, "price": str, "rating": str, "image": str}; fields that Amazon omits for a listing come back as empty strings or None. Returns an empty list when the query yields no products or when scraping is blocked.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesProduct search phrase, as a string. Example: "wireless headphones". No default (required).
max_pagesNoNumber of result pages to scrape, as an integer; higher values return more products but take longer and raise the chance of throttling. Example: 3. Default: 1.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description fully covers behavioral traits: it discloses no side effects ('no side effects beyond outgoing HTTP requests'), no auth requirements, network dependence, anti-bot throttling, and return behavior including empty list on block/no results. It also specifies the exact return shape and how missing fields are represented (empty strings or None). This is exceptionally transparent.

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

Conciseness5/5

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

The description is four sentences, each earning its place: purpose, operational context, return format, and failure behavior. It is front-loaded with the essential purpose, then adds necessary behavioral caveats, and ends with the output contract. No wasted words or repetition of schema content.

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

Completeness5/5

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

The tool is moderately complex (live network scrape with variable results), and the description covers everything an agent needs to decide and execute: live scrape, no auth, no side effects, variability, exact return schema, empty list behavior, and blocking. The presence of the output shape in the description compensates for the lack of an explicit output schema in context. Completeness is high.

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

Parameters3/5

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

Schema description coverage is 100%, and the schema already clearly documents both parameters (query and max_pages) with examples and defaults. The description itself does not add parameter-level meaning, but the schema does the heavy lifting. Per the rubric, a baseline of 3 is appropriate when schema coverage is high and no further param details are needed.

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

Purpose5/5

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

The description opens with a specific verb and resource: 'Scrape Amazon search results for a query and return a list of matching products.' This clearly distinguishes the tool from its siblings (e.g., search_images, search_youtube) by naming Amazon as the target and defining the output. The scope is explicit and unambiguous.

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

Usage Guidelines4/5

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

The description provides clear usage context: it is a live network scrape of Amazon's public search pages with no login/API key, and mentions that results vary by region/availability and may be affected by throttling. It implies when to use the tool (Amazon product searches) but does not explicitly name alternatives or state when not to use it. This qualifies as clear context without exclusions, matching a 4.

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

search_booksA

Search books by title, author, or free text via the Open Library search API and return a list of matching book records.

Queries Open Library over the network (no browser or authentication required). Returns a list of dicts, each typically containing: title (str), author_names (list of str), first_publish_year (int or None), edition_count (int), and the Open Library work key (str, e.g. "/works/OL45804W"). Fields missing upstream are omitted or None. Returns an empty list when the query matches nothing. Read-only: no local files or state are modified.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesTitle, author, or free-text search string. Type: string. Example: "the hobbit tolkien". Required, no default.
max_resultsNoMaximum number of books to return. Type: integer. Example: 10. Default: 20. Allowed: any positive integer.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries full burden. It discloses read-only behavior, no file/state modification, network access, return format, and empty-list behavior. This is excellent transparency.

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

Conciseness5/5

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

Concise and front-loaded. The first sentence captures purpose, subsequent sentences add valuable behavioral details without redundancy. Every sentence earns its place.

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

Completeness5/5

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

Covers purpose, network/auth requirements, return shape, empty results, and side effects. Output schema exists, but the description enriches context further. Complete for a search tool.

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

Parameters3/5

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

Schema description coverage is 100%, fully explaining query and max_results. The description adds no new param semantics beyond aligning with the search scope. Baseline 3 is appropriate.

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

Purpose5/5

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

The description clearly states the tool searches books by title, author, or free text via the Open Library API, with a specific verb and resource. This distinguishes it from sibling search/scrape tools.

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

Usage Guidelines4/5

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

It provides clear context: network-based, no authentication required. It does not explicitly exclude alternatives, but the book-specific scope implies when to use. No explicit when-not or alternative tool references.

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

search_githubA

Search GitHub for public repositories and return a list of repository records.

Queries the GitHub search API over the network and returns a list of dicts, each with: name (str), owner (str), stars (int), description (str), and language (str). Results are ordered per the sort argument. Returns an empty list when no repository matches the query. Requires network access; may be subject to GitHub API rate limits.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoString ordering for results; one of "best-match", "stars", "forks", or "updated". Example: "stars". Default "best-match".best-match
queryYesString search expression using GitHub search syntax, including qualifiers like "language:" or "stars:". Example: "web scraping language:python". No default (required).
max_resultsNoInteger maximum number of repositories to return. Example: 10. Default 20.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It discloses the return format (list of dicts with specific keys), ordering behavior (per sort argument), empty-list behavior when no matches, network access requirement, and rate limits. This is thorough and directly useful to an agent.

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

Conciseness5/5

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

The description is four sentences, front-loaded with the primary purpose, and every sentence adds value: scope, network behavior, return structure, empty-list handling, and rate-limit warning. No redundant or filler text.

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

Completeness5/5

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

The description is complete for this tool's complexity. It explains inputs, output schema, network dependency, rate limits, and edge-case behavior (empty list). Combined with a well-described input schema, an agent has enough information to invoke it correctly without ambiguity.

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

Parameters3/5

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

The input schema already has 100% coverage with detailed descriptions and examples for all three parameters, so the baseline is 3. The description adds little beyond mentioning ordering by sort, which the schema already covers. It does not need to compensate since the schema is sufficient.

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

Purpose5/5

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

The description clearly states a specific verb ('Search') and resource ('GitHub for public repositories'), and the return type is described as a list of repository records. This distinguishes it from sibling search tools like search_images or search_hackernews, which target different domains.

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

Usage Guidelines4/5

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

The description provides clear context: it queries the GitHub search API over the network, requires network access, and may hit GitHub API rate limits. It does not explicitly name alternatives or exclusions, but the scope ('GitHub for public repositories') makes the intended use unambiguous.

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

search_hackernewsA

Search Hacker News stories and return a list of matching story dicts, each with title, url, points, author (username), and num_comments (comment count).

Queries the public Hacker News search index (Algolia HN API) over the network; makes no local changes. Returns an empty list when nothing matches or the query is empty.

ParametersJSON Schema
NameRequiredDescriptionDefault
byNoResult ordering; type: string; one of "relevance" or "date" ("date" sorts most recent first); example: "date"; default: "relevance".relevance
tagsNoAlgolia HN tag filter; type: string; common values "story", "comment", "show_hn", "ask_hn", "poll", "job"; example: "show_hn"; default: "story".story
queryYesSearch terms to match against story titles and text; type: string; example: "rust async runtime"; no default (required).
max_resultsNoMaximum number of stories to return; type: integer; example: 10; default: 20.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.2/5.0
Behavior4/5

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

Explicitly states 'makes no local changes' and discloses the network dependency on the Algolia HN API, plus the empty-list behavior. With no annotations present, the description carries the burden well, though it omits rate-limit or error details.

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

Conciseness5/5

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

Two sentences, front-loaded with the main action and output shape, and no redundant phrasing. Every sentence contributes meaningful information.

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 simple search tool with a rich schema and explicit output shape, the description covers the essentials: network usage, non-destructive behavior, and empty-list handling. It could mention rate limits or errors, but that is not critical given the simplicity.

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

Parameters3/5

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

Schema description coverage is 100%, with every parameter having type, default, and example. The description adds no parameter-specific details beyond the schema, so the baseline of 3 is appropriate.

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

Purpose5/5

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

Description opens with a specific verb 'Search' and resource 'Hacker News stories', and clearly specifies the output as a list of dicts with named fields (title, url, points, author, num_comments). This clearly distinguishes it from sibling search tools like search_github or search_images.

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

Usage Guidelines4/5

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

States it queries the public Hacker News index over the network and returns an empty list for no matches/empty query, providing clear usage context. It does not explicitly mention alternatives or exclusions, but the tool's niche is unambiguous given the sibling list.

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

search_ikeaA

Search IKEA's online catalog for furniture and home products, returning a list of product dicts with fields name, type, price, and rating.

Scrapes the IKEA store website for the given country at call time, so results require network access and reflect that store's live listings. Prices, availability, and currency are per-country and per-language. Returns an empty list if the query matches no products.

ParametersJSON Schema
NameRequiredDescriptionDefault
langNoString language code for that store's listings; must be a language the chosen country's store supports, e.g. "en" for "us"/"gb" or "de" for "de". Example "de". Default "en".en
queryYesString search term for the product name or type, e.g. "desk" or "bookshelf". Required, no default.
countryNoString two-letter IKEA store country code that sets pricing and availability; allowed values are IKEA market codes such as "us", "gb", "de", "fr", "se". Example "gb". Default "us".us
max_resultsNoInteger cap on the number of products returned; e.g. 10. Default 24.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It discloses that results require network access, reflect live listings, prices/currency vary by country/language, and returns an empty list on no matches. This adds meaningful behavioral context beyond the schema, though it doesn't cover potential errors or rate limits.

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

Conciseness5/5

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

The description is three sentences, front-loaded with the core purpose, followed by behavioral details and edge cases. Every sentence adds value with no fluff or redundancy.

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?

Given the tool's moderate complexity (4 params, scrape-based behavior, output schema exists), the description covers purpose, return format, network dependence, and empty-result behavior. It doesn't mention potential scraper brittleness or error cases, but the schema and output schema fill most gaps, making it largely complete.

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

Parameters3/5

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

The input schema has 100% coverage with detailed descriptions for each parameter. The description adds a bit of context (e.g., tying lang/country to live listings) but largely restates what the schema already conveys, so the baseline of 3 is appropriate.

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

Purpose5/5

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

The description states the tool 'Search IKEA's online catalog for furniture and home products' with a specific verb and resource, and mentions returning product dicts with fields. This clearly distinguishes it from sibling tools like search_amazon or search_newegg by focusing on IKEA.

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

Usage Guidelines4/5

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

The description provides clear context on usage: it scrapes IKEA's live website, requires network access, and is per-country/language. However, it does not explicitly mention alternatives or when not to use it, so it stops short of a 5.

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

search_imagesA

Search the web for images and return a list of result objects with image URLs and metadata.

Each result is a dict with keys: "url" (direct link to the image), "thumbnail" (small preview), "title" (caption or alt text), "source_page" (page the image was found on), "width", and "height" (pixels). Every engine returns this same key set; fields a given engine can't provide are empty ("" for text, null for width/height — e.g. the Google path fills only "url", "title", and "source_page"). Results are returned in the engine's relevance order.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSearch terms as a string, e.g. "golden gate bridge". Required, no default.
engineNoString naming the search engine, one of "bing" or "google", e.g. "google". Defaults to "bing".bing
max_imagesNoInteger cap on the number of results returned, e.g. 10. Defaults to 20.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure, and it delivers. It reveals the exact result structure, notes engine-specific field availability (e.g., Google path fills only a subset), and states that results are in engine relevance order. This goes beyond basic expectations, though it does not cover error handling or rate limits.

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

Conciseness5/5

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

The description is concise, front-loaded with the primary action, and every sentence adds value. It efficiently packs important behavioral details (result keys, engine variations, empty field conventions) without verbosity or repetition of schema content.

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

Completeness5/5

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

Given the tool's simplicity (3 params, one required), an existing output schema, and clear return-value documentation in the description, the contextual information is complete. It covers what the tool does, what results look like, how engines differ, and the ordering, leaving minimal room for ambiguity.

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

Parameters3/5

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

The input schema already provides detailed descriptions and defaults for all three parameters (query, engine, max_images), achieving 100% schema description coverage. The tool description adds no additional parameter-specific semantics, but the schema alone is sufficient, so the baseline score of 3 applies.

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

Purpose5/5

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

The description uses a specific verb ('Search') and resource ('images'), clearly distinguishing it from sibling tools like search_youtube or search_books. It explicitly states it returns a list of result objects with image URLs and metadata, making the tool's function unmistakable.

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

Usage Guidelines4/5

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

The description clearly implies when to use this tool (when you need images from the web) and the context is unmistakable given sibling search tools for other media types. It does not explicitly mention alternatives or exclusions, but the purpose is so concrete that no additional guidance is needed.

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

search_linkedin_jobsA

Search LinkedIn public job postings and return a list of matched jobs.

Scrapes LinkedIn's public job search results over the network (no login required) and returns a list of dicts, one per posting, typically with keys: title, company, location, url, and posted_date. Returns an empty list if no postings match or the query yields no results. Live web scraping, so results reflect LinkedIn at call time and may vary between runs.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesJob title or keywords as a string. Example: "machine learning engineer". No default (required).
locationNoLocation filter as a string; city, region, or country. Example: "London" or "United Kingdom". No default (required).
max_pagesNoNumber of result pages to scrape, as an integer. Each extra page adds jobs but more scraping time. Example: 2. Default: 1.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden and does well: it reveals that the tool scrapes over the network (not an API), requires no login, returns a list of dicts with typical keys, returns an empty list on no matches, and that results are live and may vary between runs. This is strong transparency. It doesn't mention rate limits or error handling, but the disclosed traits are sufficient for a 4.

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

Conciseness5/5

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

The description is compact and front-loaded. The first sentence states the purpose, and the second block adds essential behavioral details (no login, return format, empty-list behavior, live scraping variability). Every sentence earns its place with no fluff or repetition.

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

Completeness5/5

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

Given the tool's scraping nature and the presence of a rich output schema, the description is complete. It covers purpose, network method, auth requirements, output structure, empty-result behavior, and data freshness. This is sufficient for an agent to decide when and how to invoke the tool without needing additional information.

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

Parameters3/5

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

The schema description coverage is 100% — every parameter (query, location, max_pages) has a clear description with examples and defaults. The tool description adds no extra parameter semantics beyond what the schema already provides, so the baseline of 3 is appropriate. No additional value is contributed.

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

Purpose5/5

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

The description clearly states the tool's function: 'Search LinkedIn public job postings and return a list of matched jobs.' It specifies the resource (LinkedIn job postings), the verb (search), and the output (list of matched jobs). This distinguishes it from sibling search tools that target other sources like GitHub, Hacker News, or books.

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

Usage Guidelines4/5

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

The description provides context on when to use the tool: for scraping LinkedIn's public job search without login. It mentions network scraping and live results. However, it does not explicitly exclude alternatives or state "use this instead of X" — although sibling tools are all different sources, making the context fairly clear. The lack of explicit exclusions keeps it from a 5.

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

search_neweggA

Search Newegg for electronics and computer hardware, returning a list of product dicts each with title, price, product_url, image_url, rating, and item_number.

Live-scrapes Newegg search result pages over the network; requires outbound internet access and returns an empty list if no products match or the page structure cannot be parsed. Read-only, with no side effects beyond the outbound HTTP requests.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesProduct search terms, given as a string. Example: "graphics card". No default (required).
max_pagesNoNumber of result pages to scrape, given as an integer; higher values return more products but take longer. Example: 3. Default 1.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full responsibility and does an excellent job. It discloses live scraping, outbound network access, the return of an empty list on failure, and explicitly labels the operation as read-only with no side effects beyond HTTP requests. This goes well beyond a basic statement of purpose.

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

Conciseness5/5

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

The description is compact and front-loaded. The first sentence states purpose and output, the second adds essential behavioral caveats. Every sentence contributes meaningful information with no redundancy.

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

Completeness5/5

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

The tool has an output schema and full parameter schema coverage, so the description need not repeat field details. It adds critical context about network dependency, failure modes, and side effects, making the description complete enough for an agent to use effectively.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-specific details beyond what the schema already provides; the schema itself fully explains query and max_pages meaning and defaults.

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

Purpose5/5

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

The description clearly specifies the action ('Search Newegg'), the domain ('electronics and computer hardware'), and the output shape (list of product dicts with fields). It distinguishes from siblings like search_amazon and search_ikea by naming the specific retailer and product scope.

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

Usage Guidelines4/5

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

The description sets clear context for when to use the tool: searching Newegg. It mentions the requirement for outbound internet access and the fallback behavior (empty list on no match), which implies constraints. However, it does not explicitly contrast with alternative search tools or state when not to use it.

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

search_soundcloudA

Search SoundCloud for tracks and return a list of track dicts, each with keys: title (str), artist (str), plays (int), likes (int), and url (str, the track page URL).

Renders SoundCloud's JavaScript search results with a browser backend (Playwright/Selenium), so it requires the pyscrappy[browser] extra to be installed and launches a headless browser per call. This makes it slower and heavier than the HTTP-based search tools. Results reflect SoundCloud's live public search at call time; no login or API key is used. Returns an empty list if the query matches no tracks.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query string. Example: "lofi beats". No default (required).
max_resultsNoMaximum number of tracks to return, as an integer. Example: 10. Default 20.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description fully discloses key behaviors: browser backend, dependency, headless browser per call, performance trade-offs, no auth required, and empty-list behavior. This exceeds expected transparency.

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

Conciseness5/5

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

The description is concise and well-structured: first sentence states purpose and output, second sentence explains technical trade-offs. Every sentence earns its place with no redundancy or verbosity.

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

Completeness5/5

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

Given the tool's modest complexity (2 params, no annotations, output schema exists), the description comprehensively covers return format, error case (empty list), dependencies, and performance caveats. It is complete for an agent to select and invoke correctly.

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

Parameters3/5

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

Schema description coverage is 100% for both query and max_results, so the baseline is 3. The description does not add parameter-specific meaning beyond what the schema provides; it focuses on output and operational context.

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

Purpose5/5

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

The description states the specific action (search SoundCloud for tracks), the resource (SoundCloud), and the output format (list of track dicts with keys and types). This clearly distinguishes it from sibling search tools like search_youtube or search_images.

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

Usage Guidelines4/5

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

The description provides contextual guidance by noting it is slower and heavier than HTTP-based tools and requires the pyscrappy[browser] extra. This implies when to use it (when SoundCloud-specific data is needed) but does not name explicit alternatives or exclusions.

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

search_ubereatsA

Search Uber Eats for restaurants delivering in a given city, returning a ScrapeToolResult envelope whose data is a list of restaurant objects (typically name, eta, delivery fee, and store url).

Fetches live listings from Uber Eats over the network at call time; no API key is required. The data list is capped at max_results and each item's store url is the input for get_ubereats_menu. Alongside data, the envelope carries count, scraper, source_urls, and errors (non-fatal issues, each with a url and message). If the city is unrecognized or no restaurants are found, data is an empty list and count is 0.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityYesCity name to search, as a string. Example: "London". No default (required).
max_resultsNoMaximum number of restaurants to return, as an integer. Example: 10. Default 30.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries full burden and does so excellently. It discloses network fetching at call time, lack of API key, the data cap via max_results, the envelope structure, non-fatal errors, and empty-list behavior for unrecognized cities or no results. This goes beyond just stating the operation.

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

Conciseness5/5

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

The description is well-structured into two clear sentences/paragraphs. The first sentence delivers the core purpose, followed by essential operational details. Every sentence provides necessary information without redundancy, making it appropriately concise.

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

Completeness5/5

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

The description covers the return envelope, count/scraper/source_urls/errors fields, error handling, empty results, network implications, and the link to get_ubereats_menu. Given the output schema exists, it still explains the envelope structure adequately, leaving no major gaps for the agent to select and invoke the tool.

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?

Schema coverage is 100% with both parameters already described. The description adds extra meaning by explaining that max_results caps the data list and that city is required for the search. It reinforces the purpose of each parameter in the broader workflow, adding value beyond the schema.

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

Purpose5/5

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

The description clearly states the tool's verb and resource: 'Search Uber Eats for restaurants delivering in a given city'. It distinguishes itself by specifying the output envelope and the relationship to get_ubereats_menu, making it unique among siblings.

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

Usage Guidelines4/5

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

The description provides clear context that this is a live network search with no API key, and explicitly mentions the store URL is the input for get_ubereats_menu, indicating a complementary workflow. It lacks explicit 'when not to use' or alternative tool comparisons, but the usage context is clear.

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

search_youtubeA

Search YouTube for videos matching a query and return a list of matching videos with their metadata.

Performs a live YouTube search over the network, so results reflect current YouTube data and may vary between calls; it is read-only and has no side effects. Returns a list of video objects, each typically containing: title (str), channel (str), url/link (str) to the video, video_id (str), duration (str), view_count (int), and published/upload date (str). Returns an empty list when the query matches no videos.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesThe search text, as a string. Example: "model context protocol tutorial". No default (required).
max_resultsNoMaximum number of videos to return, as an integer. Example: 10. Default 20.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNo
countNo
errorsNo
scraperNo
source_urlsNo

TDQS

A4.3/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of disclosure. It explicitly states that the operation is read-only, has no side effects, performs a live network search, and results may vary between calls. It also describes the edge case of returning an empty list for no matches. This is transparent and goes beyond minimal expectations.

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

Conciseness5/5

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

The description is concise and well-structured: it opens with a clear purpose, then adds behavioral context, then describes the return format, and finally addresses an edge case. Every sentence contributes useful information without redundancy or unnecessary length.

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

Completeness5/5

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

Given the tool's moderate complexity, the presence of an output schema, and full parameter schema coverage, the description is remarkably complete. It explains purpose, network behavior, safety (read-only), return fields, and empty-list behavior. No critical information needed for correct invocation or interpretation is missing.

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

Parameters3/5

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

The input schema already provides 100% description coverage, including examples and defaults for both 'query' and 'max_results'. The description text does not add significant parameter-specific meaning beyond referencing the query. Since the schema handles parameter semantics well, a baseline score of 3 is appropriate, and the description does not need to compensate.

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

Purpose5/5

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

The description clearly states the verb 'Search' and the resource 'YouTube', and specifies the action: searching for videos matching a query and returning metadata. This distinguishes it from sibling tools like search_images or search_github, which target different resources and use different verbs.

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 description mentions that it performs a live YouTube search over the network, providing context that results are current and non-deterministic. However, it does not explicitly state when to use this tool versus alternatives, nor does it mention any exclusions or scenarios where another tool would be preferable. The usage context is implied but not fully articulated.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv1.4.6
    • Changedconvert_currency2 fields changed
      • changedInput schema / properties / base / description
        Previous value: -"Base currency code as a 3-letter ISO 4217 string. Example: \"USD\". No default (required)."New value: +"Base currency code as a 3-letter ISO 4217 string. Example: \"USD\". Default: \"USD\"."
      • changedInput schema / properties / to / description
        Previous value: -"Target currency codes as a comma-separated string; omit or leave empty to return rates for all available currencies. Example: \"EUR,GBP\". Default: \"\" (all rates)."New value: +"Target currency codes as a comma-separated string; omit or leave empty to return rates for all available currencies. Example: \"EUR,GBP\". Default: None (all rates)."
    • Changedscrape_stock2 fields changed
      • addedInput schema / properties / interval
        Added value: +{
        +  "default": "1d",
        +  "description": "Candle size for history bars, used only when mode=\"history\"; one of \"1d\", \"1wk\", \"1mo\". Example: \"1wk\". Default: \"1d\".",
        +  "type": "string"
        +}
      • changedInput schema / properties / mode / description
        Previous value: -"String selecting what to fetch; one of \"quote\", \"history\", \"profile\". Example: \"quote\". No default (required)."New value: +"String selecting what to fetch; one of \"quote\", \"history\", \"profile\". Example: \"quote\". Default: \"quote\"."
    • Changedsearch_hackernews1 field changed
      • addedInput schema / properties / tags
        Added value: +{
        +  "default": "story",
        +  "description": "Algolia HN tag filter; type: string; common values \"story\", \"comment\", \"show_hn\", \"ask_hn\", \"poll\", \"job\"; example: \"show_hn\"; default: \"story\".",
        +  "type": "string"
        +}
    • Changedsearch_images1 field changed
      • changedInput schema / properties / engine / description
        Previous value: -"String naming the search engine, one of \"bing\", \"google\", or \"duckduckgo\", e.g. \"google\". Defaults to \"bing\"."New value: +"String naming the search engine, one of \"bing\" or \"google\", e.g. \"google\". Defaults to \"bing\"."
  2. 23 tool updates
    • Changedconvert_currency3 fields changed
      • changedInput schema / properties / amount / description
        Previous value: -"Amount of base currency to convert (default 1)."New value: +"Amount of the base currency to convert, as a number (int or float). Example: 100. Default: 1."
      • changedInput schema / properties / base / description
        Previous value: -"Base currency code, e.g. \"USD\"."New value: +"Base currency code as a 3-letter ISO 4217 string. Example: \"USD\". No default (required)."
      • changedInput schema / properties / to / description
        Previous value: -"Comma-separated target codes (e.g. \"EUR,GBP\"). Omit for all rates."New value: +"Target currency codes as a comma-separated string; omit or leave empty to return rates for all available currencies. Example: \"EUR,GBP\". Default: \"\" (all rates)."
    • Changeddefine_word1 field changed
      • changedInput schema / properties / word / description
        Previous value: -"The word to define."New value: +"The English word to define, as a string. Example: \"serendipity\". No default (required). Single words only; not phrases or non-English terms."
    • Changedget_crypto3 fields changed
      • changedInput schema / properties / max_results / description
        Previous value: -"Max coins to return (default 20)."New value: +"Integer maximum number of coins to return. Example: 10. Default 20."
      • changedInput schema / properties / query / description
        Previous value: -"Comma-separated coins (e.g. \"bitcoin, ethereum\"). Omit for top coins."New value: +"String of comma-separated coin ids. Example: \"bitcoin, ethereum\". Default None (returns top coins by market cap)."
      • changedInput schema / properties / vs_currency / description
        Previous value: -"Fiat currency for prices, e.g. \"usd\", \"eur\" (default \"usd\")."New value: +"String fiat or quote currency code for prices, lowercase. Example: \"usd\". Allowed: any currency supported by the data source, e.g. \"usd\", \"eur\", \"gbp\", \"jpy\". Default \"usd\"."
    • Changedget_ubereats_menu1 field changed
      • changedInput schema / properties / store_url / description
        Previous value: -"A store URL from a search_ubereats result's \"url\" field."New value: +"URL string of the Uber Eats store page, taken from a search_ubereats result's \"url\" field. Example: \"https://www.ubereats.com/store/some-restaurant/abc123\". No default (required)."
    • Changedget_weather1 field changed
      • changedInput schema / properties / location / description
        Previous value: -"Place name, e.g. \"London\" or \"Tokyo, Japan\"."New value: +"String naming the place to look up; a city name, optionally with a region or country to disambiguate. Example: \"Tokyo, Japan\". No default; this parameter is required."
    • Changedlookup_movie2 fields changed
      • changedInput schema / properties / max_pages / description
        Previous value: -"Pages of search results to fetch, 10 per page (title search)."New value: +"Integer. Number of search-result pages to fetch at 10 results per page; only applies to title searches and is ignored for IMDB-id lookups (e.g. 3). Default 1."
      • changedInput schema / properties / query / description
        Previous value: -"A title to search for (e.g. \"inception\"), or an IMDB id\n(e.g. \"tt1375666\") for a direct lookup."New value: +"String. A title to search for (e.g. \"inception\"), or an IMDB id starting with \"tt\" for a direct single-record lookup (e.g. \"tt1375666\"). Required, no default."
    • Changedscrape_news4 fields changed
      • changedInput schema / properties / article_url / description
        Previous value: -"A single article URL to extract full text from."New value: +"String, single article URL to extract full text from. Example: \"https://example.com/2026/news-story\". Default: None."
      • changedInput schema / properties / feed_url / description
        Previous value: -"Direct URL to an RSS/Atom feed."New value: +"String, direct URL to an RSS/Atom feed. Example: \"https://example.com/rss.xml\". Default: None."
      • changedInput schema / properties / max_articles / description
        Previous value: -"Max articles to return from a feed (default 50)."New value: +"Integer, max articles to return for feed_url or site_url; ignored for article_url. Example: 20. Default: 50."
      • changedInput schema / properties / site_url / description
        Previous value: -"News site URL — its feed is auto-discovered."New value: +"String, news site homepage URL whose feed is auto-discovered. Example: \"https://example.com\". Default: None."
    • Changedscrape_stock3 fields changed
      • changedInput schema / properties / mode / description
        Previous value: -"\"quote\", \"history\", or \"profile\"."New value: +"String selecting what to fetch; one of \"quote\", \"history\", \"profile\". Example: \"quote\". No default (required)."
      • changedInput schema / properties / period / description
        Previous value: -"History window when mode=\"history\", e.g. \"1mo\", \"1y\"."New value: +"String history window, used only when mode=\"history\" and ignored otherwise; one of \"1d\", \"5d\", \"1mo\", \"3mo\", \"6mo\", \"1y\", \"2y\", \"5y\", \"10y\", \"ytd\", \"max\". Example: \"1y\". Default: \"1mo\"."
      • changedInput schema / properties / symbol / description
        Previous value: -"Ticker symbol, e.g. \"AAPL\", \"GOOGL\"."New value: +"Ticker symbol as a string. Example: \"AAPL\". No default (required)."
    • Changedscrape_url4 fields changed
      • changedInput schema / properties / max_pages / description
        Previous value: -"Follow pagination up to this many pages (default 1)."New value: +"Integer, follow \"next\"-style pagination up to this many pages, e.g. 3. Default 1 (scrape only the given URL)."
      • changedInput schema / properties / render_js / description
        Previous value: -"Render JavaScript with a browser backend (needs pyscrappy[browser])."New value: +"Boolean, render JavaScript with a headless browser backend, e.g. True. Default False; allowed values True or False, and True needs the pyscrappy[browser] extra installed."
      • changedInput schema / properties / selectors / description
        Previous value: -"Optional CSS selectors, e.g. {\"title\": \"h1\", \"price\": \".amount\"}."New value: +"Optional dict mapping output field name to CSS selector to extract specific values into each data item, e.g. {\"title\": \"h1\", \"price\": \".amount\"}. Default None (returns only the standard text/links/images/tables/metadata)."
      • changedInput schema / properties / url / description
        Previous value: -"The page to scrape."New value: +"String, the page URL to scrape including scheme, e.g. \"https://example.com/products\". Required, no default."
    • Changedscrape_wikipedia2 fields changed
      • changedInput schema / properties / mode / description
        Previous value: -"\"full\", \"paragraphs\", or \"headers\"."New value: +"String, one of \"full\", \"paragraphs\", or \"headers\". Selects the return shape as described above. Example: \"paragraphs\". No default (required)."
      • changedInput schema / properties / query / description
        Previous value: -"Article title or search term, e.g. \"Model Context Protocol\"."New value: +"String. Article title or search term. Example: \"Model Context Protocol\". No default (required)."
    • Changedscrape_with2 fields changed
      • changedInput schema / properties / args / description
        Previous value: -"Keyword arguments passed to that scraper's `scrape()` method."New value: +"Dict of keyword arguments forwarded to the named scraper's scrape() method; required keys depend on that scraper. Example: {\"query\": \"Alan Turing\", \"lang\": \"en\"}. No default (required)."
      • changedInput schema / properties / name / description
        Previous value: -"A scraper name from `list_available_scrapers`, e.g. \"wikipedia\"."New value: +"String, the scraper's registered name from list_available_scrapers. Example: \"wikipedia\". No default (required)."
    • Changedscrape_zomato3 fields changed
      • changedInput schema / properties / city / description
        Previous value: -"City name, e.g. \"Bangalore\"."New value: +"String city name to search within. Example: \"Bangalore\". Required, no default."
      • changedInput schema / properties / max_results / description
        Previous value: -"Maximum number of restaurants to return (default 50)."New value: +"Integer maximum number of restaurants to return. Example: 20. Defaults to 50."
      • changedInput schema / properties / query / description
        Previous value: -"Optional cuisine or restaurant search term."New value: +"Optional string cuisine or restaurant search term to filter results. Example: \"biryani\". Defaults to None (returns all restaurants for the city)."
    • Changedsearch_amazon2 fields changed
      • changedInput schema / properties / max_pages / description
        Previous value: -"Number of result pages to scrape (default 1)."New value: +"Number of result pages to scrape, as an integer; higher values return more products but take longer and raise the chance of throttling. Example: 3. Default: 1."
      • changedInput schema / properties / query / description
        Previous value: -"Product search query, e.g. \"wireless headphones\"."New value: +"Product search phrase, as a string. Example: \"wireless headphones\". No default (required)."
    • Changedsearch_books2 fields changed
      • changedInput schema / properties / max_results / description
        Previous value: -"Max books to return (default 20)."New value: +"Maximum number of books to return. Type: integer. Example: 10. Default: 20. Allowed: any positive integer."
      • changedInput schema / properties / query / description
        Previous value: -"Title, author, or free-text search."New value: +"Title, author, or free-text search string. Type: string. Example: \"the hobbit tolkien\". Required, no default."
    • Changedsearch_github3 fields changed
      • changedInput schema / properties / max_results / description
        Previous value: -"Max repositories to return (default 20)."New value: +"Integer maximum number of repositories to return. Example: 10. Default 20."
      • changedInput schema / properties / query / description
        Previous value: -"Search query, e.g. \"web scraping language:python\"."New value: +"String search expression using GitHub search syntax, including qualifiers like \"language:\" or \"stars:\". Example: \"web scraping language:python\". No default (required)."
      • changedInput schema / properties / sort / description
        Previous value: -"\"best-match\" (default), \"stars\", \"forks\", or \"updated\"."New value: +"String ordering for results; one of \"best-match\", \"stars\", \"forks\", or \"updated\". Example: \"stars\". Default \"best-match\"."
    • Changedsearch_hackernews3 fields changed
      • changedInput schema / properties / by / description
        Previous value: -"\"relevance\" (default) or \"date\" (most recent first)."New value: +"Result ordering; type: string; one of \"relevance\" or \"date\" (\"date\" sorts most recent first); example: \"date\"; default: \"relevance\"."
      • changedInput schema / properties / max_results / description
        Previous value: -"Max stories to return (default 20)."New value: +"Maximum number of stories to return; type: integer; example: 10; default: 20."
      • changedInput schema / properties / query / description
        Previous value: -"Search query."New value: +"Search terms to match against story titles and text; type: string; example: \"rust async runtime\"; no default (required)."
    • Changedsearch_ikea4 fields changed
      • changedInput schema / properties / country / description
        Previous value: -"IKEA store country code, e.g. \"us\", \"gb\", \"de\" (default \"us\")."New value: +"String two-letter IKEA store country code that sets pricing and availability; allowed values are IKEA market codes such as \"us\", \"gb\", \"de\", \"fr\", \"se\". Example \"gb\". Default \"us\"."
      • changedInput schema / properties / lang / description
        Previous value: -"Language code for that store, e.g. \"en\", \"de\" (default \"en\")."New value: +"String language code for that store's listings; must be a language the chosen country's store supports, e.g. \"en\" for \"us\"/\"gb\" or \"de\" for \"de\". Example \"de\". Default \"en\"."
      • changedInput schema / properties / max_results / description
        Previous value: -"Maximum number of products to return (default 24)."New value: +"Integer cap on the number of products returned; e.g. 10. Default 24."
      • changedInput schema / properties / query / description
        Previous value: -"Product search query, e.g. \"desk\" or \"bookshelf\"."New value: +"String search term for the product name or type, e.g. \"desk\" or \"bookshelf\". Required, no default."
    • Changedsearch_images3 fields changed
      • changedInput schema / properties / engine / description
        Previous value: -"Search engine to use (default \"bing\")."New value: +"String naming the search engine, one of \"bing\", \"google\", or \"duckduckgo\", e.g. \"google\". Defaults to \"bing\"."
      • changedInput schema / properties / max_images / description
        Previous value: -"Maximum number of image results (default 20)."New value: +"Integer cap on the number of results returned, e.g. 10. Defaults to 20."
      • changedInput schema / properties / query / description
        Previous value: -"Image search query, e.g. \"golden gate bridge\"."New value: +"Search terms as a string, e.g. \"golden gate bridge\". Required, no default."
    • Changedsearch_linkedin_jobs3 fields changed
      • changedInput schema / properties / location / description
        Previous value: -"Location filter, e.g. \"London\" or \"United Kingdom\"."New value: +"Location filter as a string; city, region, or country. Example: \"London\" or \"United Kingdom\". No default (required)."
      • changedInput schema / properties / max_pages / description
        Previous value: -"Pages of results to scrape (default 1)."New value: +"Number of result pages to scrape, as an integer. Each extra page adds jobs but more scraping time. Example: 2. Default: 1."
      • changedInput schema / properties / query / description
        Previous value: -"Job title or keywords, e.g. \"machine learning engineer\"."New value: +"Job title or keywords as a string. Example: \"machine learning engineer\". No default (required)."
    • Changedsearch_newegg2 fields changed
      • changedInput schema / properties / max_pages / description
        Previous value: -"Number of result pages to scrape (default 1)."New value: +"Number of result pages to scrape, given as an integer; higher values return more products but take longer. Example: 3. Default 1."
      • changedInput schema / properties / query / description
        Previous value: -"Product search query, e.g. \"graphics card\"."New value: +"Product search terms, given as a string. Example: \"graphics card\". No default (required)."
    • Changedsearch_soundcloud2 fields changed
      • changedInput schema / properties / max_results / description
        Previous value: -"Maximum number of tracks to return (default 20)."New value: +"Maximum number of tracks to return, as an integer. Example: 10. Default 20."
      • changedInput schema / properties / query / description
        Previous value: -"Search query, e.g. \"lofi beats\"."New value: +"Search query string. Example: \"lofi beats\". No default (required)."
    • Changedsearch_ubereats2 fields changed
      • changedInput schema / properties / city / description
        Previous value: -"City name, e.g. \"London\"."New value: +"City name to search, as a string. Example: \"London\". No default (required)."
      • changedInput schema / properties / max_results / description
        Previous value: -"Maximum restaurants to return (default 30)."New value: +"Maximum number of restaurants to return, as an integer. Example: 10. Default 30."
    • Changedsearch_youtube2 fields changed
      • changedInput schema / properties / max_results / description
        Previous value: -"Maximum number of videos to return (default 20)."New value: +"Maximum number of videos to return, as an integer. Example: 10. Default 20."
      • changedInput schema / properties / query / description
        Previous value: -"Search query, e.g. \"model context protocol tutorial\"."New value: +"The search text, as a string. Example: \"model context protocol tutorial\". No default (required)."
  3. 24 tool updatesv1.3.3
    • Changedconvert_currency20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / amount / description
        Added value: +"Amount of base currency to convert (default 1)."
      • removedInput schema / properties / amount / title
        Removed value: -"Amount"
      • addedInput schema / properties / base / description
        Added value: +"Base currency code, e.g. \"USD\"."
      • removedInput schema / properties / base / title
        Removed value: -"Base"
      • addedInput schema / properties / to / description
        Added value: +"Comma-separated target codes (e.g. \"EUR,GBP\"). Omit for all rates."
      • removedInput schema / properties / to / title
        Removed value: -"To"
      • removedInput schema / title
        Removed value: -"convert_currencyArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changeddefine_word16 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / word / description
        Added value: +"The word to define."
      • removedInput schema / properties / word / title
        Removed value: -"Word"
      • removedInput schema / title
        Removed value: -"define_wordArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedget_crypto20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_results / description
        Added value: +"Max coins to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Comma-separated coins (e.g. \"bitcoin, ethereum\"). Omit for top coins."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • addedInput schema / properties / vs_currency / description
        Added value: +"Fiat currency for prices, e.g. \"usd\", \"eur\" (default \"usd\")."
      • removedInput schema / properties / vs_currency / title
        Removed value: -"Vs Currency"
      • removedInput schema / title
        Removed value: -"get_cryptoArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedget_ubereats_menu16 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / store_url / description
        Added value: +"A store URL from a search_ubereats result's \"url\" field."
      • removedInput schema / properties / store_url / title
        Removed value: -"Store Url"
      • removedInput schema / title
        Removed value: -"get_ubereats_menuArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedget_weather16 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / location / description
        Added value: +"Place name, e.g. \"London\" or \"Tokyo, Japan\"."
      • removedInput schema / properties / location / title
        Removed value: -"Location"
      • removedInput schema / title
        Removed value: -"get_weatherArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedlist_available_scrapers3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedInput schema / title
        Removed value: -"list_available_scrapersArguments"
      • removedOutput schema / title
        Removed value: -"list_available_scrapersDictOutput"
    • Changedlookup_movie18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_pages / description
        Added value: +"Pages of search results to fetch, 10 per page (title search)."
      • removedInput schema / properties / max_pages / title
        Removed value: -"Max Pages"
      • addedInput schema / properties / query / description
        Added value: +"A title to search for (e.g. \"inception\"), or an IMDB id\n(e.g. \"tt1375666\") for a direct lookup."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"lookup_movieArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_news22 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / article_url / description
        Added value: +"A single article URL to extract full text from."
      • removedInput schema / properties / article_url / title
        Removed value: -"Article Url"
      • addedInput schema / properties / feed_url / description
        Added value: +"Direct URL to an RSS/Atom feed."
      • removedInput schema / properties / feed_url / title
        Removed value: -"Feed Url"
      • addedInput schema / properties / max_articles / description
        Added value: +"Max articles to return from a feed (default 50)."
      • removedInput schema / properties / max_articles / title
        Removed value: -"Max Articles"
      • addedInput schema / properties / site_url / description
        Added value: +"News site URL — its feed is auto-discovered."
      • removedInput schema / properties / site_url / title
        Removed value: -"Site Url"
      • removedInput schema / title
        Removed value: -"scrape_newsArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_stock20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / mode / description
        Added value: +"\"quote\", \"history\", or \"profile\"."
      • removedInput schema / properties / mode / title
        Removed value: -"Mode"
      • addedInput schema / properties / period / description
        Added value: +"History window when mode=\"history\", e.g. \"1mo\", \"1y\"."
      • removedInput schema / properties / period / title
        Removed value: -"Period"
      • addedInput schema / properties / symbol / description
        Added value: +"Ticker symbol, e.g. \"AAPL\", \"GOOGL\"."
      • removedInput schema / properties / symbol / title
        Removed value: -"Symbol"
      • removedInput schema / title
        Removed value: -"scrape_stockArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_url22 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_pages / description
        Added value: +"Follow pagination up to this many pages (default 1)."
      • removedInput schema / properties / max_pages / title
        Removed value: -"Max Pages"
      • addedInput schema / properties / render_js / description
        Added value: +"Render JavaScript with a browser backend (needs pyscrappy[browser])."
      • removedInput schema / properties / render_js / title
        Removed value: -"Render Js"
      • addedInput schema / properties / selectors / description
        Added value: +"Optional CSS selectors, e.g. {\"title\": \"h1\", \"price\": \".amount\"}."
      • removedInput schema / properties / selectors / title
        Removed value: -"Selectors"
      • addedInput schema / properties / url / description
        Added value: +"The page to scrape."
      • removedInput schema / properties / url / title
        Removed value: -"Url"
      • removedInput schema / title
        Removed value: -"scrape_urlArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_wikipedia18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / mode / description
        Added value: +"\"full\", \"paragraphs\", or \"headers\"."
      • removedInput schema / properties / mode / title
        Removed value: -"Mode"
      • addedInput schema / properties / query / description
        Added value: +"Article title or search term, e.g. \"Model Context Protocol\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"scrape_wikipediaArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_with18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / args / description
        Added value: +"Keyword arguments passed to that scraper's `scrape()` method."
      • removedInput schema / properties / args / title
        Removed value: -"Args"
      • addedInput schema / properties / name / description
        Added value: +"A scraper name from `list_available_scrapers`, e.g. \"wikipedia\"."
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • removedInput schema / title
        Removed value: -"scrape_withArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedscrape_zomato20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / city / description
        Added value: +"City name, e.g. \"Bangalore\"."
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • addedInput schema / properties / max_results / description
        Added value: +"Maximum number of restaurants to return (default 50)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Optional cuisine or restaurant search term."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"scrape_zomatoArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_amazon18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_pages / description
        Added value: +"Number of result pages to scrape (default 1)."
      • removedInput schema / properties / max_pages / title
        Removed value: -"Max Pages"
      • addedInput schema / properties / query / description
        Added value: +"Product search query, e.g. \"wireless headphones\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_amazonArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_books18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_results / description
        Added value: +"Max books to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Title, author, or free-text search."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_booksArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_github20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_results / description
        Added value: +"Max repositories to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Search query, e.g. \"web scraping language:python\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • addedInput schema / properties / sort / description
        Added value: +"\"best-match\" (default), \"stars\", \"forks\", or \"updated\"."
      • removedInput schema / properties / sort / title
        Removed value: -"Sort"
      • removedInput schema / title
        Removed value: -"search_githubArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_hackernews20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / by / description
        Added value: +"\"relevance\" (default) or \"date\" (most recent first)."
      • removedInput schema / properties / by / title
        Removed value: -"By"
      • addedInput schema / properties / max_results / description
        Added value: +"Max stories to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Search query."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_hackernewsArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_ikea22 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / country / description
        Added value: +"IKEA store country code, e.g. \"us\", \"gb\", \"de\" (default \"us\")."
      • removedInput schema / properties / country / title
        Removed value: -"Country"
      • addedInput schema / properties / lang / description
        Added value: +"Language code for that store, e.g. \"en\", \"de\" (default \"en\")."
      • removedInput schema / properties / lang / title
        Removed value: -"Lang"
      • addedInput schema / properties / max_results / description
        Added value: +"Maximum number of products to return (default 24)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Product search query, e.g. \"desk\" or \"bookshelf\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_ikeaArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_images20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / engine / description
        Added value: +"Search engine to use (default \"bing\")."
      • removedInput schema / properties / engine / title
        Removed value: -"Engine"
      • addedInput schema / properties / max_images / description
        Added value: +"Maximum number of image results (default 20)."
      • removedInput schema / properties / max_images / title
        Removed value: -"Max Images"
      • addedInput schema / properties / query / description
        Added value: +"Image search query, e.g. \"golden gate bridge\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_imagesArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_linkedin_jobs20 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / location / description
        Added value: +"Location filter, e.g. \"London\" or \"United Kingdom\"."
      • removedInput schema / properties / location / title
        Removed value: -"Location"
      • addedInput schema / properties / max_pages / description
        Added value: +"Pages of results to scrape (default 1)."
      • removedInput schema / properties / max_pages / title
        Removed value: -"Max Pages"
      • addedInput schema / properties / query / description
        Added value: +"Job title or keywords, e.g. \"machine learning engineer\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_linkedin_jobsArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_newegg18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_pages / description
        Added value: +"Number of result pages to scrape (default 1)."
      • removedInput schema / properties / max_pages / title
        Removed value: -"Max Pages"
      • addedInput schema / properties / query / description
        Added value: +"Product search query, e.g. \"graphics card\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_neweggArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_soundcloud18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_results / description
        Added value: +"Maximum number of tracks to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Search query, e.g. \"lofi beats\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_soundcloudArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_ubereats18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / city / description
        Added value: +"City name, e.g. \"London\"."
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • addedInput schema / properties / max_results / description
        Added value: +"Maximum restaurants to return (default 30)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • removedInput schema / title
        Removed value: -"search_ubereatsArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
    • Changedsearch_youtube18 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / max_results / description
        Added value: +"Maximum number of videos to return (default 20)."
      • removedInput schema / properties / max_results / title
        Removed value: -"Max Results"
      • addedInput schema / properties / query / description
        Added value: +"Search query, e.g. \"model context protocol tutorial\"."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"search_youtubeArguments"
      • removedOutput schema / $defs
        Removed value: -{
        -  "ToolError": {
        -    "description": "A non-fatal problem encountered while scraping.",
        -    "properties": {
        -      "message": {
        -        "title": "Message",
        -        "type": "string"
        -      },
        -      "url": {
        -        "title": "Url",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "url",
        -      "message"
        -    ],
        -    "title": "ToolError",
        -    "type": "object"
        -  }
        -}
      • removedOutput schema / properties / count / title
        Removed value: -"Count"
      • removedOutput schema / properties / data / title
        Removed value: -"Data"
      • removedOutput schema / properties / errors / items / $ref
        Removed value: -"#/$defs/ToolError"
      • addedOutput schema / properties / errors / items / description
        Added value: +"A non-fatal problem encountered while scraping."
      • addedOutput schema / properties / errors / items / properties
        Added value: +{
        +  "message": {
        +    "type": "string"
        +  },
        +  "url": {
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / properties / errors / items / required
        Added value: +[
        +  "url",
        +  "message"
        +]
      • addedOutput schema / properties / errors / items / type
        Added value: +"object"
      • removedOutput schema / properties / errors / title
        Removed value: -"Errors"
      • removedOutput schema / properties / scraper / title
        Removed value: -"Scraper"
      • removedOutput schema / properties / source_urls / title
        Removed value: -"Source Urls"
      • removedOutput schema / title
        Removed value: -"ScrapeToolResult"
  4. 5 tool updatesv1.3.0
    • Addedconvert_currency
    • Addedlist_available_scrapers
    • Addedscrape_stock
    • Addedscrape_with
    • Addedsearch_hackernews
  5. 4 tool updatesv1.2.0
    • Removedscrape_stock
    • Addedscrape_wikipedia
    • Addedsearch_ikea
    • Addedsearch_linkedin_jobs
  6. 12 tool updatesv1.2.0
    • Removedconvert_currency
    • Addedget_crypto
    • Addedget_ubereats_menu
    • Addedlookup_movie
    • Addedscrape_url
    • Addedscrape_zomato
    • Removedsearch_ikea
    • Addedsearch_images
    • Removedsearch_linkedin_jobs
    • Addedsearch_newegg
    • Addedsearch_soundcloud
    • Addedsearch_youtube

TDQS

A4.2/5.0
Disambiguation5/5

Each tool targets a distinct external service or data type (e.g., Wikipedia, YouTube, Amazon, weather) with clear boundaries. Even the generic tools (scrape_url vs scrape_with) have well-defined differences, and no two tools appear to do the same job.

Naming Consistency3/5

Tool names follow three main prefixes (scrape_, search_, get_) but are mixed with standalone verbs like convert_currency, define_word, and lookup_movie. The pattern is readable and somewhat predictable within each group, but the inconsistent prefixes and exceptions prevent a higher score.

Tool Count3/5

With 24 tools, the server sits in the 'heavy' range (16-25). However, the broad purpose of scraping many distinct sites justifies the count, though it feels slightly overstuffed compared to simpler scraping servers.

Completeness5/5

The server covers a comprehensive set of common scraping targets (general pages, Wikipedia, news, finance, e-commerce, media, jobs, etc.) and includes a generic dispatch (scrape_with) plus a registry explorer for third-party plugins. This makes the surface virtually extensible and free of critical gaps.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Web scraping, crawling, and structured data extraction for AI agents. 5 tools: scrape (clean markdown from any URL), crawl (entire sites), map (discover URLs), extract (structured JSON), and search. 833ms avg latency, single binary, self-hostable.
    8
    935
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Fetches web pages and converts them to markdown for LLM consumption, supporting chunked reading and raw content extraction.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides coding agents with live web capabilities including web search, scraping to Markdown, structured extraction, crawling, screenshots, and company lookup, all with zero dependencies.
    8
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mldsveda/PyScrappy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server