fetchaller
This server provides web fetching/search and specialized listing lookups for Reddit, marketplaces, real estate, jobs, and e-commerce.
Fetch any URL and return clean markdown or raw HTML; handles HTML, JSON, XML, CSV, and PDFs, with GET/POST, custom headers/body, timeout, and token limits.
Search the web by query and page.
Browse subreddit posts by hot/new/top/rising and search Reddit posts globally or within a subreddit.
Search Kijiji, Craigslist, and Facebook Marketplace together by query, location, category, condition, price, sort, and platform.
Search realtor.ca Canadian homes for sale or rent with location, price, beds, baths, property/building type, ownership, sort, and paging filters.
Search LinkedIn public job postings and fetch full details for a specific job ID.
Search AliExpress products and fetch product details including price, specs, ratings, and reviews.
Search Alibaba.com B2B products and fetch product details including tiered pricing, MOQ, lead times, and supplier info.
Automatically bypasses Akamai bot challenges when fetching URLs.
Allows searching Alibaba.com B2B products and retrieving product details with tiered pricing, MOQ, and supplier info.
Allows searching AliExpress products with filters and retrieving product details including price, specs, ratings, and reviews.
Automatically bypasses Cloudflare bot challenges when fetching URLs.
Integrates DuckDuckGo web search as a supplement to Google search results.
Integrates Facebook Marketplace search for listings across categories and locations.
Integrates Google web search for querying and retrieving search results.
Allows browsing subreddit listings and searching Reddit posts with sort and time filters.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fetchallersearch Reddit for Claude Code tips"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fetchaller-mcp
Fetch websites in Claude Code without per-domain permission prompts. Includes web search, complete logged-out New Reddit support, challenge detection, and automatic solving for the supported challenge types below.
Why fetchaller?
Claude Code's built-in WebFetch asks permission for every new domain and blocks Reddit entirely. fetchaller fixes both:
fetch: Read any URL — solves supported passive challenges and reports unresolved blocks as errorssearch: Google by default, with automatic fallback; choosegoogle,ddg,brave, orall. Every result names its source.browse_reddit: Browse subreddit listings (hot/new/top/rising)search_reddit: Search Reddit posts globally or within a subredditsearch_marketplace: Search Kijiji, Craigslist, and Facebook Marketplace simultaneously with human-readable params (city name, category, price range)search_realtor: Search Canadian homes on realtor.ca for sale or rent with full filters (location, price, beds, baths, property/building type, ownership)search_linkedin_jobs/get_linkedin_job: Search LinkedIn's public logged-out job board (keywords, location, date posted, remote/hybrid/on-site, experience, job type, salary) and read full postings — no account neededsearch_gojobs/get_gojobs_job: Search Ontario Public Service jobs and read full posting and competition status detailssearch_indeed/get_indeed_job: Search Indeed Canada and read full public posting data, including salary bands and expiry datessearch_jobbank: Search Canada's federal Job Bank by title, city, and radius with local result recheckingsearch_gcjobs/get_gcjobs_job: Search GC Jobs, the federal public service board, and read full postings with the "Who can apply" eligibility line firstget_unifi_manual: Download a Ubiquiti UniFi installation guide as a PDF or per-page PNGs. Ubiquiti publishes no PDF and draws these guides as vector artwork, so they carry no readable text — this rebuilds the pages into a real documentget_aliexpress_product: AliExpress product details (price, specs, ratings, reviews)search_aliexpress: Search AliExpress products with price filters and sortingget_alibaba_product: Alibaba.com B2B product details (tiered pricing, MOQ, lead times, supplier info)search_alibaba: Search Alibaba.com B2B products
Related MCP server: Spider MCP Server
Quick Start
Local Installation (stdio mode)
# Clone and install
git clone https://github.com/Averyy/fetchaller-mcp.git
cd fetchaller-mcp
uv sync
# Point this at branded Google Chrome. The pinned Linux reference build in
# Dockerfile gives the closest browser/transport identity match.
export BROWSER_EXECUTABLE_PATH=/path/to/Chrome-for-Testing
# Add to Claude Code
claude mcp add fetchaller -- uv --directory "$(pwd)" run fetchaller-mcpAdd permissions to ~/.claude/settings.json:
{
"permissions": {
"allow": [
"mcp__fetchaller__fetch",
"mcp__fetchaller__search",
"mcp__fetchaller__browse_reddit",
"mcp__fetchaller__search_reddit",
"mcp__fetchaller__search_marketplace",
"mcp__fetchaller__search_realtor",
"mcp__fetchaller__search_linkedin_jobs",
"mcp__fetchaller__get_linkedin_job",
"mcp__fetchaller__search_gojobs",
"mcp__fetchaller__get_gojobs_job",
"mcp__fetchaller__search_indeed",
"mcp__fetchaller__get_indeed_job",
"mcp__fetchaller__search_jobbank",
"mcp__fetchaller__search_gcjobs",
"mcp__fetchaller__get_gcjobs_job",
"mcp__fetchaller__get_unifi_manual",
"mcp__fetchaller__get_aliexpress_product",
"mcp__fetchaller__search_aliexpress",
"mcp__fetchaller__get_alibaba_product",
"mcp__fetchaller__search_alibaba"
]
}
}Restart Claude Code.
Recommended CLAUDE.md Addition
Add this to your project's CLAUDE.md (or global ~/.claude/CLAUDE.md) to instruct Claude to prefer fetchaller:
## Web Fetching & Search
**ALWAYS use fetchaller tools instead of WebFetch and WebSearch.** fetchaller has no domain restrictions and produces cleaner output.
- `mcp__fetchaller__fetch(url, maxTokens?, timeout?)` — Fetch any URL → clean markdown
- `mcp__fetchaller__search(query, provider, page?)` — Web search; required provider: `google` (preferred), `ddg`, `brave`, or `all`
- `mcp__fetchaller__browse_reddit(subreddit, sort?, time?, limit?)` — Browse subreddit listings
- `mcp__fetchaller__search_reddit(query, subreddit?, sort?, time?, limit?)` — Search Reddit posts
- `mcp__fetchaller__search_marketplace(query, location, platforms?, category?, sort?, condition?, min_price?, max_price?)` — Search Kijiji + Craigslist + Facebook Marketplace
- `mcp__fetchaller__search_realtor(location, transaction?, property_type?, building_type?, min_price?, max_price?, min_beds?, min_baths?, ownership?, sort?, page?)` — Search realtor.ca homes
- `mcp__fetchaller__search_linkedin_jobs(keywords, location?, strict_location?, date_posted?, workplace?, experience?, job_type?, min_salary?, easy_apply?, under_10_applicants?, sort?, start?, limit?)` — Search LinkedIn public jobs; `strict_location` defaults to `true` and re-checks each posting's own location
- `mcp__fetchaller__get_linkedin_job(job_id)` — Full public detail for one LinkedIn posting
- `mcp__fetchaller__search_gojobs(title?, location?, job_category?, career_level?, min_salary?, strict_title?, limit?)` — Search Ontario Public Service jobs
- `mcp__fetchaller__get_gojobs_job(job_id)` — Full OPS posting and competition status
- `mcp__fetchaller__search_indeed(title?, location?, radius_km?, strict_title?, strict_location?, limit?)` — Search Indeed Canada
- `mcp__fetchaller__get_indeed_job(job_key)` — Full Indeed posting, salary band, and expiry
- `mcp__fetchaller__search_jobbank(title?, location?, radius_km?, strict_title?, strict_location?, limit?)` — Search Canada's federal Job Bank
- `mcp__fetchaller__search_gcjobs(title?, location?, organization?, min_salary?, language?, exclude_various_locations?, strict_title?, limit?)` — Search GC Jobs, the federal public service board
- `mcp__fetchaller__get_gcjobs_job(job_id)` — Full GC Jobs posting: eligibility, closing date, salary, classification
- `mcp__fetchaller__get_unifi_manual(url, format?)` — Rebuild a UniFi installation guide as `pdf`/`png`/`svg`. Writes into the server's `DATA_DIR`, so on a containerised deployment the files land inside the container
- `mcp__fetchaller__get_aliexpress_product(product_id, timeout?)` — AliExpress product details
- `mcp__fetchaller__search_aliexpress(query, page?, sort?, min_price?, max_price?, timeout?)` — Search AliExpress
- `mcp__fetchaller__get_alibaba_product(product_id, timeout?)` — Alibaba.com product details
- `mcp__fetchaller__search_alibaba(query, page?, sort?, min_price?, max_price?, timeout?)` — Search Alibaba.comUsage
The mcp__fetchaller__fetch tool is now available:
# Fetch a URL
fetch https://example.com
# Fetch with token limit
fetch https://example.com maxTokens=10000
# Fetch slow site with longer timeout
fetch https://slow-site.com maxTokens=25000 timeout=60Web Search
# Search the web
search "python asyncio tutorial"
# Page 2 of results
search "python asyncio tutorial" page=2Web Research Pattern
Use
searchto find URLsUse
fetchto read them
Tool Reference
fetch(url, maxTokens?, timeout?, raw?, method?, headers?, body?)
Parameter | Type | Default | Description |
url | string | required | URL to fetch (http/https) |
maxTokens | number | 25000 | Max tokens to return |
timeout | number | 10 | Request timeout in seconds |
raw | boolean | false | Return raw HTML instead of markdown |
method | string |
|
|
headers | object | — | Extra request headers (max 32) |
body | string | — | Request body, |
POST
Many search and listing APIs answer only to POST — Getro (which powers a large share of VC portfolio job boards), Algolia, GraphQL gateways. Their pages look static and fetch fine, so a GET-only fetcher reports an empty board on a site that appears to work.
{
"url": "https://api.getro.com/api/v2/collections/246/search/jobs",
"method": "POST",
"headers": { "Accept": "application/json" },
"body": "{\"hitsPerPage\":100,\"page\":0}"
}Content-Type defaults to application/json when the body is valid JSON.
A POST skips site-specific handling and the response cache — every site
interceptor answers a URL pattern by issuing its own request, which would
discard the caller's body, and the cache is keyed by URL alone.
Only GET and POST are accepted. PUT/PATCH/DELETE have no retrieval
use; connection and body-framing headers (Host, Content-Length,
Transfer-Encoding, …) cannot be set. Credentials (Authorization, Cookie,
…) are dropped if a redirect crosses to another host, and a 301/302/303
downgrades a POST to a bodyless GET as browsers do.
Returns
Clean markdown with:
Page title as H1
Scripts, styles, nav, footer, iframes removed (careers/jobs links in the site chrome are preserved — they are almost never in the body copy)
HTML converted to markdown
Redirects noted
Content truncated at token limit
A
possibly_js_renderedwarning when the page's content is assembled by JavaScript, so an un-hydrated shell is not mistaken for an empty site — with whatever the shell still declares (description, canonical URL, company profiles from JSON-LD) recovered alongside it, since on such a page that is the entire available answer
Edge Cases
Scenario | Behavior |
Invalid URL | Error message |
Non-200 response | Error + partial body |
JSON content | Returned as-is |
XML/RSS feeds | Returned as-is |
CSV files | Returned as-is |
Plain text | Returned as-is |
PDF files | Text extracted |
Timeout | Error after timeout (default 10s) |
Huge page | Truncated at maxTokens |
search(query, provider, page?)
Parameter | Type | Default | Description |
query | string | required | Search query (up to 512 characters) |
provider | string | required; prefer |
|
page | integer | 1 | Result page: 1-100; DDG alone supports 1-10 |
search({query: "Python asyncio documentation", provider: "google"})
search({query: "Python asyncio documentation", provider: "all", page: 2})Google is the default choice, but provider must be included in every MCP call. A Google failure automatically falls back to DuckDuckGo, then Brave if needed. The output states why Google failed and which provider answered, and every result carries its source. An honest zero-result response does not trigger fallback. Explicit ddg and brave calls use only that provider. all queries all three concurrently and deduplicates URLs, keeping Google ranking first. Beyond page 10, DDG is explicitly skipped in all and Google fallback.
Google returns ten requested results per page through the Google Docs research-search JSON endpoint, using eligible public document IDs as request context; it searches the web, not those documents. No API key, login, browser or Opera Mini profile is used. All verified IDs are indexed in src/fetchaller/search/google_documents.json; each uncached Google request starts with a random healthy ID, avoiding consecutive reuse when alternatives exist. Document-specific failures are logged, cooled down for 15 minutes and skipped within a three-attempt total budget. HTTP 429 respects Retry-After and Google-wide backoff without rotating IDs. Requests across the entire Google pool are spaced at least six seconds apart. Pagination prefers server cursors and otherwise encodes the requested offset as a protobuf varint.
Override the verified pool with FETCHALLER_GOOGLE_DOCUMENT_IDS, a JSON array of eligible IDs. Do not add IDs without validating the search endpoint. See the handoff and verified pool. This legacy endpoint has no established parity with the ordinary Google SERP for ranking, freshness, SafeSearch, geography or time filters.
DuckDuckGo pages by walking its previous Next form, up to page 10; Brave uses a zero-based page offset and returns about twenty results per page. All three engines are paced at least six seconds apart per provider, matching Reddit’s default budget of ten requests per minute. DuckDuckGo and Brave add jitter, serialize HTTP requests, and also enable wafer’s six-second limiter; hidden transport retries are disabled. Their shared provider cooldowns cover explicit calls, all, and fallback: 60 seconds after HTTP 429 and 300 seconds after HTTP 403 (also DDG’s blocking 202), extended by a longer Retry-After. Google retains its escalating global backoff. Complete nonempty successes are cached for five minutes per query, page and provider; fallback and partial failures are retried on the next call. Provider errors always remain visible.
Brave delegates its verification challenge to wafer through the server’s existing guarded browser solver. Recovery uses the published wafer 0.7.9 release, required by fetchaller 3.8.6. The solver allows up to 120 seconds, the complete HTTP call 150 seconds, and the Brave provider 180 seconds including pacing and parsing. A challenge that remains unresolved is reported as a provider failure and starts a cooldown, including a challenge returned with HTTP 200. No challenge solving or cookie manipulation lives in fetchaller. Wafer 0.7.9 includes commit d01c811, which fixes the earlier reload stall and fast-recovery classification race. Real challenged MCP searches returned 20 Brave results on macOS and Linux, and native headed/headless checks verified fresh PoW, spare-token reuse and browser-free restart. Brave consumes token cookies after HTTP reads; wafer can use session-local spare tokens for later gates, with fresh work potentially needed after restart. See the verification record. Google and DuckDuckGo remain browser-free. Allow up to 360 seconds in MCP clients for the complete Google → DDG → Brave fallback chain. See local Brave verification.
Reddit Tools
Two tools for Reddit research:
browse_reddit - Browse Subreddit Listings
browse_reddit({
subreddit: "LocalLLaMA", // without r/ prefix
sort: "hot", // hot, new, top, rising
time: "day", // hour, day, week, month, year, all (for "top" only)
limit: 10 // 1-25
})Returns post titles, scores, comment counts, and URLs. Use fetch to read full posts.
search_reddit - Search Posts
search_reddit({
query: "best mass spectrometry software",
subreddit: "labrats", // optional - limit to subreddit
sort: "relevance", // relevance, hot, top, new, comments
time: "year", // hour, day, week, month, year, all
limit: 10 // 1-25
})Returns matching posts with metadata. Use fetch to read full discussions.
Compact New Reddit Fetching
Normal Reddit URLs and emitted links are canonicalized to www.reddit.com.
Structured JSON reads use the logged-out api.reddit.com origin and are
rendered as compact Markdown; HTML-only legs remain on the fixed New Reddit
www origin.
/r/{subreddit}/wiki/pages/ first reads the canonical New Reddit SSR page tree,
then falls back to New Reddit's own logged-out WikiPageRevisionsV2 page tree on
the fixed /svc/shreddit/graphql route when a community does not server-render
that tree. Both paths are anonymous: the page index needs no OAuth scope and no
browser. For a genuine historical collection URL, fetchaller
validates exact collection metadata from its archived New Reddit Redux snapshot
and hydrates every archived post ID from Reddit's current /api/info endpoint.
Archive shells, mismatched identities, empty collections, and missing current
posts are errors rather than successful empty or fabricated output.
Thread output includes the public vote score and upvote ratio returned by
Reddit, comment count and nested comments, outbound/discussion links, and
structured gallery, video, crosspost, poll, NSFW/spoiler/locked/archived, and
deleted-content state. Comment permalink URLs preserve the selected comment and
its parent context.
old.reddit.com input URLs are canonicalized to New Reddit; no normal request
depends on Old Reddit. Explicit .json URLs still return raw JSON. raw=true
on a normal Reddit URL returns the canonical New Reddit HTML representation.
Embedded author-written Old Reddit links are rewritten to their equivalent
www.reddit.com target.
Explicit JSON always remains parseable. When it exceeds maxTokens, fetchaller
retains only whole source scalars in a structural prefix and adds the top-level
JSON marker "_fetchaller_truncated": true (or a marker object at the end of a
top-level array). It never slices a string, substitutes a value, or reports
invalid JSON as success; a budget too small for both useful content and the
marker returns an explicit error.
fetchaller reads Reddit anonymously only and holds no credential: there is no account, login, OAuth user token, or client ID/secret in fetchaller. Every read is logged out. Its transport, wafer (>=0.7.0), serves JSON reads through Reddit's Android app API on an anonymous install token it mints and caches itself, and HTML through New Reddit's logged-out web path; neither needs a browser. The wiki page index is served by the SSR tree or New Reddit's logged-out page-tree route. Routes Reddit serves only to a logged-in account — exact moderator rosters, and account-private upvoted/downvoted activity — return an explicit error saying so; no names or counts are ever guessed or reconstructed.
Vote data is not reconstructed: score is Reddit's public, fuzzed vote score,
and upvote_ratio is displayed only when Reddit returns it. Separate true
upvote/downvote counts are not available anonymously and are never invented.
Bounded Context Use
The compact renderer requests limits and nesting depth from the caller's token budget, emits complete sections, and names every omitted section. Compactness is never allowed to remove public content silently. Any future size benchmark must ship its corpus, raw outputs, command, and timestamp with the result.
Reproducible Live Parity Evidence
baselines/reddit-legacy-contract-v1.json is an independent, versioned
inventory derived from the last generic Old Reddit implementation. The
offline gate compares that contract with both the production router and
baselines/reddit-parity-corpus.json, then exercises route/schema/renderer/MCP
fixtures:
uv run pytest -q \
tests/test_reddit_legacy_contract.py \
tests/test_reddit_parity_corpus.py \
tests/test_reddit.pyThe separate live gate runs the corpus through a real stdio MCP server with its six-second default pacing (five-second minimum):
SMOKE_STDIO_COMMAND='["docker","run","--rm","-i","fetchaller-mcp:candidate","python","-m","fetchaller.main"]' \
uv run python scripts/reddit_parity.py \
--strict \
--include-unstable \
--output /tmp/fetchaller-reddit-parityThe runner starts with an empty dedicated wafer-cache directory, keeps it for
the warm and recreated-process stages, and records every body (including a
failed/challenge body), hash, command, timestamp, and outcome. For an exact
docker run command it mounts beneath entrypoint-owned /app/data, aligns the
runtime UID/GID with the host, validates a real owner-only Reddit cookie file
after warm and recreated stages, records non-secret Reddit cache hydration and
pure-HTTP verification counts, and rejects either recreated verification or
guarded-browser egress. A conflicting cache/ownership environment or --env-file
fails closed. When real OAuth credentials make the two OAuth corpus entries eligible,
Docker receives only --env NAME forwarding (never credential values in the
command or report); anonymous SSR output never counts as OAuth evidence.
Default runs require stable anonymous targets in --strict mode. The complete
release gate adds --include-unstable: the runner discovers current real
post/comment, wiki-revision, public-multireddit, and live-update IDs through
separately recorded MCP calls, then requires
every public route
cold, warm, and recreated. It never substitutes a fake opaque ID.
Fixture-only targets always remain offline and can never become live evidence;
they are limited to inherently non-public access states such as private,
quarantined, banned, gated, forbidden, and not-found, and to surfaces Reddit
itself retired (gilded listings, post collections, the gold-only directory),
which are reported exactly as Reddit answers them and never rebuilt from an
archive.
Every route in the corpus is an anonymous public read and needs no
configuration. The live Reddit gates are currently waived on GitHub's hosted
runners only: Reddit answers the anonymous solve origin with 403 there, to a
real headful Chrome as well as to the HTTP client, which is consistent with
datacenter-IP blocking rather than anything request-side. Those runs carry an
explicit warning annotation so a green build is never mistaken for validated
Reddit, and the offline Reddit contract and fixture gate still runs on every
build. Every offline entry must carry a mandatory reason and complete fixture
evidence.
Rate Limits
browse_reddit and search_reddit each use one JSON call. A normal fetch
uses one bounded JSON call for most URLs; a profile root uses five independent
public sources for metadata, activity, trophies, multireddits, and moderated
communities. Mapped fetch calls and both dedicated tools share the server's
request queue. Anonymous reads share a durable wafer session; configured API
reads share a separate cookie-isolated application session. Caller-selected
raw representations use the generic fetch path and its Reddit domain limiter.
Token refreshes and every API request use the same bounded request budget.
AliExpress & Alibaba Tools
get_aliexpress_product(product_id, timeout?) - Product Details
Accepts a numeric product ID (e.g., 1005006027485365) or full URL. Returns
price, specifications, ratings, and recent reviews via AliExpress's MTop API.
If MTop is unavailable after a live search, an exact matching validated search
listing can supply a clearly labeled, narrower title/price/rating snapshot.
The optional timeout is an end-to-end budget from 1 to 180 seconds (default 180).
search_aliexpress(query, page?, sort?, min_price?, max_price?, timeout?) - Search Products
Parameter | Type | Default | Description |
query | string | required | Search query |
page | number | 1 | Page number (1-indexed) |
sort | string | "default" | default, orders, price_asc, price_desc |
min_price | number | — | Minimum price filter |
max_price | number | — | Maximum price filter |
timeout | integer | 180 | End-to-end budget in seconds (1–300) |
get_alibaba_product(product_id, timeout?) - B2B Product Details
Accepts a numeric product ID or full URL. Returns tiered pricing, MOQ, lead times, supplier info, and specifications. The optional timeout is an end-to-end budget from 1 to 300 seconds (default 180).
search_alibaba(query, page?, sort?, min_price?, max_price?, timeout?) - Search B2B Products
Parameter | Type | Default | Description |
query | string | required | Search query |
page | number | 1 | Page number (1-indexed) |
sort | string | "default" | default, price_asc, price_desc |
min_price | number | — | Minimum price filter (USD) |
max_price | number | — | Maximum price filter (USD) |
timeout | integer | 180 | End-to-end budget in seconds (1–300) |
Marketplace Search
search_marketplace — Search Kijiji, Craigslist, and Facebook Marketplace
Searches all three platforms concurrently with human-readable parameters and returns grouped results.
Parameter | Type | Default | Description |
query | string | required | Search keywords |
location | string | required | City name (e.g. "toronto", "st catharines, ON", "seattle") |
platforms | string[] | all | Platforms to search: kijiji, craigslist, facebook |
category | string | "all" | all, cars, electronics, furniture, clothing, tools, free, bikes, phones, motorcycles, boats, rvs, auto_parts, sporting, toys, baby |
sort | string | "date" | date, price_asc, price_desc, relevance |
condition | string | — | new, like_new, good, fair |
min_price | number | — | Minimum price in dollars |
max_price | number | — | Maximum price in dollars |
Kijiji is Canada-only and automatically skipped for US locations. Location matching supports exact names, common aliases (e.g. "niagara" → Hamilton CL area), and fuzzy matching for typos.
Real Estate Search
search_realtor — Search realtor.ca homes
Searches Canadian homes for sale or rent via realtor.ca's api2, with the full filter set so an assistant can narrow a home search. Returns listings with price, address, beds/baths, size, agent, and a realtor.ca URL.
Parameter | Type | Default | Description |
location | string | required | City, neighbourhood, or postal code (e.g. "Ottawa", "Orleans, Ottawa", "M5V") |
transaction | string | "sale" | sale, rent |
property_type | string | "any" | any, residential, condo, recreational, vacant-land, multi-family, agriculture, parking |
building_type | string | — | house, duplex, triplex, townhouse, apartment, other |
min_price | integer | — | Minimum price (sale) or monthly rent |
max_price | integer | — | Maximum price (sale) or monthly rent |
min_beds | integer | — | Minimum bedrooms |
min_baths | integer | — | Minimum bathrooms |
ownership | string | — | freehold, condo |
sort | string | "newest" | newest, oldest, price-asc, price-desc |
page | integer | 1 | Result page (~20 per page, up to 600 returnable) |
Call fetch(url) on any listing URL for the full description, every property detail, and similar nearby homes. fetch also handles realtor.ca search/SEO/map pages (/{prov}/{city}/real-estate, /map) and all wellfound.com pages (startup job search, job detail, company profiles).
How It Works
Validates URL (http/https only)
Blocks private/internal IPs (SSRF protection with DNS rebinding prevention)
Fetches with browser-like TLS fingerprints via wafer (Rust/BoringSSL) — rotates Chrome versions automatically
If bot challenge detected: solves automatically (see Bot Challenge Bypass below)
Detects content type
For HTML: removes junk elements (nav, footer, ads, cookie banners), applies site-specific cleanup (25+ sites including GitHub, Reddit, HN, Wikipedia, Medium, Stack Overflow, Amazon, eBay, AliExpress, Alibaba, DigiKey, Mouser, realtor.ca, wellfound.com, vacuumwars.com, The Home Depot (homedepot.com + homedepot.ca), plus Ashby/Greenhouse/Lever/Gem/Dayforce/Cornerstone/Workday/BambooHR/JazzHR/Work-at-a-Startup job boards with embed + white-label detection, and more), converts to markdown
For JSON/XML/CSV/text: returns raw
For PDF: extracts text
Truncates to token limit
Bot Challenge Bypass
fetchaller detects bot challenges and attempts the supported solver. A request
is successful only after the resulting content is no longer a challenge or
block page; a Playwright navigation that remains blocked is an error, never a
successful fetch. First requests can be slower, while later requests can reuse
durably cached cookies. The timeout parameter is one total wall-clock budget
covering transport retries, queueing, and browser solving.
Supported Challenges
Challenge | Method | Speed |
Alibaba Cloud WAF (ACW) | Inline Python solver | ~1ms |
Alibaba Cloud WAF (TMD) | wafer browser solver | ~5-60s |
Cloudflare Managed Challenge | Patchright browser solver | ~3-30s |
Akamai Bot Manager | Patchright browser solver | ~3-15s |
Amazon rate-limit/CAPTCHA | Inline form parse + follow (no browser) | ~100ms |
DataDome, PerimeterX, Imperva | Patchright browser solver | ~3-10s |
Kasada | Browser CT token + Python SHA-256 PoW | ~3-10s |
GeeTest v4 slide CAPTCHA | CV notch detection + drag replay | ~5-15s |
hCaptcha | Checkbox auto-pass; image escalation is detect-only | ~5-30s |
reCAPTCHA v2 / Enterprise | Checkbox → ONNX image grid | ~5-60s |
F5 Shape, AWS WAF | Patchright browser solver | ~3-15s |
All challenge solving is handled by wafer's BrowserSolver (Patchright-based). Cookies are cached per-domain so subsequent requests skip the challenge.
Arkose/FunCaptcha and hCaptcha image escalation are detect-only and return an explicit challenge error. Vercel and generic-JS handling supports passive JavaScript checks only. An interactive CAPTCHA or any page that still contains the challenge is reported as unresolved.
Requirements
Docker: The browser-complete image is linux/amd64 because Google does not
publish Chrome for Testing for Linux arm64. The build downloads one immutable
Chrome-for-Testing archive, verifies its SHA-256 digest and exact version, and
sets BROWSER_EXECUTABLE_PATH to that binary. BrowserSolver validates that the
configured executable is branded Chrome and warns if its version differs from
wafer/wreq's default emulation; browser-bound HTTP identity is aligned to the
installed browser, while the pinned image also keeps the TLS shape matched. The
local Compose file requests amd64 automatically on Apple Silicon, and the
cookie-data volume persists solved cookies across restarts.
Local (stdio): Browser support is included by default, but protected-site
solves require installed branded Google Chrome. Set BROWSER_EXECUTABLE_PATH
to that executable. Matching wafer's current emulation is recommended so the
browser and TLS identities stay aligned; the current Linux reference version
and archive checksum are the CHROME_VERSION and CHROME_SHA256 arguments in
Dockerfile.
Architecture
Content Processing
src/fetchaller/content/ handles HTML→markdown conversion. Each site module exports is_<site>(url), SELECTORS_LIST, and optionally strip_<site>_junk(soup) / postprocess_<site>(markdown):
html.py— Generic pipeline + dispatch. Universal junk selectors, markdownify, whitespace cleanup. Generic JSON-LD Product fallback.amazon.py— All TLDs (.com, .ca, .co.uk, .de, etc.). CSS selectors, soup cleanup, regex post-processors.github.py— CSS selectors, URL transforms, file tree extraction, issue/PR/discussion extraction from embedded JSON.reddit.py— Strict Reddit host recognition, New Reddit canonicalization, public URL→structured routing (JSON plus the canonical SSR wiki page tree), bounded compact renderers for threads/listings/profiles/rules/wiki, rich media, and structured access states.hackernews.py— CSS selectors, table unwrapping, story block reformatter.medium.py— CSS selectors (data-testid), HTML-based detection for unknown custom domains.huggingface.py— data-target attribute selectors, filter tag/button cleanup.stackoverflow.py— All Stack Exchange sites. CSS selectors, soup cleanup, regex post-processors.redflagdeals.py— RFD-specific CSS selectors, soup cleanup, regex post-processors.forums.py— Generic forum support (XenForo, vBulletin, phpBB, Discourse). RSS/Atom feed autodiscovery.wikipedia.py— CSS selectors for edit buttons, navboxes, TOC, reference lists.vacuumwars.py— Vacuum Wars (vacuumwars.com, compare.vacuumwars.com, robotvacs.com). Reads the robot-vacuum comparison tool's inline dataset (window.vwProducts), which the client-side app otherwise renders as an empty board; routes comparison reads to the tool's own uncached host rather than the cached WordPress copy, disclosing the swap and falling back loudly if it fails; separates lab-tested models from listed-only ones, collapses colour variants only where every printed figure agrees, and de-duplicates the leaderboard card that prints each product twice.alibaba.py— Embedded JSON extraction (window.detailData,window.__page__data_sse10), soup cleanup.aliexpress.py— CSS selectors, soup cleanup, regex post-processors.craigslist.py— All city subdomains. CSS selectors, regex post-processors. Search URL detection for SAPI intercept.facebook_marketplace.py— URL detection only. GraphQL client infacebook_marketplace/package.digikey.py— All TLDs. CSS selectors, soup cleanup. Behind Akamai (wafer handles). HTML fallback without API key.ebay.py— All TLDs. JSON-LD product extraction, search result DOM extraction (.s-item), regex post-processors.molex.py— JSON-LD Product extraction (additionalProperty specs). CSR site — specs only in structured data.mouser.py— All TLDs. CSS selectors, soup cleanup. Behind Akamai. HTML fallback without API key.soylent.py— Shopify store cleanup, inventory extraction fromgsf_conversion_data.ti.py— Document viewer support for lazy-loaded datasheets.ashby.py/greenhouse.py/lever.py/gem.py/dayforce.py/cornerstone.py/workday.py/bamboohr.py/jazzhr.py/teamtailor.py/workatastartup.py— Job-board platforms. All preserve the source's own field names, enum values, and section titles. Each posting and (where supported) board listing is dispatched to the platform's API/JSON shell before the generic HTML pipeline. Six embed/white-label detectors run during the HTML phase so company career pages likesynaptivemedical.com/job-openings(white-label Dayforce),skywatch.com/careers/(Ashby<script src="…/embed">),avidbots.com/company/careers/(BambooHR<div id="BambooHR">),earthdaily.com/job-openings(JazzHR multi-tenant), andcareers.oatly.com/jobs(Teamtailor on a custom domain) are upgraded to structured ATS output instead of returning empty SPA shells. Seedocs/site-apis.mdfor endpoints and detection details.
Search
src/fetchaller/search/ — Unified Google, DuckDuckGo and Brave search. Google uses the Google Docs JSON endpoint with a randomized healthy document pool, cursor pagination and global throttling backoff. Provider selection, automatic Google fallback, source labels, URL deduplication and a 5-minute cache use separate wafer sessions; Brave alone receives the server’s guarded browser solver for challenge recovery.
Site-Specific API Intercepts
CSR sites where HTML scraping produces garbage are intercepted in fetch_url() and routed to structured APIs:
Craigslist (
src/fetchaller/craigslist/) — SAPI v8 client (sapi.craigslist.org). Up to 120 items/request with total count. Area IDs from page HTML, cached per hostname. Listing pages stay in HTML pipeline.Kijiji (
src/fetchaller/kijiji/) — Unauthenticated Apollo GraphQL (kijiji.ca/anvil/api). Search + listing detail. Prices in cents.Facebook Marketplace (
src/fetchaller/facebook_marketplace/) — GraphQL (facebook.com/api/graphql/) sent in the logged-out Comet form (__a,__comet_req; without them search silently serves nothing). A search or city URL is read from the page's own preloaded query and results, so location and filters match facebook.com; listing detail with photos.AliExpress (
src/fetchaller/aliexpress/) — MTop API for products (token bootstrap + MD5 signing). SSR HTML for search. Reviews fromfeedback.aliexpress.com.Alibaba.com (
src/fetchaller/alibaba/) — SSR HTML with embedded JSON. No MTop API for international site.eBay — SSR search results extracted from
.s-itemDOM elements, formatted as numbered list.Mouser (
src/fetchaller/mouser/) — Search API client. RequiresMOUSER_API_KEY.DigiKey (
src/fetchaller/digikey/) — OAuth2 client_credentials API. RequiresDIGIKEY_CLIENT_ID+DIGIKEY_CLIENT_SECRET.Ubiquiti / UniFi (
src/fetchaller/ubiquiti/) —*.store.ui.com,techspecs.ui.com, andui.com/qig/<slug>installation guides. Store pages carry the price in their HTML but none of the technical specifications, which render client-side from__NEXT_DATA__; dispatch is by Next.js route, not URL shape. Guides are JS page assets of outlined vector art with no readable text, rebuilt into a PDF/PNG byget_unifi_manual.Costco (
src/fetchaller/costco/) — costco.com and costco.ca search and category pages from the catalogue search the sites themselves use (Google Retail Search behindgdx-api.costco.com), configured from each page's own published service config: prices, sale prices, promotions, delivery and warehouse stock for the site's default warehouse (named), ratings, item numbers, paging, sort, brand refinement, and the site's own keyword redirects ("tv" → TVs) followed and disclosed.The Home Depot (
src/fetchaller/homedepot/) — homedepot.com and homedepot.ca, neither needing a browser. homedepot.com's pages sit behind Akamai's sensor challenge, but their data comes from the site's own federation-gateway GraphQL, which answers plainly: products (specs, per-store price and pickup stock, shipping), search and category listings (paging, sort, price range, refinements, keyword redirects followed and disclosed), reviews (pooled across variants, each sibling's review marked) and store pages. homedepot.ca is read from its Angular page state, its search API and its price service (sale was-prices live only there), in English and French.Marketplace Search (
src/fetchaller/marketplace/) — Unified orchestrator searching Kijiji, Craigslist, and Facebook Marketplace concurrently. Human-readable params mapped to platform-specific values. Auto-skips Kijiji for non-Canadian locations.Dayforce HCM (
src/fetchaller/content/dayforce.py) — Posting detail from SSR'd__NEXT_DATA__. Board listing via CSRF-protected POST to/api/geo/{namespace}/jobposting/search(NextAuth/api/auth/csrfround-trip required). White-label deployments on company domains are detected via__NEXT_DATA__.runtimeConfig.BASE_URLand rewritten to the canonicaljobs.dayforcehcm.comboard URL.Cornerstone OnDemand (
src/fetchaller/content/cornerstone.py) — SPA shell carries a JWT incsod.context. Posting fromservices/x/job-requisition/v2/requisitions/{reqid}/jobDetails; board listing POSTed torec-job-search/external/jobson the regional cloud host (us|eu|uk|au.api.csod.com).Workday (
src/fetchaller/content/workday.py) —{tenant}.wd{1-103}.myworkdayjobs.comboards and postings. Posting GET/wday/cxs/{tenant}/{site}/job{externalPath}; board POST/wday/cxs/{tenant}/{site}/jobspaginated in batches of 20 (capped at 200).BambooHR (
src/fetchaller/content/bamboohr.py) —{tenant}.bamboohr.com/careers. Board GET/careers/list; posting GET/careers/{id}/detail. Both return clean JSON unauthenticated. Widget embeds (<div id="BambooHR" data-domain="{tenant}.bamboohr.com">) on company sites are auto-detected and resolved to the tenant subdomain.Teamtailor (
src/fetchaller/content/teamtailor.py) —{slug}.teamtailor.com/jobsor the company's own domain (careers.oatly.com/jobs, recognised from the page). The HTML list stops at 20 with no salaries, so the board is read fromjobs.json(salary band, dates) joined tojobs.rss(department, location, remote status) on the posting UUID, walking both feeds' paging to the end — which works differently with a filter than without. Postings render from their own page.JazzHR (
src/fetchaller/content/jazzhr.py) —{tenant}.applytojob.com/apply. Board SSR'd HTML (.list-group .list-group-item); posting reads schema.orgJobPostingJSON-LD. Company sites that reference one or more JazzHR tenants via JS (e.g.earthdaily.com/job-openings) are auto-aggregated into a combined board.
HTTP Transport (Wafer)
All HTTP is handled by wafer (~/code/wafer). Fetchaller does NOT contain bot protection, challenge solving, or TLS fingerprinting code. If a site blocks requests, fix it in wafer.
Remote Deployment (HTTP Mode)
Deploy fetchaller as a remote MCP server for Claude.ai, Claude Desktop, or any MCP client.
Quick Start
# Local loopback HTTP with authentication and restart-stable OAuth
export MCP_API_KEY='your-secret-key'
export JWT_SECRET="$(openssl rand -hex 32)"
export MCP_SERVER_URL='http://localhost:6000'
uv run python -m fetchaller.main --http
# Production Compose also requires a public HTTPS origin. It binds the app
# itself to 127.0.0.1:6000 for a host TLS reverse proxy.
export MCP_SERVER_URL='https://mcp.example.com'
docker compose up -dProduction traffic must terminate TLS before reaching the loopback-bound app.
Configure the host reverse proxy to forward to 127.0.0.1:6000. If the proxy
sets X-Forwarded-For, set TRUSTED_PROXY_IPS to only that proxy's exact
address or CIDR; untrusted forwarded headers are ignored.
Local Development
# Build and test locally
docker compose -f docker-compose.local.yml up --build
# Test endpoints
curl http://localhost:6000/health
curl -X POST http://localhost:6000/mcp \
-H "Authorization: Bearer test-api-key-local" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'Claude Code/Desktop Config
{
"mcpServers": {
"fetchaller": {
"type": "streamable-http",
"url": "https://mcp.fetchaller.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Claude.ai Custom Connector (OAuth)
For Claude.ai web/mobile with cross-platform sync:
Go to Settings → Connectors → Add Custom Connector
Name:
fetchallerURL:
https://mcp.fetchaller.com/mcpLeave Client ID/Secret blank
Enter your API key when prompted
Environment Variables
Variable | Default | Description |
| 6000 | Server port (1-65535) |
|
| Container supervisor deadline for HTTP readiness; expiry exits nonzero so Docker restarts the service |
|
| Grace period after supervisor |
| (required) | Bearer token for auth |
| loopback default outside production Compose | Public HTTPS origin for OAuth; exact loopback HTTP is allowed for local use |
| (required with API keys) | Stable signing secret for OAuth tokens — see below |
|
| Set to |
|
| Persistent OAuth client and refresh-token state |
|
| OAuth access-token lifetime in seconds (30 days) |
| 100 | Requests/minute per IP |
|
| Set to |
| — | Comma-separated addresses/CIDRs of reverse proxies whose rightmost |
|
| Timezone of the challenge-solving browser. Set it to your server's public IP's zone (e.g. |
| — | Mouser Search API key (free registration) |
| — | DigiKey API client ID (free registration) |
| — | DigiKey API client secret |
JWT_SECRET (required for persistent deployments)
OAuth access tokens are stateless JWTs. When MCP_API_KEY is configured, HTTP startup fails
if JWT_SECRET is unset. For local HTTP development only, ALLOW_EPHEMERAL_JWT=1 opts into a
random per-process secret; every previously issued access token then becomes invalid when the
process restarts. Registered clients and hashed refresh tokens persist under DATA_DIR, while
short-lived authorization codes remain in memory.
Generate one value and keep it stable for the life of the deployment:
openssl rand -hex 32Pass it to the container the same way as MCP_API_KEY (compose environment:, Unraid
template variable, etc.). Verify it landed with printenv | grep JWT_SECRET inside the
container — an empty value counts as unset and prevents authenticated HTTP startup.
Two caveats:
Changing it invalidates every access token. Clients can normally recover with their persisted rotating refresh tokens, but rotating both the secret and OAuth state un-pairs every connector.
Do not derive it from
MCP_API_KEY. Token payloads carryapi_key_hashin cleartext, so a derived secret is recoverable from any captured token, allowing forged tokens. Use an independent random value.
Bearer auth with a raw MCP_API_KEY is unaffected by any of this — it is validated against
the environment variable directly and survives restarts.
Security
SSRF Protection: Blocks localhost, private IPs, CGNAT/shared space, link-local addresses, and DNS rebinding services (nip.io, xip.io, etc.). Resolves hostnames, verifies every resolved address, and pins the connection to those addresses to close the DNS-rebinding window. Chromium challenge solving is covered too: every browser redirect and subresource is forced through a loopback-only SOCKS5 guard that re-applies the address policy and connects to an approved numeric IP. Public nonstandard ports remain supported; Chromium's own unsafe-port policy determines which ports a page may use. Transition addresses (NAT64, 6to4, Teredo, IPv4-mapped) are judged by the IPv4 they actually translate to, so
64:ff9b::+ a public host works on IPv6-only networks while64:ff9b::7f00:1(loopback) and64:ff9b::a9fe:a9fe(cloud metadata) stay blocked. Unresolvable hosts fail closed but are reported as a DNS failure, not as a private-host block.OAuth 2.1: PKCE required for authorization-code exchanges. Refresh tokens are hashed at rest and rotate on use.
Rate Limiting: Per-IP rate limiting with configurable limits.
Files
fetchaller-mcp/
├── pyproject.toml # Python package config
├── src/fetchaller/ # Python source
│ ├── main.py # Entry point
│ ├── server.py # MCP server setup
│ ├── config.py # Configuration
│ ├── http/ # HTTP server (FastAPI)
│ ├── tools/ # MCP tools (fetch, search, reddit, aliexpress, alibaba, marketplace)
│ ├── content/ # Content processing (HTML→markdown, site-specific cleanup)
│ ├── search/ # Web search (Google / DDG / Brave / all)
│ ├── aliexpress/ # AliExpress MTop API client, product, search, reviews
│ ├── alibaba/ # Alibaba.com product and search extraction
│ ├── mouser/ # Mouser Search API client
│ ├── craigslist/ # Craigslist SAPI client + location resolution
│ ├── kijiji/ # Kijiji GraphQL API client + location resolution
│ ├── facebook_marketplace/# Facebook Marketplace GraphQL client
│ ├── marketplace/ # Unified marketplace search orchestrator
│ ├── ubiquiti/ # UniFi store/techspecs specs + installation guides
│ ├── homedepot/ # homedepot.com gateway GraphQL + homedepot.ca page state
│ ├── digikey/ # DigiKey API client (OAuth2 + product/search)
│ ├── cache/ # Response caching
│ ├── queue/ # Reddit rate limiting
│ └── security/ # SSRF, crypto, XSS
├── docker-compose.yml # Production deployment
├── docker-compose.local.yml # Local testing
├── Dockerfile # Container build
├── docs/ # Architecture & developer docs
├── CLAUDE.md # Instructions for Claude
├── README.md # This file
└── landing/ # Static site (fetchaller.com)
├── index.html # Landing page
└── llms.txt # LLM-readable project summary (llmstxt.org spec)Dependencies
wafer-py[browser]- HTTP transport with TLS fingerprinting, bot challenge bypass, and browser solver (Rust/BoringSSL + Patchright)mcp- MCP protocol SDKfastapi+uvicorn- HTTP serverbeautifulsoup4+markdownify- HTML to markdownpymupdf4llm- PDF to markdown extractionpyjwt- OAuth tokens
Testing
# Run tests
uv sync --extra dev
uv run ruff check src/ tests/
uv run pytest tests/ -x -q
# Test in Docker
docker compose -f docker-compose.local.yml up --build
curl http://localhost:6000/healthLicense
MIT
Available Tools
28 toolsbrowse_redditB
Browse a subreddit's posts. Returns metadata and URLs. Use mcp__fetchaller__fetch to read full post content.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort order | hot |
| time | No | Time filter (only applies to 'top' sort) | day |
| after | No | Pagination cursor from previous response | |
| limit | No | Number of posts (1-25) | |
| timeout | No | Request timeout in seconds (default: 10) | |
| subreddit | Yes | Subreddit name without r/ prefix |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must fully disclose behavioral traits. It mentions returns metadata and URLs, but does not state read-only nature, rate limits, authentication needs, error conditions, or side effects. This is a significant gap for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is extremely concise: two sentences, front-loaded with purpose, and immediately followed by actionable guidance. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description mentions returns 'metadata and URLs', but not what metadata includes. No coverage of pagination, error cases, or tool-specific features. Adequate but not thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all 6 parameters described in schema), so baseline is 3. The description adds no additional meaning beyond schema; no explanation of parameter purpose or usage context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Browse a subreddit's posts' with specific verb and resource, and distinguishes from fetch by directing to use fetch for full content. However, it does not differentiate from search_reddit sibling, leaving ambiguity about when to use browse vs search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides partial guidance: it tells users to use fetch for reading full content, implying browse is not for that purpose. But it gives no explicit when-to-use vs siblings like search_reddit, and no prerequisites or context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetchA
Fetch any URL and return the page content as clean markdown. Handles HTML, JSON, XML, CSV, and PDF files. Use this tool for reading/fetching web pages - it has no domain restrictions. For discovering URLs via search, use the search tool. For reading URL content, use this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | Return raw HTML instead of markdown (default: false) | |
| url | Yes | The URL to fetch | |
| body | No | Request body (POST only). Content-Type defaults to application/json when the body is valid JSON. | |
| method | No | HTTP method (default: GET). Use POST for search/listing APIs that only answer to POST (Getro, Algolia, GraphQL). POST requests skip site-specific handling and the response cache. | |
| headers | No | Extra request headers, e.g. {"Accept": "application/json"}. Connection and body-framing headers cannot be set. | |
| timeout | No | Request timeout in seconds (default: 10) | |
| maxTokens | No | Maximum tokens to return (default: 25000) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It mentions handling multiple file types and returning markdown, but omits details on caching, redirect handling, or rate limits. The schema adds some behavior (POST bypasses cache), but the description does not summarize this.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each adding critical information: core function, supported formats, and usage guidance against alternatives. No waste or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 7 parameters and no output schema, the description covers core behavior, supported formats, and use cases. Missing details like error handling or timeouts, but schema covers parameter constraints.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 no parameter-specific meaning beyond what the schema already provides. The mention of 'handles HTML...' is about output, not parameters, and does not enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches any URL and returns markdown content. It differentiates from sibling tools by noting 'no domain restrictions' and explicitly contrasts with the search tool for URL discovery.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance to use this tool for reading web pages and directs users to the search tool for URL discovery. Does not contrast with other fetch-like siblings (e.g., get_alibaba_product), but the 'no domain restrictions' implies preference for generic use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_alibaba_productA
Get Alibaba.com B2B product details including tiered pricing, MOQ, lead times, supplier info, and specifications. Accepts a numeric product ID or full URL.
| Name | Required | Description | Default |
|---|---|---|---|
| timeout | No | End-to-end timeout in seconds (default: 180) | |
| product_id | Yes | Numeric product ID or full Alibaba.com URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It lists returned data types but does not disclose read-only nature, error handling, rate limits, or authentication needs. Adequate but with gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no wasted words. Front-loads the main action and key details. Every piece of information is relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter tool with no output schema and no annotations, the description is fairly complete. It explains what the tool does, what input to provide, and what kind of information to expect. Could mention that product_id can be just a number, but it's implied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds value by clarifying that product_id accepts both numeric ID and full URL. For timeout, description adds nothing beyond schema defaults and bounds. Overall helpful beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get Alibaba.com B2B product details' and lists specific data points (tiered pricing, MOQ, lead times, supplier info, specifications). Distinguishes from sibling tools like search_alibaba and get_aliexpress_product in scope and target platform.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly indicates when to use: when you have a numeric product ID or full URL. Does not provide when-not-to-use or name alternatives, but the context is clear for a retrieval vs. search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_aliexpress_productA
Get AliExpress product details including price, specifications, ratings, and recent reviews. Accepts a numeric product ID or full URL.
| Name | Required | Description | Default |
|---|---|---|---|
| timeout | No | End-to-end timeout in seconds (default: 180) | |
| product_id | Yes | Numeric product ID or full AliExpress URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It mentions the tool retrieves details including price, specs, ratings, and recent reviews, which suggests a read-only behavior. However, it does not disclose potential failure modes, authentication needs, rate limits, or whether it fetches live data from the web, leaving some behavioral aspects unclear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long: the first states the purpose and output, the second states the input format. It is front-loaded with the core action and is free of unnecessary words or redundancies.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description lists some returned fields (price, specifications, ratings, recent reviews) but does not provide a complete response structure. With no output schema, the agent must infer the full format. Additionally, it lacks details on constraints like pagination, language, or error handling, making it adequate but not comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 repeats the input format ('numeric product ID or full URL') that is already in the schema description for product_id. It does not add significant additional meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Get AliExpress product details including price, specifications, ratings, and recent reviews.' It uses a specific verb ('Get') and resource ('AliExpress product details'), and distinguishes itself from sibling tools like search_aliexpress by focusing on retrieving details for a known product rather than searching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you have a numeric product ID or full URL ('Accepts a numeric product ID or full URL'), but it does not explicitly state when to use this tool versus alternatives like search_aliexpress or get_alibaba_product. No when-not or alternative guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gcjobs_jobA
Full detail for one GC Jobs posting by the numeric poster ID in its URL. Reports 'Who can apply' first — the eligibility line that decides whether a federal posting is open to the reader — flags a posting whose closing date has passed (the board still serves 2001-era postings as though live), and, for the third of postings the hiring organization hosts on its own site, returns the outbound URL instead of an empty record.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Numeric poster ID from the posting URL (page1800?poster=NNNNNNN), e.g. "2432896" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description has to do the work alone, and it discloses genuinely non-obvious behavior: 'Who can apply' is surfaced first, postings past their closing date are flagged because the board still serves 2001-era listings as though live, and about a third of postings return an outbound URL instead of a record. That is the kind of context needed to interpret a result correctly. It stops short of covering failure modes (invalid ID) or any rate-limit/auth expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One tight sentence, front-loaded with the core purpose before the value-add details about eligibility, stale listings, and off-site hosting. The parenthetical about 2001-era postings is slightly colorful but still carries information about stale data, so nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the return-value burden, and it does describe the notable parts of the response: the eligibility line reported first plus the outbound-URL fallback. It is not an exhaustive field list, but it covers what an agent needs to decide whether this tool answers its question.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents job_id as a numeric poster ID from the URL with a concrete example, so the description adds essentially nothing beyond that. Baseline 3 applies when the schema does the heavy lifting and the description only restates the key format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: full detail for a single GC Jobs posting, keyed by the numeric poster ID from its URL. That is clearly distinct from the sibling list tools (search_gcjobs) and from job-detail tools for other boards (get_linkedin_job, get_indeed_job, get_gojobs_job) without needing to open any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage is implied rather than stated: 'by the numeric poster ID in its URL' signals this is the detail lookup that follows a search, and the mention of postings hosted off-site hints at when the result will not contain a full record. But it never explicitly names search_gcjobs as the way to obtain an ID, nor states any when-not condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_gojobs_jobA
Full detail for one Ontario Public Service posting by its numeric Job ID. Reports the competition status, which can say a job is filled while the posting still reads as open.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Numeric Job ID, e.g. "232882" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It adds useful context by warning that the competition status may say a job is filled while the posting still appears open, but it omits explicit read-only/no-side-effects confirmation and does not describe error behavior or return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is two tight sentences with the core purpose front-loaded. The second sentence adds a non-obvious data caveat without wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter retrieval tool, the description gives enough context to select and call it correctly, especially since the schema fully documents the ID format. It could say more about what 'full detail' includes, but no output schema exists and the main operational caveat is already surfaced.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter and schema description coverage is 100%, so the schema already documents the Job ID with an example. The description restates that it is a numeric Job ID but adds no meaningful syntax, format, or validation detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: retrieves full detail for one Ontario Public Service posting by numeric Job ID. It implicitly distinguishes itself from the sibling search_gojobs tool by emphasizing a single posting looked up by ID rather than a search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the usage context clear enough: use it when you have a numeric Job ID and need the full posting. However, it does not explicitly say when to use this instead of search_gojobs or other job-detail siblings, nor does it mention prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_indeed_jobA
Full detail for one Indeed posting: description, salary band, and the listing's expiry date — the only expiry any indexed board publishes, which distinguishes a live posting from a stale index entry. Use this to read a body that a UKG or PeopleSoft careers site gates behind a session.
| Name | Required | Description | Default |
|---|---|---|---|
| job_key | Yes | Alphanumeric key from a ?jk= URL, e.g. "2a12ebab7a985a08" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses the returned fields and explains that the expiry date distinguishes a live posting from a stale index entry, but it does not state read-only safety, authentication requirements, rate limits, or error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is two tightly written sentences with no waste, and the core purpose is front-loaded before the supporting use case. The expiry explanation earns its place by clarifying why the field matters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter detail tool with no output schema, the description identifies the main returned fields and the key expiry semantics. It stops short of describing error cases or the full response shape, but it is otherwise complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already explains that job_key is an alphanumeric key from a ?jk= URL with an example. The description adds no parameter-level detail beyond what the schema provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Full detail for one Indeed posting' — and names the fields returned, including description, salary band, and expiry date. This clearly distinguishes the tool from search_indeed and from sibling get_*_job tools for other boards.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete when-to-use scenario: retrieving a posting body that a UKG or PeopleSoft careers site gates behind a session. It does not explicitly name search_indeed as the prior step or state when not to use it, but the retrieval context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_linkedin_jobB
Get the full public detail for one LinkedIn job posting: description, seniority, employment type, job function, industries, and applicant count. Applying still requires a LinkedIn account.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Numeric LinkedIn job ID (6-20 digits), the trailing number in a linkedin.com/jobs/view/<id> URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It notes that applying requires an account, but lacks information on rate limits, authentication needs, or any side effects. The tool is a read-only operation, but this is not explicitly stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exceptionally concise with two sentences that front-load the core purpose and essential caveat. Every sentence is necessary and contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple input (one parameter) and no output schema, the description covers the key output fields and a practical limitation. However, it does not mention potential errors or response format, which could be useful for completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% schema description coverage with a well-described job_id parameter. The tool description adds further context by explaining how to obtain the job ID from a LinkedIn URL, which enhances understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves full public detail for a single LinkedIn job posting, listing specific fields. It distinguishes itself from sibling search tools by being a detail fetcher, though not explicitly differentiating from get_alibaba_product or get_aliexpress_product which are similar in nature but for different platforms.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions that applying requires a LinkedIn account, which provides some context, but it does not guide on when to use this tool versus alternatives like search_linkedin_jobs. No explicit when-to-use or when-not-to-use guidelines are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_unifi_manualA
Download a Ubiquiti UniFi installation guide (ui.com/qig/) as a readable document. Ubiquiti publishes no PDF and draws every word of these guides as vector artwork, so the guide cannot be read as text — this rebuilds its pages and writes them to disk. Use 'pdf' for one combined file, or 'png' to get one image per page that can be viewed directly. For a device's specifications or price, fetch its store or techspecs.ui.com page instead.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Installation guide URL, e.g. https://ui.com/qig/u7-pro-wall or https://dl.ui.com/qig/u7-pro-wall/ | |
| format | No | pdf: one vector file with every page. png: one raster image per page, readable by a vision-capable client. svg: the reconstructed vector source per page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses that the source is vector artwork with no PDF, that the tool reconstructs pages, and that it writes files to disk (a side effect an agent must know about). It omits where files land, whether an existing file is overwritten, and any auth or rate-limit behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and resource, then the reason it exists, then format guidance and the exclusion. Slightly longer than needed because the format sentence duplicates the schema enum text, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema, the description covers what is produced (a PDF, per-page PNGs, or SVG sources written to disk) and why the textual route is impossible. Missing only operational specifics like output path and overwrite behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear enum descriptions for url and format, so the baseline is 3. The description's "one combined file" vs "one image per page" framing restates the schema's pdf/png semantics rather than adding new detail such as file naming or resolution.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Download a Ubiquiti UniFi installation guide") plus the exact URL pattern it operates on. It further distinguishes itself from generic fetching and from the store/techspecs pages, so an agent can tell what this tool does and does not cover without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent away for adjacent intents ("For a device's specifications or price, fetch its store or techspecs.ui.com page instead") and explains which format to pick for which output need. It does not name any sibling tool as an alternative, which keeps it 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.
searchA
Search the web for titles, URLs, and snippets, then use fetch to read full pages. Specify provider: google (default choice, automatic fallback to DDG then Brave on failure), ddg, brave, or all (merge all three). Sources and fallback are disclosed. Google and Brave support pages 1-100; DDG supports 1-10 and is skipped beyond page 10 in all/fallback. Brave challenge recovery may take up to three minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Result page (1-indexed, default: 1) | |
| query | Yes | Search query | |
| provider | Yes | Required. Prefer google; google failures fall back to DDG then Brave. all merges all providers. Every result names its source. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does it well: it discloses the fallback chain, per-provider page ceilings, that DDG is silently skipped past page 10 in `all`/fallback modes, that result sources are labeled, and even a latency hazard (Brave challenge recovery up to three minutes). These are exactly the operational traits an agent needs before committing a call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose in the first sentence, then dense but relevant operational detail. Slightly overpacked as a single block, and the provider/fallback information partly duplicates what the schema's `provider` description already states, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter, annotation-free, output-schema-free tool, the description covers everything material: what comes back (titles/URLs/snippets with source labels), how provider choice behaves on failure, and per-provider page limits. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 earns above that by adding a fact the schema cannot express — that the `page` maximum of 100 is provider-dependent (Google/Brave 1-100, DDG only 1-10 and skipped beyond 10). The `provider` and `query` semantics largely restate the enum description rather than extend it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource ("Search the web") and states the return shape (titles, URLs, snippets), then explicitly routes to the sibling `fetch` for full pages. An agent can distinguish this general web search from the domain-specific `search_*` siblings and from `fetch` without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit two-step usage (search here, then fetch), and detailed provider-selection guidance: google as default with automatic fallback to DDG then Brave, `all` to merge. It stops short of saying when NOT to use it (e.g., prefer the job/marketplace-specific search siblings for those domains), leaving that inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_alibabaA
Search Alibaba.com B2B products. Returns supplier listings with tiered pricing, MOQ, and supplier info.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-indexed, default: 1) | |
| sort | No | Sort order | default |
| query | Yes | Search query | |
| timeout | No | End-to-end timeout in seconds (default: 180) | |
| max_price | No | Maximum price filter (USD) | |
| min_price | No | Minimum price filter (USD) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It mentions the return type (supplier listings with pricing, MOQ, info) but does not disclose behavioral aspects such as rate limits, authentication needs, pagination behavior, or whether results are real-time. It is adequate but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the primary action and key return info. There is no unnecessary content, and it is efficiently concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema, the description covers the primary return elements (supplier listings, pricing, MOQ, supplier info). However, it omits details on pagination, result count limits, and how filters combine. The parameter schema is well-documented, but the description could be more complete for a tool with moderate complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds no extra meaning beyond what the schema already provides (e.g., explanation of how min_price/max_price interact or sort options). It merely restates the purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Search', the resource 'Alibaba.com B2B products', and what is returned (supplier listings with tiered pricing, MOQ, and supplier info). It distinguishes from siblings like search_aliexpress (consumer) and search_marketplace (generic).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives, nor does it provide prerequisites or exclusions. The name and purpose imply B2B product search on Alibaba, but explicit guidance is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_aliexpressA
Search AliExpress products. Returns product listings with prices, ratings, and links. Best-effort — may fail if anti-bot protection triggers.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-indexed, default: 1) | |
| sort | No | Sort order | default |
| query | Yes | Search query | |
| timeout | No | End-to-end timeout in seconds (default: 180) | |
| max_price | No | Maximum price filter | |
| min_price | No | Minimum price filter |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavior. It mentions best-effort execution and possible anti-bot failure, which is useful. However, it omits details on rate limits, data freshness, or whether results are real-time, which are important for a scraping tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first states purpose and return type, the second adds a behavioral caveat. No extraneous words, front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 6 parameters and no output schema, the description covers purpose and basic behavior but lacks details on pagination, sorting options in context, or filter usage. Schema descriptions for params help, but overall context is minimal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description does not need to add parameter details. The description adds no extra meaning beyond what the schema provides, maintaining the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Search' and resource 'AliExpress products', and specifies the return type (listings with prices, ratings, links). This distinguishes it from siblings like 'search_alibaba' (different platform) and 'get_aliexpress_product' (specific product).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for searching AliExpress and warns of potential anti-bot failure, but does not explicitly state when to use this tool over alternatives like 'get_aliexpress_product' or other search tools. No exclusions or context for when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_amazon_jobsA
Search amazon.jobs by title, location, and job category. Amazon publishes pay bands inline where local law requires it (including Canada), and those are surfaced as a Pay field. Its own search is fuzzy — a "product designer" query returns engineering reqs — so title and location are both re-applied against each posting. title and job_category search DIFFERENT things and return disjoint sets: category="Design" finds an "Art Director" that no title query reaches, while title="designer" finds a "Design Verification Engineer" that is not in the Design category. To survey a field rather than a job name, run the category too.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result ordering | relevant |
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "software engineer" | |
| country | No | ISO alpha-3 code or country name, e.g. "CAN". Inferred from location when omitted. | |
| location | No | City or country, e.g. "Toronto" or "Vancouver, British Columbia, Canada". Resolved to Amazon's exact location value automatically. | |
| job_category | No | Amazon job category, e.g. "Design", "Software Development", "Marketing". This is the reliable way to find design roles, whose titles vary ("Art Director", "UX Designer"). | |
| strict_title | No | Require the title words to appear in the posting's title | |
| strict_location | No | Require the location to match the posting's own location, not just Amazon's search radius |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden well: it discloses that upstream matching is unreliable and that post-filtering is applied, which is real behavioral context an agent cannot get from the schema. It also explains the Pay field's provenance (local-law dependent, e.g. Canada). It stops short of stating result caps, deduplication across multiple queries, or whether postings include apply URLs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and facets, then the caveats, then the disambiguation rule — a sensible order with no filler. It is on the long side and the paired examples are somewhat redundant with the job_category schema description, but each sentence still carries decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, no-annotation, no-output-schema search tool, the description covers invocation strategy, result trustworthiness, and a distinguishing data feature. Remaining gaps are minor and mostly schema-documented (sort, limit) — only cross-query result handling and return shape are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description earns an increment by adding semantics the schema does not convey: that title and job_category target different fields and return disjoint sets, with worked examples of each failing case. The anyOf (at least one of title/location/job_category) is never stated in prose, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Search amazon.jobs") plus the three facet dimensions it accepts, which immediately separates it from the sibling job boards (search_indeed, search_linkedin_jobs, search_google_jobs). The added note that pay bands are surfaced as a Pay field tells the agent what makes this source distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly explains that Amazon's native search is fuzzy and that title/location are re-applied against each posting, which tells the agent how to trust results. It goes further and states the exact selection rule between title and job_category (disjoint sets, with concrete examples) and when to run the category instead: "To survey a field rather than a job name, run the category too."
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_apple_jobsA
Search jobs.apple.com by title and location. A place name is resolved to Apple's own location code automatically. Country scope comes from location only — the locale changes the storefront in the output URLs and nothing else.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | Yes | Job title, e.g. "machine learning engineer" | |
| locale | No | Storefront for the returned links, e.g. "en-ca" (default) or "en-us". Does NOT scope the search — use `location` for that. | |
| location | No | City or country, e.g. "Toronto", "Vancouver", "Canada" | |
| strict_title | No | Require the title words to appear in the posting's title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that place names are auto-resolved to Apple location codes and that locale affects only output URLs, but it does not describe authentication, rate limits, return format, or result pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences with the core purpose front-loaded. Each sentence adds useful context about search scope or the location/locale behavior, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter search tool with no output schema, the description covers the main ambiguity around location versus locale and explains automatic location resolution. It does not describe the shape of returned job results or pagination beyond the limit parameter, but it is largely complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all five parameters. The description still adds meaning beyond the schema by explaining that location drives country scope and that place names are automatically resolved, while reinforcing that locale only changes storefront links.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: searching jobs.apple.com by title and location. Naming the Apple jobs domain clearly distinguishes this from sibling job-board search tools such as search_linkedin_jobs or search_indeed. It also clarifies the key location/locale distinction up front.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the platform-specific description: use this to search Apple job postings. However, it does not explicitly say when to use this instead of other job-search siblings or state any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_eightfold_jobsA
Search a company career site hosted by Eightfold AI — Microsoft, Netflix, PayPal, or any other Eightfold tenant by board URL. Filter by job title and location. The board ranks rather than filters, so the title is re-applied against each posting's own name and the number dropped is reported. Use fetch() on a returned posting URL for the full description.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result ordering | relevance |
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "software engineer" | |
| employer | Yes | "microsoft", "netflix", "paypal", or any Eightfold board URL (e.g. https://acme.eightfold.ai/careers) | |
| location | No | City or country as the board spells it, e.g. "Vancouver, Canada". Returns the board's own spellings when nothing matches. | |
| strict_title | No | Require the title words to appear in the posting's title. Turn off to see everything the board ranked. | |
| include_remote | No | Include remote postings in a location search |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and provides meaningful behavioral context: the board ranks rather than filters, title filtering is re-applied against posting names, the number dropped is reported, and location matching returns the board's own spellings when nothing matches. It does not cover authentication, rate limits, or return format, but the ranking/filtering caveat is unusually transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core search scope, then the important ranking caveat, then the follow-up fetch instruction. No filler; every sentence carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter search tool with no annotations and no output schema, the description covers the key behavioral caveat (ranking vs filtering), the follow-up path for full descriptions, and location quirks. It could say more about the return shape (e.g., list of postings with URLs) but adequately enables correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 genuine meaning beyond the schema by explaining that strict_title re-applies the title against each posting's own name and reports the number dropped, and that location returns the board's own spellings when nothing matches—semantics the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Search), resource (company career site hosted by Eightfold AI), and scope (Microsoft, Netflix, PayPal, or any Eightfold tenant via board URL). This clearly distinguishes it from generic job search siblings by naming the hosting platform, though it doesn't explicitly compare against the many other job-board tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an implied context—use this for Eightfold-hosted career sites—and a follow-up instruction to use fetch() for full descriptions. However, it does not explicitly say when to choose this over search_linkedin_jobs, search_indeed, or the other job-board siblings, nor does it state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_gcjobsA
Search GC Jobs (emploisfp-psjobs.cfp-psc.gc.ca), the federal public service board — the only route to Government of Canada postings, which a plain fetch of the site cannot read (it returns a 'JavaScript must be enabled' shell over zero postings). Title, location, organization, minimum salary and language are real board filters, sent the way the board's own form sends them and confirmed against the page's echo of what it applied; title, location and salary are re-checked here. Rows come back soonest-closing first. Eligibility ('Who can apply') is not on the listing — many federal processes are restricted to current public servants, citizens, or a named area — so read a posting with get_gcjobs_job before relying on it. Give at least one filter.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "policy analyst" | |
| language | No | Language requirement facet, as the board defines it ("english" includes postings open to either language) | |
| location | No | Canadian city or province, e.g. "St. Catharines, ON", "Ottawa", "Ontario". "Canada" covers the whole board and is treated as no filter. | |
| min_salary | No | Minimum annual salary in dollars, e.g. 70000. Matched against the bottom of each posting's salary range. | |
| organization | No | Hiring organization, by exact name or abbreviation, e.g. "Canada Revenue Agency", "CRA", "RCMP" | |
| strict_title | No | Require the title words to appear in the posting's title | |
| exclude_various_locations | No | Drop postings listed as “Various Locations”. The board counts those as matches for any city, and they can outnumber the postings that name the place. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses that filters are sent as the board's own form sends them, confirmed against the page echo, that title/location/salary are re-verified, and that rows return soonest-closing first. It omits rate limits, error behavior, and what fields each row contains, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and domain, then behavior, then routing advice — a sensible order. A couple of clauses (the 'way the board's own form sends them' detail) are dense but earn their place by conveying verification behavior; overall it is tight for the amount of substance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, zero-annotation, no-output-schema search tool this covers purpose, filtering semantics, sort order, the fetch fallback, and the crucial eligibility caveat. The main gap is that return-row shape is unspecified, which an agent may need to know when parsing results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema by identifying which five inputs are 'real board filters' and which three (title, location, salary) are re-checked server-side after submission. It does not elaborate on strict_title or exclude_various_locations, which live entirely in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — searching the GC Jobs federal public service board — and pins it to the exact domain. It distinguishes itself from the many other job-search siblings by being the only route to Government of Canada postings, and explains why a plain fetch fails, so an agent can tell it apart immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the constraint 'Give at least one filter' (matching the schema's anyOf), and routes the agent to the sibling get_gcjobs_job with the precise condition: before relying on eligibility, since 'Who can apply' is not on the listing. It also excludes fetch by explaining the JS-shell failure mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_gojobsA
Search gojobs.gov.on.ca, the Ontario Public Service (OPS) careers board. Every posting is an Ontario government job. The board has NO keyword search of its own — its only text input is an exact Job ID — so title is matched here against each posting's own title. Region, city, job category, career level and minimum salary are real board filters. Give at least one filter — an unfiltered listing is a dozen sequential postbacks.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "policy advisor" | |
| location | No | Ontario city or region, e.g. "Toronto", "Thunder Bay", "North". "Ontario" and "Canada" cover the whole board and are treated as no filter. | |
| min_salary | No | Minimum annual salary the board offers as a step, e.g. "70000", "100000" | |
| career_level | No | One of: Student, Entry level, Experienced, Management, Executive | |
| job_category | No | OPS job category, e.g. "Information Technology", "Corrections and Enforcement" | |
| strict_title | No | Require the title words to appear in the posting's title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it explains that the board has NO keyword search, that its only native text input is an exact Job ID, and that `title` is therefore matched client-side against each posting's own title. It also warns that unfiltered listings trigger "a dozen sequential postbacks," a useful performance trait. It stops short of covering return shape or pagination, hence not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, zero waste, and the most decision-relevant fact (the board's lack of keyword search) is front-loaded right after the identity sentence. Every clause earns its place by either orienting the agent or preventing a costly invocation mistake.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given seven params with 100% schema coverage but no annotations and no output schema, the description supplies the key behavioral context an agent needs to call it correctly. The one remaining gap is the absence of any indication of what the results look like or how `limit` interacts with the sequential-postback warning, but for a public search tool this is a minor omission rather than a blocking one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value the schema lacks: it explains that `title` is matched locally against posting titles because the board has no keyword field, and it clarifies which fields (region, city, job category, career level, minimum salary) correspond to genuine board filters. The special
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ("Search gojobs.gov.on.ca, the Ontario Public Service (OPS) careers board") and immediately clarifies what kind of postings it returns ("Every posting is an Ontario government job"). This source identification cleanly distinguishes it from the many other job-board search siblings without needing to name each one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete invocation requirement — "Give at least one filter — an unfiltered listing is a dozen sequential postbacks" — which maps directly to the anyOf constraint and explains the cost of ignoring it. It does not explicitly compare against siblings like get_gojobs_job or the other portal search tools, so the when-to-use alternative guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_google_jobsA
Search Google's own careers board by job title and location. Google's free-text matching is very loose — a "product designer" search in Canada reports 38 matches of which two have a matching title — so each posting's own title and location are re-checked and both counts are reported separately.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result ordering | relevance |
| limit | No | Jobs to return (default: 25) | |
| title | Yes | Job title, e.g. "product designer" | |
| location | No | Country, or a FULLY QUALIFIED city — "Waterloo, ON, Canada", not "Waterloo", which Google resolves to Waterloo, Belgium | |
| remote_only | No | Only remote-eligible postings | |
| strict_title | No | Require the title words to appear in the posting's title | |
| strict_location | No | Require the posting's own location to match; Google's city filter is radius-based and includes neighbours |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does real work: it warns that Google's free-text matching is loose (with a concrete 38-vs-2 example), that postings are re-checked, and that two counts are reported separately. That is meaningful disclosure about result semantics and accuracy that no structured field provides; only auth, rate limits, and pagination behavior are left unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler; purpose comes first and the matching caveat second. The em-dash example is dense but earns its space by quantifying the looseness problem in a way the agent can reason about.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Seven parameters, no annotations, no output schema — the description compensates by explaining the matching model and that two result counts are returned, which is the key return-shape fact an agent needs. It does not cover empty-result behavior or the relevance/date sort semantics, small gaps for a low-risk search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds rationale the schema cannot: the loose-matching explanation justifies the default-on strict_title/strict_location checks and tells the agent why reported counts differ. It also reinforces the precise-location requirement the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search Google's own careers board') plus the two scoping dimensions (job title, location), which cleanly separates it from the many other company-specific job search siblings. An agent can immediately tell this is the Google-board variant rather than another board.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The scope ('Google's own careers board') implies when to reach for it, but there is no explicit when-to-use/when-not or named alternative among the ~15 sibling job search tools. The agent must infer routing from the tool name and the board scope rather than being told.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_indeedA
Search ca.indeed.com. Carries salary bands on most result cards, and get_indeed_job will read the full body of any result — including postings a UKG or PeopleSoft careers site will not serve. Returns one page (~15 postings) per query: every deeper offset returns Indeed's sign-in wall, so refining the query changes which postings appear rather than how many.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title or keywords, e.g. "administrative assistant" | |
| location | No | City, e.g. "St. Catharines, ON" | |
| radius_km | No | Search radius in km (0 = Indeed's default 25) | |
| strict_title | No | Require the title words in the posting's own title | |
| strict_location | No | Require the posting's own city to match; off by default since Indeed searches a radius |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, and the description carries the full burden well: it discloses the ~15-posting page cap, the sign-in wall on deeper offsets, that salary bands appear on most cards, and that some postings are reachable here that UKG/PeopleSoft career sites will not serve. These are exactly the operational traits an agent cannot infer from 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with what is searched, followed by result quality, the follow-up tool, and the pagination caveat. No sentence is filler and the most consequential constraint (no deep pagination) is stated plainly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description supplies result count, salary-band richness, and the escalation path to get_indeed_job, which is nearly everything needed. What remains unstated is the shape of returned fields and whether empty result sets or blocked offsets surface as errors versus empty lists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 earns a bump by clarifying that the effective result ceiling is one page (~15) per query, which tempers expectations for the limit parameter (max 100, default 25). It says nothing about title, location, radius_km, or the strict_* flags, leaving those entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and named resource with geographic scope ("Search ca.indeed.com"), which immediately separates it from search_linkedin_jobs, search_jobbank and the other board-specific searchers. It also distinguishes itself from get_indeed_job by assigning that sibling the full-body reading job.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to get_indeed_job for full posting bodies and warns that deeper offsets hit a sign-in wall, so the correct behavior is to refine the query instead of paginating. It gives no guidance on choosing between this and the other job-board siblings when a title matches several, which is the only gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_jobbankA
Search jobbank.gc.ca, the federal Job Bank — the highest-volume Canadian board, with salary published on most listings. A place name is resolved to Job Bank's own numeric city id first, because the board silently ignores an unresolved location and returns the whole country (64,000+ postings) as an ordinary successful search. Job Bank searches a RADIUS around a city, so nearby towns are included by design and the radius used is always reported.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title or keywords, e.g. "truck driver" | |
| location | No | Canadian city, ideally with province, e.g. "St. Catharines, ON". Ambiguous names resolve to the province given. | |
| radius_km | No | Search radius around the city in km (default: 50, Job Bank's own). Measured from St. Catharines: 10 km gives 152 postings, 25 km 424, 50 km 1036, 100 km 10327. | |
| strict_title | No | Require the title words to appear in the posting's title | |
| strict_location | No | Require the posting's own location to match the city. Off by default because a radius search is the point. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and largely meets it: it discloses a serious silent-failure mode (an unresolved location returns 64,000+ national postings as an ordinary success) and explains that results are radius-based with the radius reported. It omits auth/rate-limit behavior and return shape, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with what the tool is, followed by the two facts most likely to cause a wrong call (location resolution and radius semantics). No filler and no repetition of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter, annotation-free search tool with no output schema, the description covers the major pitfall and the scoping model. It stops short of describing result ordering, pagination, or what fields come back, which is a modest gap given there is no output schema to rely on.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 limit, title, location, radius_km, strict_title and strict_location in detail, including example radii. The description adds the reason location must be resolvable but otherwise restates schema-level behavior; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Search jobbank.gc.ca, the federal Job Bank') and identifies the board precisely, which separates it from siblings like search_indeed, search_gcjobs, and search_linkedin_jobs. It also states a differentiating characteristic (salary published on most listings).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the mechanics of use — a place name is resolved to a numeric city id, and searches are radius-based around a city — which tells the agent how to supply inputs correctly. It does not explicitly name when to prefer this over search_indeed or search_gcjobs, so the routing guidance is implied rather than stated.
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's public job board (no account needed). Filter by keywords, location, date posted, remote/hybrid/on-site, experience level, job type, and minimum salary. Returns title, company, location, posting date, and a linkedin.com/jobs/view URL. Call get_linkedin_job(job_id) for the full description.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | LinkedIn's own sort is not honoured on this endpoint; "recent" sorts the fetched results by posting date here. | relevance |
| limit | No | Jobs to return (default: 10) | |
| start | No | Result offset for pagination (max 999) | |
| geo_id | No | LinkedIn geo ID, if you already have one. Takes precedence over location. | |
| job_type | No | Employment type | |
| keywords | Yes | Job title or skills, e.g. "software engineer" | |
| location | No | City/region, e.g. "Toronto, Ontario, Canada". Resolved to a LinkedIn geo ID automatically. | |
| workplace | No | Workplace type | |
| easy_apply | No | Only postings you can apply to inside LinkedIn (no external application form) | |
| experience | No | Experience level | |
| min_salary | No | Minimum annual salary filter | |
| date_posted | No | How recently the job was posted | any |
| strict_location | No | Re-check each posting's own location against `location`. LinkedIn filters by radius, so a St. Catharines search returns GTA postings; with this on they are dropped and counted. | |
| under_10_applicants | No | LinkedIn's "Under 10 applicants" filter — strongly favours postings with few applicants so far |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and delivers the two most important facts: no authentication/account is required, and the response shape is a compact listing (title, company, location, date, URL) rather than full postings. It omits rate limits and pagination ceilings (which the schema covers for start/limit), so it is informative but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: what it searches, what it filters, what it returns, plus the routing hint. Filter list is front-loaded and no sentence is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter list tool with no output schema, the description fills the key gap by naming the returned fields, so an agent knows what it gets back. Minor residual gaps (pagination/size expectations, result ordering) are already handled in the schema's sort, start, and limit descriptions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter carries its own explanation, including the non-obvious strict_location and sort caveats, so the schema does the heavy lifting. The description only restates the filter categories generically without adding syntax or interaction details, which is the baseline for fully-documented schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search LinkedIn's public job board'), scopes it ('no account needed'), enumerates the filter dimensions, and names the follow-up sibling get_linkedin_job. An agent can distinguish it from search_indeed or search_workday_jobs by the LinkedIn-specific naming without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context for when to use it and an explicit hand-off rule: 'Call get_linkedin_job(job_id) for the full description,' which tells the agent this is the discovery step, not the detail step. It does not state when to prefer the other job-board siblings, so it stops short of a full alternatives map.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_marketplaceA
Search Kijiji, Craigslist, and Facebook Marketplace simultaneously. Takes human-readable parameters (city name, category, price range) and returns grouped results from all platforms. Use fetch(url) to get full listing details for any result URL.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort order | date |
| query | Yes | Search keywords (e.g. "golf r", "ikea couch") | |
| category | No | Category filter | all |
| location | Yes | City name, optionally with province/state (e.g. "toronto", "st catharines, ON", "seattle") | |
| condition | No | Item condition filter | |
| max_price | No | Maximum price in dollars | |
| min_price | No | Minimum price in dollars | |
| platforms | No | Platforms to search (default: all). Kijiji is Canada-only and auto-skipped for US locations. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full burden. It mentions 'grouped results' and simultaneous search, but omits details on rate limits, authentication, error handling, or result volume.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, immediately stating the main purpose and key features. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite 8 parameters and no output schema, the description is very brief. It does not explain return format, pagination, error behavior, or how to interpret grouped results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description adds minimal value beyond what schema already provides. It restates 'human-readable parameters' but doesn't elaborate on format or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 specific resources (Kijiji, Craigslist, Facebook Marketplace), distinguishing it from sibling tools like search_aliexpress or search_reddit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for multi-platform searches, but lacks explicit guidance on when not to use it or how it compares to alternatives like the 'fetch' tool for individual listings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_meta_jobsA
Search metacareers.com by title and office. Meta spells its offices "Vancouver, Canada" rather than "Vancouver, BC"; a place name is matched against its real office list and the list is returned when nothing matches.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | Yes | Job title, e.g. "product designer" | |
| location | No | Office, city, or country, e.g. "Toronto", "Menlo Park", "Canada" | |
| remote_only | No | Only remote postings | |
| strict_title | No | Require the title words to appear in the posting's title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden. It usefully discloses a fallback behavior: a place name is matched against Meta's real office list, and that list is returned when nothing matches. However, it does not cover other relevant traits such as read-only nature (implied by 'search'), rate limits, authentication, or result format/pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with purpose and followed by a key input nuance. Every clause earns its place, and there is no extraneous text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter search tool with no output schema, the description covers the core purpose and a critical location-formatting detail, but it omits useful context such as result ordering, pagination behavior, and explicit usage contrast with sibling job-search tools. It is adequate but leaves clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 value beyond the schema by explaining the specific location-matching quirk (e.g., 'Vancouver, Canada' vs 'Vancouver, BC') and the fallback behavior when no office matches. It does not elaborate on limit, remote_only, or strict_title, but the schema already documents those fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb, resource, and target site: 'Search metacareers.com by title and office.' This immediately distinguishes it from sibling job-search tools that target other companies (LinkedIn, Indeed, etc.). An agent can tell exactly what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (searching Meta jobs) and provides input-format guidance for office names, but it does not explicitly state when to use this tool versus the many sibling job-board search tools. There are no exclusions or alternative recommendations, leaving the agent to infer that this is Meta-specific from the domain name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_oracle_jobsA
Search a career site running on Oracle Recruiting Cloud (Oracle Fusion) — Oracle and Uber today, or any ORC tenant by careers URL or Fusion host. Returns the full posting text, location, department, and job family. The board filters by country but ignores city names, so a city is matched against each posting here.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "product designer" | |
| employer | Yes | "oracle", "uber", a careers URL, or a Fusion host (https://{tenant}.fa.{region}.oraclecloud.com) | |
| location | No | City and/or country, e.g. "Toronto, Canada". A country narrows the board server-side; a city is filtered here. | |
| strict_title | No | Require the title words to appear in the posting's title | |
| strict_location | No | Require the location to match the posting's own location |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations the description must carry the burden, and it does disclose two non-obvious traits: the return payload (full posting text, location, department, job family) and that country filtering is server-side while city matching is performed by this tool. It omits pagination/limit interplay and any rate-limit or auth expectations, which keeps it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three front-loaded sentences with no filler; the platform scope leads, the return shape follows, and the location quirk closes. It is dense but every sentence contributes, with the parentheticals the only minor drag.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter tool with a fully documented schema and no output schema, the description supplies both the return fields and the server-vs-local filtering behavior an agent would otherwise get wrong. What remains unaddressed is how limit interacts with the 200 cap and how this tool relates to the overlapping search_uber_jobs sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter including limit, title, location, and both strict_* flags is already documented, and the baseline of 3 applies. The description adds only the rationale for city filtering happening here, which explains strict_location indirectly but gives no new syntax or default information beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (a career site on Oracle Recruiting Cloud / Fusion), and enumerates the tenant forms it accepts, which implicitly separates it from the many other ATS-specific search_*_jobs siblings. It stops short of naming a sibling to use instead when an employer is not on ORC, so differentiation is by platform rather than by explicit routing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening clause establishes applicability precisely: any ORC tenant by careers URL or Fusion host, with Oracle and Uber called out as current examples, which tells an agent when this tool is the right pick. It offers no explicit when-not or named alternative (e.g. search_workday_jobs), leaving cross-tool routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_realtorA
Search Canadian homes for sale or rent on realtor.ca with full filters (location, price, beds, baths, property/building type, ownership). Returns listings with price, address, beds/baths, size, agent and a realtor.ca URL. Call fetch(url) on a listing URL for the full description, every property detail, and similar nearby homes.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Result page (~20 per page, up to 600 total) | |
| sort | No | Sort order | newest |
| location | Yes | City, neighbourhood, or postal code (e.g. "Ottawa", "Orleans, Ottawa", "Toronto", "M5V") | |
| min_beds | No | Minimum bedrooms | |
| max_price | No | Maximum price (sale) or monthly rent | |
| min_baths | No | Minimum bathrooms | |
| min_price | No | Minimum price (sale) or monthly rent | |
| ownership | No | Ownership type | |
| transaction | No | Buy (sale) or rent | sale |
| building_type | No | Building type filter | |
| property_type | No | Property category | any |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool returns listings with price, address, beds/baths, size, agent, and a realtor.ca URL, and suggests using fetch for full descriptions. However, it does not mention any rate limits, authentication needs, or potential side effects, which would elevate it to a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, front-loading the purpose and filter capabilities in the first sentence, and detailing return values and follow-up in the second. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of 11 parameters, no output schema, and no annotations, the description is fairly complete. It covers the tool's purpose, key filters, return fields, and a clear next step (fetch). It lacks only a mention of pagination beyond the page parameter description in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description summarizes key filters (location, price, beds, baths, property/building type, ownership) but adds little meaning beyond what the schema already provides. It does not elaborate on parameter usage nuances.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches Canadian homes for sale or rent on realtor.ca with full filters. It specifies the resource (realtor.ca) and the action (search), distinguishing it from sibling tools like search_aliexpress or search_alibaba.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives. It mentions a follow-up action (call fetch for details) but provides no guidance on selecting this tool over other search tools among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_redditB
Search Reddit posts. Returns metadata and URLs. Use mcp__fetchaller__fetch to read full post content.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort order | relevance |
| time | No | Time filter | all |
| after | No | Pagination cursor from previous response | |
| limit | No | Number of results (1-25) | |
| query | Yes | Search query | |
| timeout | No | Request timeout in seconds (default: 10) | |
| subreddit | No | Limit to subreddit (without r/) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states that the tool returns metadata and URLs, implying it is read-only, but does not disclose rate limits, authorization needs, pagination behavior (despite the 'after' parameter), or error handling. The behavioral description is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences, front-loaded with the primary purpose, and includes a complementary instruction to use 'fetch' for full content. Every word is necessary and there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 7 parameters and no output schema. The description is too brief to be complete: it omits explanation of the return structure beyond 'metadata and URLs', does not explain pagination (despite the 'after' parameter), and does not differentiate from the sibling 'browse_reddit' tool. More context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the input schema already documents all 7 parameters. The description adds no additional meaning beyond what is in the schema (e.g., it does not explain the purpose of 'sort', 'time', or 'after'). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches Reddit posts and returns metadata and URLs. It distinguishes from siblings like 'browse_reddit' by indicating that this tool is for searching, not browsing, and that full content requires another tool. However, it does not explicitly differentiate from the generic 'search' tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a usage hint: use another tool ('fetch') for full content. However, it does not give explicit context on when to use this over siblings like 'browse_reddit' or 'search', nor does it mention prerequisites or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_uber_jobsA
Search Uber's job board by title and location. Uber runs on Oracle Recruiting, which answers anonymously with the full posting text, so results carry title, department, team, level, location, and description.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | Yes | Job title, e.g. "product designer" | |
| location | No | City and/or country, e.g. "Toronto, Canada" or "Canada" | |
| strict_title | No | Require the title words to appear in the posting's title | |
| strict_location | No | Require the city to match the posting's own location |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does useful work: it discloses that the board answers anonymously (no auth needed) and that results carry the full posting text rather than snippets. It omits rate limits, pagination behavior, and whether result counts are capped beyond the limit parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the search action and scope front-loaded; the second sentence is informational rather than padding. Slightly verbose about the Oracle backend, but it earns its place by explaining why full descriptions are available.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description helpfully enumerates expected return fields (title, department, team, level, location, description). For a five-parameter read-only search this is nearly complete, with only pagination and result-ordering behavior left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters including strict_title and strict_location are already documented in the schema. The description adds only the general notion of filtering by title and location, no extra semantics for the strictness flags, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) and a precisely scoped resource (Uber's job board), with the qualifying dimensions (title and location) named up front. It is trivially distinguishable from the many sibling job-board tools because the company is named, and it even clarifies the underlying ATS (Oracle Recruiting), which helps separate it from search_oracle_jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The title/location framing implies when the tool applies, but there is no explicit guidance on when to prefer it over search_oracle_jobs or the other company-specific job tools, nor any stated prerequisites or exclusions. Usage is inferable rather than instructed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_workday_jobsA
Search any Workday board (*.myworkdayjobs.com) by job title and location — Adobe, NVIDIA, Salesforce, Autodesk, CrowdStrike, ServiceTitan, Motorola Solutions, or any tenant by board URL. Resolves the tenant's own location facet, whatever it is named, and filters the title client-side because Workday's searchText is unreliable (on some tenants it silently drops real matches).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Jobs to return (default: 25) | |
| title | No | Job title, e.g. "product designer" | |
| employer | Yes | "adobe", "nvidia", "salesforce", "autodesk", "crowdstrike", "servicetitan", "motorolasolutions", "mastercard", or a board URL (e.g. https://acme.wd1.myworkdayjobs.com/External) | |
| location | No | City, region, or country, e.g. "Toronto" or "Canada". Matched against the tenant's location facet; its real values are listed when nothing matches. | |
| strict_title | No | Require the title words to appear in the posting's title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the disclosure burden and does well: it explains that it resolves the tenant's own location facet regardless of naming and that title filtering is done client-side because Workday's searchText silently drops real matches. It omits rate limits, pagination, and return shape, which are the remaining gaps for a no-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both earning their place: the first establishes scope and inputs, the second discloses the two non-obvious implementation quirks. No filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter search tool with no output schema and no annotations, the description covers the critical gotchas (tenant resolution, facet naming, unreliable server-side title search). It does not describe the result structure or how empty results are signaled, leaving a modest gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline would be 3, but the description adds cross-parameter semantics the schema cannot: location is matched against the tenant's dynamically-named facet (with real values surfaced on no-match), and title is filtered client-side rather than via Workday's searchText.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Search any Workday board (*.myworkdayjobs.com) by job title and location') and enumerates concrete tenants. This clearly distinguishes it from sibling tools like search_indeed, search_google_jobs, or search_linkedin_jobs, which target other job sources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It makes the usage condition explicit: any Workday tenant, either by known employer name or by board URL, with worked examples. It does not explicitly say when to prefer a sibling board search or what to do if the employer is not on Workday, so it stops short of full routing guidance.
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.
18 tool updates
v3.8.6- Added
get_gcjobs_job - Added
get_gojobs_job - Added
get_indeed_job - Added
get_unifi_manual - Changed
search2 fields changed- added
Input schema / properties / providerAdded value: +{ + "default": "google", + "description": "Required. Prefer google; google failures fall back to DDG then Brave. all merges all providers. Every result names its source.", + "enum": [ + "google", + "ddg", + "brave", + "all" + ], + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "query" -]New value: +[ + "query", + "provider" +]
- Added
search_amazon_jobs - Added
search_apple_jobs - Added
search_eightfold_jobs - Added
search_gcjobs - Added
search_gojobs - Added
search_google_jobs - Added
search_indeed - Added
search_jobbank - Changed
search_linkedin_jobs1 field changed- added
Input schema / properties / strict_locationAdded value: +{ + "default": true, + "description": "Re-check each posting's own location against `location`. LinkedIn filters by radius, so a St. Catharines search returns GTA postings; with this on they are dropped and counted.", + "type": "boolean" +}
- Added
search_meta_jobs - Added
search_oracle_jobs - Added
search_uber_jobs - Added
search_workday_jobs
12 tool updates
v3.3.1- First observed
browse_reddit - First observed
fetch - First observed
get_alibaba_product - First observed
get_aliexpress_product - First observed
get_linkedin_job - First observed
search - First observed
search_alibaba - First observed
search_aliexpress - First observed
search_linkedin_jobs - First observed
search_marketplace - First observed
search_realtor - First observed
search_reddit
TDQS
Scored across 28 tools
Most tools are distinguishable by platform or action, but the set contains many job-board search tools that all perform the same conceptual operation, plus some actual overlap such as search_uber_jobs versus search_oracle_jobs (Uber runs on Oracle). The descriptions help, but choosing among 16+ job search endpoints is still confusing.
Names mostly follow a snake_case verb_noun pattern (search_*, get_*, browse_reddit), with only minor deviations like the bare `search` and `fetch`, and singular/plural inconsistency between search_linkedin_jobs and get_linkedin_job. The pattern is readable and predictable overall.
At 28 tools, this is above the 25-tool threshold and feels sprawling for a web-fetch aggregator. Many platform-specific search tools are near-duplicates in purpose, making the surface heavier than its scope requires.
The set covers generic fetch, web search, and search/detail pairs for several job and product boards. Some specialized sources only expose search and rely on `fetch` for detail pages, but the descriptions explicitly account for that workaround.
Maintenance
Related MCP Connectors
Web search, browser automation, scraping, crawling and CAPTCHA solving for AI agents.
Direct access to 60+ scraping and search tools. Extract structured data from Google (Search, Maps, Trends), Amazon, Airbnb, Social Media, and any web page directly into your AI agent.
Web data for agents. Extract web pages, crawl websites, discover URLs, and search the web.
Web MCP: scrape/crawl sites, web search, brand assets, app stores, YouTube, Reddit, Hacker News.
Related MCP Servers
- AlicenseDqualityDmaintenanceEnables AI assistants to reliably fetch web content as markdown and search the web by bypassing bot detection and rendering JavaScript. Provides tools to unblock URLs and search the web with results converted to markdown format.230 npmMIT
- AlicenseAqualityCmaintenanceEnables AI agents to crawl, scrape, search, and automate browsers with anti-bot bypass, providing fast web access via 22 tools.2236 npm3MIT
- AlicenseNot gradedqualityDmaintenanceProvides AI agents with reliable web fetching capabilities, handling retries, caching, and anti-bot bypass automatically.MIT
- AlicenseAqualityAmaintenanceEnables fetching any web page's HTML by bypassing anti-bot protection, and also provides AI-parsed structured data and Google search results.241,476 npm2MIT