0.0 / 30
What changed in the harness
Selection accuracy 98→98, token cost up 5%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
26.8 / 30
03Economics
19.1 / 20
04Discoverability
14.4 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
4 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
map_site |
no_return_description |
Discover up to 500 public same-site URLs from robots.txt, sitemaps, and bounded link traversal. Mapping costs no credits, fetched page content is not stored, and robots rules are respected. Paid plans only. Read-only. Requires HAUNT_API_KEY environment variable. Returns a JSON object with the list of discovered URLs (capped by the limit parameter) and the total count found. |
crawl_site |
params_unexplained no_return_description |
Discover and extract the same structured fields from up to 20 public same-site pages, following links up to max_depth. Complete pages use normal extraction credits; partial and failed pages cost zero credits. Robots rules are respected and fetched crawl content is not stored. Paid plans only. Read-only. Requires HAUNT_API_KEY environment variable. include_subdomains: whether to also crawl subdomains of the site (default false). include_query_parameters: whether URLs with query strings are treated as distinct pages and included (default false). include_paths: optional list of path globs (e.g. /docs/*) restricting the crawl to matching URLs. exclude_paths: optional list of path globs to skip during the crawl. Returns a JSON array of per-page results, each with the page URL, the extracted fields per the prompt/schema, and a status (complete, partial, or failed). |
company_profile |
no_return_description |
Turn a company website URL into a structured profile: what the company does, its product, and the contact and social details published on the site. Reads the live site rather than a stale third-party database. Costs no credits. Requires HAUNT_API_KEY environment variable. Returns a JSON object with the company description, product summary, and any contact details and social links found on the site. |
get_usage |
no_return_description |
Check current Haunt plan, monthly credit limit, used credits, reserved credits, and remaining credits. Read-only. Requires HAUNT_API_KEY environment variable. Returns a JSON object containing the plan name, monthly credit limit, credits used, credits reserved, and credits remaining. |
Selection evidence
Confusable tool pairs.
5 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
extract |
extract_article |
high | A request like 'get me the article content from this URL' plausibly maps to either the general-purpose extract with a prompt like 'title, body, author' or the dedicated extract_article shortcut, since both cover article extraction and extract's description explicitly calls out extract_article as an alternative. |
extract |
extract_markdown |
high | A task like 'get clean readable text from this page for my notes' could go to extract with response_format=markdown or directly to extract_markdown, since both produce markdown output and extract explicitly offers this as a built-in mode. |
extract |
extract_metadata |
medium | A request like 'get the title and description of this page' could be satisfied by extract with a prompt targeting those fields, or by extract_metadata which returns meta tags including title/description, creating overlap for simple metadata asks. |
extract_article |
extract_metadata |
low | Both target public pages and return title-like fields, but their outputs (full article body vs meta tags) are distinct enough that only vague requests like 'get info about this article page' would cause hesitation. |
try_demo_extract |
extract |
medium | A phrase like 'try extracting data from a page' without mentioning API key setup could be misrouted to try_demo_extract (which takes no URL and is fixed-demo) instead of extract, especially for users new to the tool who just say 'extract something' as a first test. |
Compare the field